# einzelne Zeichen in jTable einlesen



## rei0d (28. Jan 2013)

Guten Abend Community,
ich soll eine Logikminimierung mit dem Programm Espresso programmieren, also aus einer Datei 0 bzw. 1 oder - einlesen, diese in einer Tabelle anzeigen und dann über Espresso minimieren lassen.
Bisher klappt mein Programm soweit, dass ich die Eingangsvariablen und Ausgangsvariablen richtig einlesen kann(auch wenn es etwas umständlich ist) und die Tabelle dementsprechend zeichnen kann. Auch die Funktion, mit der eine Reihe hinzugefügt wird klappt einwandfrei. Das einzige Problem habe ich beim Einlesen der Datei, da diese am Anfang ".i 4" und ".o 2" stehen hat (.i = Anzahl der Eingangsvariablen, .o = Anzahl der Ausgangsvariablen), also keine reinen Int Werte.
Habt ihr eine Idee, wie ich diese "rausfiltern" kann, ohne die Datei selbst zu verändern? Ich habe mir das so gedacht, dass die Datei in eine Arraylist oder ähnliches eingelesen wird und dann, wenn sich ein int Wert am Anfang befindet, die Werte in ein neues Array gespeichert werden, am besten Zeichen für Zeichen.
Die Datei sieht so aus:


Spoiler



.i 4
.o 2
0000 01
0001 01
0010 00
0011 -0
0100 11
0101 11
0110 1-
0111 1-
1000 0-
1001 11
1010 00
1011 -1
1100 10
1101 11
1110 0-
1111 11
.e



Meine Programm sieht so aus:

