# Konsolentabelle darstellen



## Jay1980 (7. Mai 2009)

Servus,

ich habe eine Tabelle in der Konsole, diese lass ich mir über System.out.println(outputString) anzeigen. Nun will ich diese Tabelle auch in Swing so sehen können. 

Ich habe schon etwas mit einem JTable rumprobiert, das ist mir aber zu kompliziert und zu aufwändig, eigentlich will ich ja nur meinen String ausgeben. Da wiederum ist aber das Problem mit einem Zeilenumbruch, JLabel macht das ja nicht und dazu kommt noch, dass  ich die Größe der Matrix vorher nicht weiss, mal gibt der Nutzer die Strings 'frieda' und 'fritz' ein, mal zwei sehr lange. Da kommt es dann ja zu Problemen, weil ich eine fixe Größe des Elternpanels habe.

Ein vielversprechender Versuch war für mich, alles in einem JOptionPane zu packen, der Message-Dialog geht ja als eigenes Fenster auf und Zeilenumbrüche versteht der Dialog auch, das einzige was noch etwas zwickt ist hier, dass die Leerzeichen und die Schrift in meiner Eclipse-Konsole und in meiner Swing-Anwendung unterschiedlich sind, da stehen meine 'Zellen' also nicht mehr übereinander.

Wie würdet ihr es machen, dass ich die Zeichen-Tabelle in der Konsole sehen kann und diese dem Nutzer meiner Swing-Anwendung ebenfalls verfügbar machen kann?

Danke vorab. 


```
// ---------------------------------------------
		// 
		//         || - | f ; r ; i ; t ; z ; |      // Array columnsNames [0] ist f von fritz
		//	   || f | 1 ; 0 ; 0 ; 0 ; 0 ; |      // 2D-Array dataRows						     
		// 	   || r | 0 ; 1 ; 0 ; 0 ; 0 ; |      // 	dataRows[0] = Array { 1, 0, 0, 0, 0 }; 
		// 	   || i | 0 ; 0 ; 1 ; 0 ; 0 ; |      // 	dataRows[1] = Array { 0, 1, 0, 0, 0 };
		// 	   || e |				  //     dataRows[2][3] = 1;
		//	   || d |							 
		// 	   || a |							 
		//
		//            ^ Array firstDataRow [0] = f von frieda
```


----------



## Ebenius (7. Mai 2009)

Ich würde so was versuchen: 
	
	
	
	





```
public static void main(String[] args) {
  final JTextArea textArea = new JTextArea(20, 76);
  textArea.setEditable(false);

  final int fontSize = textArea.getFont().getSize();
  textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, fontSize));
  textArea
        .setText("// ---------------------------------------------\n"
              + "// \n"
              + "//         || - | f ; r ; i ; t ; z ; |      // Array columnsNames [0] ist f von fritz\n"
              + "//         || f | 1 ; 0 ; 0 ; 0 ; 0 ; |      // 2D-Array dataRows\n"
              + "//         || r | 0 ; 1 ; 0 ; 0 ; 0 ; |      //         dataRows[0] = Array { 1, 0, 0, 0, 0 }; \n"
              + "//         || i | 0 ; 0 ; 1 ; 0 ; 0 ; |      //         dataRows[1] = Array { 0, 1, 0, 0, 0 };\n"
              + "//         || e |                                 //     dataRows[2][3] = 1;\n"
              + "//         || d |                                                        \n"
              + "//         || a |                                                        \n"
              + "//\n"
              + "//            ^ Array firstDataRow [0] = f von frieda");
  final JPanel contentPane = new JPanel(new BorderLayout(6, 6));
  contentPane.add(new JScrollPane(textArea));

  final JFrame f = new JFrame("Test Frame: PseudoConsoleOutput");
  f.setContentPane(contentPane);
  f.pack();
  f.setLocationRelativeTo(null);
  f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  f.setVisible(true);
}
```
Vielleicht hilft's.

Ebenius


----------



## Jay1980 (7. Mai 2009)

Sorry,

es soll nur die Tabelle rein, nicht die Kommentarzeichen und Tabulatorsprünge. Aber egal, ich habe eine andere Idee, die TextArea-Geschichte probiere ich aus.

Folgendes: kennt einer von euch eine Anwendung, die OpenSource ist, auf Swing basiert und die Konsolenausgaben in einem Fenster darstellt - da könnte ich dann ja schauen, wie die das gemacht haben?! Eclipse nutzt ja kein Swing, aber ggf. kennt ja einer etwas in der Richtung, die müssen das ja auch irgendwie gemacht haben, und so hol ich dann ja direkt die Konsole ins SwingPanel - oder hab ich da irgendwo einen Denkfehler.


