AbstractTableModel

ich glaube wir reden aneinander vorbei.

Ich schilder noch einmal:

Also ich habe eine JTable, die ich vorab mit einerm query aus der DB fülle (und anzeige). Dann habe ich die Möglichket über ein Textfeld ein neues query an die DB zu jagen und meine Tabelle wird auch neu geladen. Soweit-sogut.

Nun klicke ich auf irgendeine Zelle und schreibe was rein. Nun Drück ich enter oder klicke woanders hin, dann bleibt der wert aber nicht Der Alte wird angezeigt.

Also muss ich ja den neuen wert in meinen DATENVEKTOR schreiben, komme aber nicht dran

Gruss
brunso
 
Einen neuen Wert brauchst du nicht in deinen Vector schreiben. Den übergibst du nur einmal, den Rest macht die Table. Die hält sich die Daten nach der Übergabe selbst. Sie fragt nicht jedes Mal den Vector, den du übergeben hast, sondern die Kopie die sie sich gemacht hat.
Erster Tip auf jeden Fall nicht mehr die Methode setValueAt überschreiben. Denn die wird aufgerufen, wenn einer den Wert einer Zelle ändert. Und du füllst ja bisher in dieser Methode nur deinen Vector. Das nützt der Table aber nichts. Wenn sie dennoch in der Methode den neuen Wert übernehmen soll, dann musst du super.setValueAt(...) aufrufen. ABER du scheinst das Überschreiben nicht zu brauchen, also lass das.
Wenn das nicht hilft:
Schau dir mal das Standartverhalten der Table an. Normalerweise nimmt sie neue Werte auf. Also muss es ja etwas sein, das du da rein gebaut hast...Eine falsch gesetzte Option, oder eben eine Methode die du falsch überschreibst. Kommentiere also nach ein ander mal verschiedene Sachen aus, und probier obs dann geht.
Aber mein Tip ist wie schon geschrieben: lösche Folgendes einfach raus:
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {

aValue = (Object) data[rowIndex][columnIndex];






}
 
Okay, hab ich gemacht, dann bekomme ich eine NullPointerException. Aus dem weiterne Fehlercode nehme ich an, dass ich meinem Model auch noch einen CellEditor implementieren lassen muss. Sehe ich das richtig ?

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.table.DefaultTableModel.setValueAt(Unknown Source)
at javax.swing.JTable.setValueAt(Unknown Source)
at javax.swing.JTable.editingStopped(Unknown Source)
at javax.swing.AbstractCellEditor.fireEditingStopped(Unknown Source)
at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(Unknown Source)
at javax.swing.DefaultCellEditor.stopCellEditing(Unknown Source)
at javax.swing.JTable$GenericEditor.stopCellEditing(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI$Handler.mousePressed(Unknown Source)
at java.awt.AWTEventMulticaster.mousePressed(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)
 
Poste bitte nochmal deinen Code wie er jetzt ist.
EDIT: Kann es sein, dass dein Query irgendwo null dabei hat? Wenn ja hast du jetzt einen Grund die Methode setValueAt(...) zu überschreiben ;-).
Das sähe dann so aus:
Java:
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {          
   if (aValue==null)aValue=new String();
   super.setValueAt(aValue,rowIndex,columnIndex);
}
 
Zuletzt bearbeitet:
Moin,

auch mit deiner Methode bekomme ich eine NullPointerException.

hier mein Model
Code:
import java.util.Vector;

import javax.swing.table.DefaultTableModel;



public class PXTableModel extends DefaultTableModel{

	/**
	 * 
	 */
	private static final long serialVersionUID = 7505358431169338941L;
	private Vector data;
	private Vector columnNames;

	
	public PXTableModel( Vector data, Vector columnNames) 
	   { 
		this.columnNames = columnNames; 
	    this.data = data;
	   
	    System.out.println(this.columnNames);
	    System.out.println("++++++++++++++++++++++++++++++++++++++");
	    System.out.println(this.data);
	   
	   } 
	    
	   public void setDataVector( Vector data, Vector columnNames ) { 
		   	this.columnNames = columnNames; 
		    this.data = data; 
	        
	   }
	   
	   public Vector getDataVector() { 
	    return data; 
	   } 
	  
	   public int getRowCount() { 	
	      // TODO Automatisch erstellter Methoden-Stub 
	    return data.size(); 
	   }
	   
	   public int getColumnCount() { 
	      // TODO Automatisch erstellter Methoden-Stub 
	    return columnNames.size(); 
	   }
	   