```
package logikminimierung;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class Application extends JFrame implements ActionListener {
	private static final long serialVersionUID = 17L;
	String line;
	Integer init1 = new Integer(loadInput()); // Anzahl der Variablen aus Datei
												// laden
	Integer init2 = new Integer(loadOutput()); // Anzahl der Funktionen aus
												// Datei laden
	Integer min = new Integer(0);
	Integer max = new Integer(100);
	Integer step = new Integer(1);
	JTable truthTable;

	SpinnerNumberModel num1 = new SpinnerNumberModel(init1, min, max, step);
	JSpinner numSpin = new JSpinner(num1);
	SpinnerNumberModel num2 = new SpinnerNumberModel(init2, min, max, step);
	JSpinner funktionenSpin = new JSpinner(num2);
	SpinnerNumberModel model = (SpinnerNumberModel) numSpin.getModel();
	int vars = model.getNumber().intValue();

	JPanel panelTOP = new JPanel();
	JPanel panelEAST = new JPanel();
	JPanel panelSOUTH = new JPanel();
	JPanel panelCENTER = new JPanel();
	JPanel panelNORTH = new JPanel();

	JPanel cp;
	JScrollPane sp1;

	JLabel variablenLabel = new JLabel("Variablen");
	JLabel funktionenLabel = new JLabel("Funktionen");
	JButton minimizeButton = new JButton("Minimize");
	JButton addrowButton = new JButton("Add Row");
	JButton fillButton = new JButton("Fill");

	FlowLayout flowlayout1 = new FlowLayout(FlowLayout.CENTER);
	int anzahlVariablen;
	int anzahlFunktionen;
	int row;

	ArrayList<Funktion> liste = new ArrayList<Funktion>();



	public Application() throws IOException {
		row = (int) Math.pow(2, anzahlVariablen);
		cp = (JPanel) getContentPane();
		setSize(500, 500);
		cp.setLayout(new BorderLayout());

		addrowButton.addActionListener(this);
		fillButton.addActionListener(this);
		minimizeButton.addActionListener(this);



		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		initPanelNorth();

		initPanelEast();
		initPanelSouth();
		truthTable = new JTable();
		DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) truthTable
				.getDefaultRenderer(Object.class);
		renderer.setHorizontalAlignment(SwingConstants.CENTER);

		sp1 = new JScrollPane(truthTable);
		loadInput();
		initPanelCenter();
		setSize(500, 500);

		row = (int) Math.pow(2, anzahlVariablen);

	}

	private int loadInput() throws IOException {
		String inputFile = ".\\pla\\Bsp.pla";
		Scanner input = new Scanner(inputFile);

		try {

			String zeile;
			BufferedReader reader = new BufferedReader(
					new FileReader(inputFile));

			zeile = reader.readLine();
			String[] tmp = zeile.split(" ");
			anzahlVariablen = Integer.parseInt(tmp[1]);

			while (zeile != null) {
				zeile = reader.readLine();
			}
		} catch (FileNotFoundException e) {
			System.out.println("Error: Datei nicht gefunden");
		} catch (IOException e) {
			System.out.println("Error:Fehler beim einlesen");

		}
		input.close();
		return anzahlVariablen;
	}

	public static String readLine(int lineNumber) throws Exception {
		if (lineNumber < 1)
			return null;
		String inputFile = ".\\pla\\Bsp.pla";
		LineNumberReader f = new LineNumberReader(new FileReader(inputFile));
		while (f.getLineNumber() < lineNumber - 1) {
			if (f.readLine() == null)
				break;
		}
		return f.readLine();
	}

	private int loadOutput() {
		String inputFile = ".\\pla\\Bsp.pla";
		Scanner input = new Scanner(inputFile);
		try {

			String zeile;
			BufferedReader reader = new BufferedReader(
					new FileReader(inputFile));

			zeile = reader.readLine();
			@SuppressWarnings("unused")
			String[] tmp = zeile.split(" ");
			String funktionen = readLine(2);

			String[] tmp2 = funktionen.split(" ");
			anzahlFunktionen = Integer.parseInt(tmp2[1]);

			while (zeile != null) {

				zeile = reader.readLine();
			}
		} catch (FileNotFoundException e) {
			System.out.println("Error: Datei nicht gefunden");
		} catch (IOException e) {
			System.out.println("Error:Fehler beim einlesen");
		} catch (Exception e) {
			e.printStackTrace();
		}

		input.close();
		return anzahlFunktionen;
	}

	private void initPanelNorth() {
		panelNORTH.setLayout(flowlayout1);
		panelNORTH.add(variablenLabel);
		panelNORTH.add(numSpin);
		panelNORTH.add(funktionenLabel);
		panelNORTH.add(funktionenSpin);
		panelNORTH.add(addrowButton);
		panelNORTH.add(fillButton);

		cp.add(BorderLayout.NORTH, panelNORTH);
		cp.add(BorderLayout.CENTER, panelCENTER);
		cp.add(BorderLayout.EAST, panelEAST);
		cp.add(BorderLayout.SOUTH, panelSOUTH);

	}

	private void createTable() {

		int anzahlVariablen = Integer.valueOf(num1.getValue().toString())
				.intValue();
		int anzahlFunktionen = Integer.valueOf(num2.getValue().toString())
				.intValue();
		String[] header = new String[anzahlVariablen + anzahlFunktionen];
		String[][] werte = new String[row][anzahlVariablen]; // [Anzahl
																// Zeilen(2^n)



		int i = anzahlVariablen;
		while (i + 1 > 0) {
			header[i] = ("x" + i); // header füllen
			i--;
		}
		int o = anzahlFunktionen - 1;
		while (o + 1 > 0) {
			header[anzahlVariablen + o] = ("y" + o); // header füllen
			o--;
		}

		DefaultTableModel tableModel = new DefaultTableModel(werte, header);

		DefaultTableModel model = (DefaultTableModel) truthTable.getModel();
		String[] data = null; // vorbelegte Werte
		model.addRow(data);
		pack(); // Tabelle neu generieren
		panelCENTER.add(sp1);
		truthTable.setModel(tableModel);
	}

	private void initPanelCenter() {
		panelCENTER.setLayout(flowlayout1);
		createTable();
		cp.add(panelCENTER, BorderLayout.CENTER);

	}

	private void initPanelEast() {
		panelEAST.setLayout(flowlayout1);

	}

	private void initPanelSouth() {
		panelSOUTH.setLayout(flowlayout1);
		panelSOUTH.add(minimizeButton, BorderLayout.SOUTH);
		cp.add(panelSOUTH, BorderLayout.SOUTH);
	}



	private void addRow() {
		row++;


	}

	private void fill() throws IOException {
		String uebergabeVariable;
		ArrayList<Character> werteArray = new ArrayList<Character>();
		String inputFile = ".\\pla\\Bsp.pla";
		Scanner input = new Scanner(inputFile);
		BufferedReader reader = new BufferedReader(new FileReader(inputFile));
		String[] tmp;
		String str;
		String zeile = "";
		for (int i = 0; i < tmp.length; i++) {
			zeile = reader.readLine();
		}
		tmp = (zeile.split(""));
	

		
		for (int i = 0; i < tmp.length; i++) {
			werteArray.add((char) reader.read());
		}

		for (int i = 0; i <tmp.length; i++) {
			str = reader.readLine();
			System.out.println("blaa");
			if (str.equals("1") || str.equals("0")) {		// || = oder
				werteArray.add(str.charAt(0)); // Zeichen am Index 0 übergeben
												// nach werteArray
				System.out.println("fwafawf");
				i++;
				
			} else {
				i++;
				continue;
				
			}


				zeile = reader.readLine();
			}
		}



	private void minimize() {
		try {
			String inputFile = ".\\pla\\Bsp.pla";
			String outputFile = ".\\pla\\min.pla";
			String options = "";
			String command = "cmd /c .\\bin\\espresso " + inputFile + " > "
					+ outputFile;
			// System.out.println(command); //Test
			Process espresso = Runtime.getRuntime().exec(command);
			int errorCode;
			try {
				errorCode = espresso.waitFor();
			} catch (InterruptedException e) {
				System.out.println(e);
			}
		} catch (IOException e) {
			System.out.println(e);
		}
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		switch (arg0.getActionCommand()) {
		case "Minimize":
			minimize();
			break;
		case "Fill":
			initPanelCenter();
			try {
				fill();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			break;
		case "Add Row":
			addRow();
			initPanelCenter();

		}
	}

}
```