----------



## fjord (7. Mai 2009)

Willst du sowas in der Art?

```
import javax.swing.*;
import java.io.*;

public class KonsoleFrame {
	private JTextArea area;
	
	public KonsoleFrame() {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		area = new JTextArea(15, 50);
		area.setEditable(false);
		frame.add(area);
		frame.pack();
		frame.setVisible(true);
		System.setOut(new PrintStream(new OutputFilter(System.out)));		
	}	

	public static void main(String[] args) {
		new KonsoleFrame();
		System.out.println("test");
	}
	
	class OutputFilter extends FilterOutputStream {
		public OutputFilter(OutputStream out) {
			super(out);
		}
		
		@Override
		public void write(byte b[]) throws IOException {
			out.write(b); // schreibt in die Konsole
			final String temp = new String(b);
			SwingUtilities.invokeLater(new Runnable(){
				@Override
				public void run() {
					area.append(temp);					
				}				
			});            
        }
		
		@Override
        public void write(byte b[], int off, int len) throws IOException {
			out.write(b, off, len); // schreibt in die Konsole
            final String temp = new String(b , off , len);
            SwingUtilities.invokeLater(new Runnable(){
				@Override
				public void run() {
					area.append(temp);					
				}				
			});
        }		
	}	
}
```


----------



## Jay1980 (7. Mai 2009)

Ah, okay man findet ja schon einige Lösungen für 'console java swing', aber die Variante mit der JTextArea ist wohl in meinem Fall am besten. Eigentlich muss ich es nur noch schaffen, eine Monospace-Schrift zu erhalten. Ich habe schon gelesen und kann mir nicht erklären, was ich da falsch gemacht habe - mit den Schriften hatte ich mit meinem Ubuntu schon oftmals eine Extraschicht einlegen müssen, bis alles so lief wie ich wollte. 

Hier ist der Code - sieht jemand einen Fehler? 


```
// put Panel together
		JPanel jobaDotplotPanel = new JPanel();
		
		// JTextArea mit ScrollPane
		JTextArea textArea = new JTextArea( dialogString, 10, 10 );
		textArea.setEditable(false);
		textArea.setLineWrap(true);
		textArea.setWrapStyleWord(true);
		
		JScrollPane scrollPane = new JScrollPane( textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		Dimension dim = new Dimension( 600, 600);
		scrollPane.setPreferredSize(dim);
		scrollPane.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 16));
		
		// einhängen ins Panel
		jobaDotplotPanel.add(scrollPane);
		
		// save Panel in attribute
		this.jobaDotplotPanel = jobaDotplotPanel;
```


----------



## Ebenius (7. Mai 2009)

Aus welchem Grund setzt Du der JScrollPane den Font? Der muss natürlich auf die JTextArea.

Ebenius


----------



## Jay1980 (7. Mai 2009)

Danke Ebinius, das war der Fehler, dass sich da nichts getan hat.

Leider immer noch keine Lösung, auch durch die Angabe von Font.Monospaced erhalte ich keine richtige Monospace-Schrift. Das i hat nicht den gleichen Platz wie das Z daher ist meine Tabelle ultraverrutscht. 

Mir ist das eh nicht ganz klar, als ersten Parameter eines Font-Konstruktors kann ich ja einen String mit dem Font-Namen mitgeben oder aber auch so Konstanten wie Font.MONOSPACED, dann aber wieder keinen Font-Namen. Nehmt ihr dann lieber direkt eine nichtproportionale Schrift, etwa Courier - die ist ja dann von Haus aus Monospaced. Wie macht man es dann wenn etwa Courier nicht auf dem System des Anwenders installiert ist?


----------



## Jay1980 (7. Mai 2009)

Sodala,

jetzt ist das Problem gelöst. Der Schlüssel war zu überprüfen welche Schriften denn auf meinem System überhaupt installiert sind - das geht mit einer statischen Methode. Dann stellte ich fest, dass 'Monospaced' zwar installiert ist, aber dass es damit nicht klappte, das i war viel schmaler als das Z. Nun habe ich eine Schrift genommen die bei meinem System (Ubuntu Linux) mit dabei war, Nimbus Sans Mono L oder so ähnlich und dann war die Anzeige wirklich nichtproportional. Tabelle steht nun also. 

Die Methode zum Auslesen der Schriften auf dem eigenen System ist diese hier: 


```
for ( String fonts : GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() )
		{
			System.out.println(fonts);
		}
```


----------