	   public String getColumnName(int col) { 
		return this.columnNames.elementAt(col).toString(); 
	   }
	   
	   public Object getValueAt(int rowIndex, int columnIndex) {
		return ((Vector) getDataVector().get(rowIndex)).get(columnIndex);	
	}

	   public boolean isCellEditable(int row, int col) {
		  
		return true;
		  
	  }
	  
	
}

Hier das Panel, wo es instanziiert wird (achte nicht auf den teilweise doch rechten wirrwarr,, das Layout ist nich nicht fertig, dies dient mehr noch dem testen)
Code:
package de.bwa.projektx.GUI;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import de.bwa.projektx.DB.DBHelper;
import de.bwa.projektx.MODELS.PXTableModel;

public class QueryPanel implements ActionListener, TableModelListener{

	public JScrollPane scrollPane;
	private JPanel queryPanel, setQuery;
	private JTable table;
	public DBHelper db;
	private String query = "select * from artikel_kategorie";
	private JButton fire;
	private JTextField in;
	private PXTableModel tModel;
	private Vector newData;
	
	public JPanel createQueryPanel() {

		
		
		queryPanel = new JPanel();
		queryPanel.setBackground(Color.gray);
		queryPanel.setLayout(new BorderLayout());
		queryPanel.add(BorderLayout.NORTH,setQuery());
		
			
			db = new DBHelper();
			db.Connect(query);
			//db.listTables();
			tModel = new PXTableModel(db.resultData, db.resultColumnNames);
			table = new JTable(tModel);
			//tModel.addTableModelListener(this);
			
		
			scrollPane = new JScrollPane();	
			scrollPane.getViewport().add(table);
		
		
		
			queryPanel.add(BorderLayout.CENTER,scrollPane);

		
	return queryPanel;
	}
	
	public JPanel setQuery() {
		db = new DBHelper();
		db.Connect(query);
		setQuery = new JPanel();
		
		GridBagLayout gbl = new GridBagLayout();
		setQuery.setLayout(gbl);
		GridBagConstraints gbc=new GridBagConstraints();

		//		 Festlegen, dass die GUI-Elemente die Gitterfelder in 
        // waagerechter Richtung ausfüllen:
		gbc.fill=GridBagConstraints.HORIZONTAL;

		// Die Abständer der einzelnen GUI-Elemente zu den gedachten 
        // Gitterlinien festgelegen:
		gbc.insets = new Insets(5,5,5,5);  

		gbc.gridx = 0;  // x-Position im gedachten Gitter
		gbc.gridy = 0;  // y-Position im gedachten Gitter
		gbc.gridheight = 5;  // zwei Gitter-Felder hoch


		
		gbc.gridx=1; 
		gbc.gridy=1;
		gbc.gridheight = 1;
		in = new JTextField(50);
		gbl.setConstraints(in, gbc);
		setQuery.add(in);
		
		gbc.gridx=2; 
		gbc.gridy=3;
		gbc.gridheight = 1;
		
		//gbl.setConstraints(db.listTables(), gbc);
		//setQuery.add(fire);
		
		gbc.gridx=0; 
		gbc.gridy=5;
		gbc.gridheight = 1;
		in = new JTextField(50);
		gbl.setConstraints(in, gbc);
		setQuery.add(in);
		
		gbc.gridx=1; 
		gbc.gridy=5;
		gbc.gridheight = 1;
		fire = new JButton("Finden 0/5");
		gbl.setConstraints(fire, gbc);
		setQuery.add(fire);
		
		

		gbc.gridx=0; 
		gbc.gridy=0;
		gbc.gridheight = 1;
		Button btClose = new Button("0/0");
		btClose.addActionListener(this);
		gbl.setConstraints(btClose, gbc);
		setQuery.add(btClose);


		
		
		
		fire.addActionListener(this);
		
		return setQuery;
	}



	public Vector result(String query) {
			
			db = new DBHelper();
			db.Connect(query);
			newData = db.resultData;
			
			System.out.println(newData);
	return newData;
		
	}
	
	


	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource().equals(fire)) {
			
			System.out.println("You´r fired");
			
			if((!(in.getText()=="")))
			{
			
			
			query = in.getText();
			
	
			this.tModel.setDataVector(result(query), db.resultColumnNames);
			this.tModel.fireTableDataChanged();
			
			
		} else {
				System.out.println("Must schon was eingeben");
				}
			
		}
	}

	public void tableChanged(TableModelEvent arg0) {
		
		
	}
	
	
}