----------



## SlaterB (29. Jan 2013)

zwei Zeilen überlesen ist nicht schwer, 2x readLine() am Anfang,
oder besser jede Zeile prüfen ob sie Buchstaben enthält, etwa mit regulären Ausdrücken, behandelt auch die letzte Zeile


etwas problematisch ist im Moment, dass du an verschiedenen Stellen einliest,
mach das lieber einmal zentral Datei -> Daten, dann auch von diesen fertigen Daten die Zeilenanzahl, falls benötigt usw.

ich habe vor allem auf fill() geschaut, aber diese Methode kann ja gar nicht funktionieren..

```
Scanner input = new Scanner(inputFile); // wird nicht verwendet..
        BufferedReader reader = new BufferedReader(new FileReader(inputFile));
        String[] tmp; // ist null
        String str;
        String zeile = "";
        for (int i = 0; i < tmp.length; i++) { // NullPointerException, tmp ist null
            zeile = reader.readLine();
        }
```
selbst wenn es ginge wird es danach auch kaum besser, wie lang wird schon das tmp-Array aus einer Zeile,
und das dient dann als Schleifenlänge für neues Lesen, mal einzelnes read(), mal wieder readLine() ?
sehr wirr


----------



## rei0d (29. Jan 2013)

Ich sollte vielleicht nicht immer abends programmieren, hab jetzt nochmal drüber geschaut und bin ganz gut weiter gekommen.
Bisher funktioniert es soweit, dass er die Bsp Datei richtig einliest und gefiltert und gesplittet in ein Array (werteArray) übergibt. In diesem Array ist jetzt für jede 0/1 ein Eintrag übergeben worden. Das ganze sieht dann mit System.out.println(werteArray) so aus:

[0, 0, 0, 0, 0, 0, 0, -, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, -, 1, 1, 1, 1, 1, 0, 1, 1]

Soweit so gut.

Jetzt soll noch die JTable (truthTable) damit gefüllt werden, ich habe mir das so überlegt, dass zwei For-Schleifen brauche, um jeweils Zeile und Spalte hochzuzählen und eine For-Schleife für die Laufvariable i. Leider funktioniert das nicht ganz so, die Tabelle wird zwar gefüllt, aber nur die ersten 3 Zeilen und alle mit "1". 

Meine Code dementsprechend sieht so aus:


```
row = (int) Math.pow(2, anzahlVariablen);    //Anzahl der möglichen Belegungen: 2^anzahlVariablen
.
.
.
for (int spalte = 0; spalte <= werteArray.size(); spalte++) {
			for (int reihe = 0; reihe <= (anzahlVariablen + anzahlFunktionen - 1); reihe++) {
				for (int i = reihe * (anzahlVariablen + anzahlFunktionen); i <= row; i++) {
					truthTable.setValueAt(werteArray.get(i), reihe, spalte);
				}
			}

		}
```

Es kommt folgende Exception:


Spoiler



Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 6 >= 6
	at java.util.Vector.elementAt(Unknown Source)
	at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source)
	at sun.swing.SwingUtilities2.convertColumnIndexToModel(Unknown Source)
	at javax.swing.JTable.convertColumnIndexToModel(Unknown Source)
	at javax.swing.JTable.setValueAt(Unknown Source)
	at logikminimierung.Application.fill(Application.java:388)
	at logikminimierung.Application.actionPerformed(Application.java:504)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$200(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)



Der Fehler:
	
	
	
	





```
at logikminimierung.Application.fill(Application.java:388)
```
kommt bei der Zeile:

```
truthTable.setValueAt(werteArray.get(i), reihe, spalte);
```

Ich denke mal, dass es an 
	
	
	
	





```
i <= row;
```
 in der 3. For-Schleife liegt, wenn ich diesen Wert verändere, kommen auch ganz andere Strings in die Tabelle, beispielsweise nur "0" oder nur "-". 

//edit: Exception hinzugefügt, Variablen besser benannt, Problem präzisiert.


----------



## Dumdidum (29. Jan 2013)

ich hab es ehrlich gesagt noch ned 100% verstanden, was du da machst.

Stimmt das so?

.i 4 (<- anzahlVariablen)
.o 2 (<- anzahlFunktionen)
0000 01
0001 01
0010 00
0011 -0

und wie soll das dann in deiner Tabelle aussehen?

0 0 0 0 0 1
0 0 0 1 0 1
0 0 1 0 0 0
0 0 1 1 - 0

einfach so? Dann würde das ja viel einfacher gehen. Aber ich glaube nicht das du das so meisnt, aber aus deinem Beitrag werd ich auch ned schlau.




```
truthTable.setValueAt(werteArray.get(i), reihe, spalte);
```

In der ersten for-Schleife gehst du das werteArray durch, wodurch du also genauso viele Spalten in deiner Tabelle haben willst wie du Einträge hast. Also könntest du ja alles in eine Zeile wiedrum schreiben. Was steht dann in den restlichen Zeilen? 

War zwar keine Hilfe. Aber ich biete sie dir an, wenn du genauer beschreibst was denn eigentlich nacher in deiner Tabelle stehen soll. Idealerweise anhand deines werteArray Beispiels!


----------



## rei0d (29. Jan 2013)

Dumdidum hat gesagt.:


> Stimmt das so?
> 
> .i 4 (<- anzahlVariablen)
> .o 2 (<- anzahlFunktionen)


Ja.



Dumdidum hat gesagt.:


> und wie soll das dann in deiner Tabelle aussehen?
> 
> 0 0 0 0 0 1
> 0 0 0 1 0 1
> ...


Ja, so sollte es eigentlich aussehen. Jeder Char soll in ein Feld der Tabelle.



Dumdidum hat gesagt.:


> In der ersten for-Schleife gehst du das werteArray durch, wodurch du also genauso viele Spalten in deiner Tabelle haben willst wie du Einträge hast. Also könntest du ja alles in eine Zeile wiedrum schreiben. Was steht dann in den restlichen Zeilen?



Das soll dann so aussehen(nur, dass hier falscher weise überall "1" steht und nicht alle Zeilen beschrieben werden) :






Es sollen also anzahlVariablen + anzahlFunktionen (hier 6) Werte in jede Zeile geschrieben werden.


----------



## Dumdidum (29. Jan 2013)

dann schlage ich mal ungeprüft folgendes vor, statt deiner for-Schleife.


```
int column = 0;
		int row = 0;
		for (int index = 0; index < werteArray.size(); index++) {
			truthTable.setValueAt(werteArray.get(index), row, column);
				if (column < (anzahlVariablen + anzahlFunktionen-1)) {
				column++;
			} else {
				row++;
				column = 0;
			}
		}
```


EDIT: versehentlich column auf 1 statt 0 gesetzt xD


----------



## rei0d (29. Jan 2013)

Dumdidum hat gesagt.:


> dann schlage ich mal ungeprüft folgendes vor, statt deiner for-Schleife.
> 
> 
> ```
> ...



Danke, das klappt!

Ich habe nur ein Problem, anscheinend wird mein Array gar nicht richtig eingelesen, sondern nur ein Teil davon, deswegen sind dann auch nicht alle Felder der Tabelle belegt.

Einlesen soll er durch den reader2 in den tmp[] String und diesen dann ausfiltern (alles außer "1","0","-" wird nicht behandelt) und in das werteArray hinzufügen.
Das sieht dann so aus:

```
ArrayList<Character> werteArray = new ArrayList<Character>();
		String inputFile = ".\\pla\\Bsp.pla";
		char[] tmp = new char[row];
		String str;
		InputStream istream = new FileInputStream(inputFile);
		Scanner reader2 = new Scanner(istream);

		while (reader2.hasNext()) {

			int i = 0;
			str = reader2.next();
			tmp[i] = str.charAt(i);
			System.out.println(tmp[i]);

			if (tmp[i] == '1' || tmp[i] == '0' || tmp[i] == '-') { // || = oder
				werteArray.add(tmp[i]); // Zeichen am Index 0 übergeben
										// nach werteArray
				i++;

			} else {
				continue;
			}
		}
```

Warum fügt er jetzt nur die Hälfte hinzu?


----------



## Dumdidum (29. Jan 2013)

erstmal zu deiner variable i!!!


```
ArrayList<Character> werteArray = new ArrayList<Character>();
        String inputFile = ".\\pla\\Bsp.pla";
        char[] tmp = new char[row]; //  (1) hier erstellst du ein char-Array
        String str;
        InputStream istream = new FileInputStream(inputFile);
        Scanner reader2 = new Scanner(istream);
 
        while (reader2.hasNext()) {
 
            int i = 0; // (2) setzt jedesmal, i wieder auf 0
            str = reader2.next();
            tmp[i] = str.charAt(i); // (4) setzt jedesmal an array tmp[0] = str.charAt(0)
            System.out.println(tmp[i]);
 
            if (tmp[i] == '1' || tmp[i] == '0' || tmp[i] == '-') { // || = oder
                werteArray.add(tmp[i]); // Zeichen am Index 0 übergeben
                                        // nach werteArray
                i++; // (3) wodurch die Erhöhung hier keinen Effekt hat
 
            } else {
                continue;
            }
        }
```

Warum brauchst du ein Char-Array wenn du sowieso nur die erste Stelle immer benutzt?
Des weiteren betrachtest du ja auch nur die erste Stelle von dem String, der dir dein Scanner übergibt. Ich kenn die Scanner Klasse ehrlich gesagt nicht. Aber da sie dir ja nen String zurück gibt, wird sie dir wahrscheinlich immer den ganzen String einer zeile geben, wodurch du alle Chars des Strings in einer for schleife durchgehen solltest


----------



## rei0d (29. Jan 2013)

Also muss ich i vor der while-Schleife mit 0 initialisieren und auch nicht in der if-Anweisung hochzählen lassen, sondern direkt davor oder?



Dumdidum hat gesagt.:


> Warum brauchst du ein Char-Array wenn du sowieso nur die erste Stelle immer benutzt?


Das Char-Array habe ich erstellt, als das mit dem splitten nicht so funktioniert hat. Anscheinend klappt es ja immer noch nicht. Fällt dir eine bessere Möglichkeit ein, als damit?

```
String[] uebergabeArray = str.split("");
```


----------



## Dumdidum (29. Jan 2013)

```
char tmp;
		while (reader2.hasNext()) {
			str = reader2.next();
			for (int i = 0; i < str.length(); i++) {
				tmp = str.charAt(i);
				if (tmp == '1' || tmp == '0' || tmp == '-') { 
					werteArray.add(tmp);
				} else {
					continue;
				}
			}
		}
```

Das wäre dein code abgewandelt...

und wenn du es mit split machen würdest müsstest du:


```
String[] uebergabeArray = str.split(" "); // leerzeichen nicht vergessen!
```


----------



## rei0d (29. Jan 2013)

Ein großes Danke nochmal, es funktioniert endlich!


----------