und dann noch der DB Helper, wo ich mir die Daten Ziehe (auch hier im Moment nur Connect() zu betrachten)

Code:
package de.bwa.projektx.DB;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;

public class DBHelper {
	
	 
	
    
     String hostname="xxxxxxx"; 
     String port="3306"; 
     String dbname="xxxx"; 
     String user="xxxx"; 
     String pw="xxxxx"; 	
     Connection conn = null;
     String sql;
     
     public Vector<Vector<Object>> resultData;
     public Vector<String> resultColumnNames;
     
     public Vector<Vector<Object>> Connect(String sql) {
    	 
    	 	resultColumnNames = new Vector<String>(); 
    	 	resultData = new  Vector<Vector<Object>>(); 
    	 	this.sql = sql;
     
     try 
     { 
         Class.forName("com.mysql.jdbc.Driver").newInstance(); 
         String url="jdbc:mysql://"+hostname+":"+port+"/"+dbname; 
         conn=DriverManager.getConnection(url,user,pw); 	
      
         
         Statement stmt=conn.createStatement(); 
         
         ResultSet rs=stmt.executeQuery(sql); 
         ResultSetMetaData rsmd=rs.getMetaData(); 
         
         int columns=rsmd.getColumnCount(); 
        
         
         for (int i = 1; i <= columns; i++) 
         { 
        	
             resultColumnNames.add( rsmd.getColumnName(i) ); 
         } 
         while (rs.next()) 
         { 
             Vector<Object> row = new Vector<Object>(columns); 
             for (int i = 1; i <= columns; i++) 
             { 
            	
                 row.addElement( rs.getObject(i) ); 
             } 
            
                          
             resultData.addElement( row ); 
             
         } 
        
         rs.close(); 
         
         stmt.close(); 
     } 
     catch(Exception e) 
     { 
         System.out.println( e ); 
     }
     
	return resultData;     

     }
     
     public void listTables() {
    	 
    	 try {

    		DatabaseMetaData rsmd = conn.getMetaData();
			ResultSet rs = rsmd.getCatalogs();//getTables(dbname, null, null, null);
			
			  ResultSetMetaData rsmr =rs.getMetaData(); 
			  int counter = rsmr.getColumnCount();
			  
			  System.out.println(counter);
			while (rs.next()) {
				for(int i=1; i<counter ; i++) {
				System.out.println(rs.getObject(i));
				}
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	 
    	 
     }
     
}


Gruss
brunso
 
:suspekt: Mir ist immer noch nicht klar, warum du so viele Methoden in deinem DefaultTableModel überschreibst, in denen du gerade so viel tust wie nötig, oder sogar zu wenig. Ich kann mich ja irren, aber ich sehen keinen Sinn in den Methoden:
- getDataVector
- setDataVector
- getRowCount
- getColumnCount
- getColumnName
- getValueAt
...kommentier die mal aus.

Noch lustiger ist, dass die Methode fehlt, die ich oben geschrieben habe ;-)
 
Zuletzt bearbeitet:
Du,

das habe ich so aus den Büchern/Internet usw. Lach, Deine Methode, Du hast doch geschrieben ich solls gar nicht überschreiben, deshalb habe ich die auch wieder rausgenommen.

naja, vielleicht muss ich auch erstmal in mich gehn und drüber nachdenken :-)

gruss

brunso
 
Ok. Sry. Das war ein bisschen viel hin und her.
Also... was ich jetzt probieren würde:
- Die besagten Methoden auskommentieren.
- Die setValueAt so wie ich sie oben beschrieben habe reinnehmen. (ich bin mir dessen bewüsst dass ich erst sagte "nicht überschreiben, weil es keinen Sinn macht", aber jetzt macht es ja Sinn, weil du so auf den Fall aValue==null reagieren kannst, und dafür einen neuen leeren String übergeben kannst (an die super.setValueAt(...)) )
 
Wärste ne Frau, würd ich Dich jetzt knutschen :-)

IT WORKS.

Mann Mann Mann. Also ich bin der Meinung, ich hab schon recht viel an Literatur(die ich mir auch reinpfeife) Auch wird hier immer bei sowas das Dicke Buch von SunPress empfohlen "JFC beherrschen" - wo es auch extremst ausführlich beschriben ist, aber sehr unverständlich, wie ich finde.

Denn ganz nachvollziehen kann ich das nicht.

Mal sehen, jetzt muss ich nämlich den neu gesetzten wert auch wieder zurückbekommen und in die DB schreiben.

Gruss
brunso
 
Zurück