JTable Problem

Status
Nicht offen für weitere Antworten.

metalsoft

Mitglied
hi jungs

ich arbeite grad an nem mail programm um mich mit java vertraut zu machen .. jedenfalls will ich die mails die aufm Imap server sind in ner entsprechenden Tabelle anzeigen lassen. Demnach kämpf ich grad mit JTable und hab mir das tut von Beni zur hilfe genommen. Ich hab aus "Teil 2 - Wie kommen Daten in die Tabelle? " die "- 4. Möglichkeit - TableModel " gewählt. Hab das dann alles entsprechend abgeändert für meine mail zwecke .. Ich hau jetz mal den ganzen Quellcode hier rein in der hoffnung der eine oder andere schaut mal durch :

Hier erstmal das Fenster wo die tabelle drin erscheinen soll :
Code:
package mail;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Container; 


public class ImapWin extends JFrame {
static JScrollPane scrollPane = null ;
static JTable table = null ;
static ImapWin ImapFrame = null;
String lookAndFeel = null;
	
	public ImapWin () {
	ImapModel model = new ImapModel();
	
  	  lookAndFeel = UIManager.getSystemLookAndFeelClassName() ;
  	  try {
	      UIManager.setLookAndFeel(lookAndFeel);
	      } catch (Exception e) { };
      this.setBounds(0,0,400,250);
      this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE );	
      table = new JTable (model) ;
      
      ImapFrame.getContentPane().add( new JScrollPane( table ) );
      

      scrollPane = new JScrollPane(table);
      //table.setPreferredScrollableViewportSize(new Dimension(500, 70));
      
      this.getContentPane().add(scrollPane);
      this.setVisible(true);

	}
	public static void main(String[] args) {
		
	}
	
//	 Stellt einfach eine neue Instanz einer MailInfo her.
	   public static MailInfo createMailInfo( Boolean read , Boolean delete , Boolean down , String from , String to , String subj , String date )
             {
	   	return new MailInfo( read , delete , down , from , to , subj , date );
	      } 
}


Da drin wird ja dann das ImapModel für die Tabelle aufgerufen :
Code:
class ImapModel implements TableModel {
	   private Vector MailInfos = new Vector();
	   private Vector listeners = new Vector();

	   public void addMailInfo ( MailInfo mailinfo){
	   	int index = MailInfos.size();
	   	MailInfos.add(mailinfo);
	   	
	   	//Zuerst ein Event, "neue Row an der Stelle index" herstellen 
	      TableModelEvent e = new TableModelEvent( this, index, index,
	            TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT );
	      
	      // Nun das Event verschicken
	      for( int i = 0, n = listeners.size(); i<n; i++ ){
	         ((TableModelListener)listeners.get( i )).tableChanged( e );
	      } 
	   }
	public int getColumnCount() {
		return 7;
	}

	public int getRowCount() {
		return MailInfos.size();
	}

	public boolean isCellEditable(int arg0, int arg1) {
		// Hier für die checkboxen true setzen
		return false;
	}

	public Class getColumnClass(int arg0) {
		switch(arg0){
		case 0:return Boolean.class ;
		case 1:return Boolean.class ;
		case 2:return Boolean.class ;
		case 3:return String.class ;
		case 4:return String.class ;
		case 5:return String.class ;
		case 6:return String.class ;	
		default: return null ;
		}
		
	}

	public Object getValueAt(int arg0, int arg1) {
		MailInfo mailinfo = (MailInfo)MailInfos.get(arg0);
		switch(arg1){
		case 0:return mailinfo.isRead() ;
		case 1:return mailinfo.isDown();
		case 2:return mailinfo.isDelete();
		case 3:return new String(mailinfo.getSubj()) ;
		case 4:return new String(mailinfo.getFrom()) ;
		case 5:return new String(mailinfo.getTo()) ;
		case 6:return new String(mailinfo.getDate()) ;
		default: return null ;
		}
	}

	public void setValueAt(Object arg0, int arg1, int arg2) {
	}

	public String getColumnName(int arg0) {
		switch(arg0){
		case 0: return "Read" ;
		case 1: return "Down" ;
		case 2: return "Del" ;
		case 3: return "Betreff" ;
		case 4: return "Absender" ;
		case 5: return "Empfänger" ;
		case 6: return "Datum" ;
		default: return null; 
		}
		
	}

	public void addTableModelListener(TableModelListener arg0) {
	listeners.add(arg0);
		
	}

	public void removeTableModelListener(TableModelListener arg0) {
	listeners.remove(arg0) ;
		
	}

}

Und hier dann noch die Klasse MailInfo die verwendet wird :
Code:
public class MailInfo {
	private Boolean read ;
	private Boolean down ;
	private Boolean delete ;
	private String to ;
	private String from ;
	private String subj ;
	private String date ;
	
	public MailInfo( Boolean read , Boolean delete , Boolean down , String from , String to , String subj , String date ){
		this.date = date ;
		this.down = down ;
		this.read = read ;
		this.delete = delete ;
		this.from = from ;
		this.to = to ;
		this.subj = subj ;		
	}
	public Boolean isRead(){return read;}
	public Boolean isDown(){return down;}
	public Boolean isDelete(){return delete;}
	public String getTo(){return to;}
	public String getFrom(){return from;}
	public String getSubj(){return subj;}
	public String getDate(){return date;}
	
}

Aus meinem Hauptfenster heraus wird dann per buttonklick dieses ImapWin aufgerufen
Code:
ImapWin.ImapFrame = new ImapWin();
und das erscheind dann garnich mehr ( hat aber funktioniert bevor ich die sache mit der tabelle eingebaut hab ) und eclipse sagt folgendes :
java.lang.NullPointerException
at mail.ImapWin.<init>(ImapWin.java:29)
at mail.Toolbar1Actions.button_actionPerformed1(Toolbar1Actions.java:24)
at mail.Window$2.actionPerformed(Window.java:94)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$ForwardActionEvents.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.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.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.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(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)

Mir sagt das leider garnicht so viel also frag ich euch mal ... danke wenn sichs jemand antut 😉

Edit von Roar: Quotes zu codes gemacht
 
Das liegt wohl daran, dass du auf die statische Variablen "ImapFrame" zugreiffen willst, während sie noch null ist.

Code:
public class ImapWin extends JFrame {
  static ImapWin ImapFrame = null;   

  public ImapWin () {
     
      ImapFrame.getContentPane().add( new JScrollPane( table ) );

Einfach das "ImapFrame." weglassen, dann kommt das Fenster.
 
Astrein danke , das heisst ja das ich das relativ gut und fehlerfrei von deinem tut übernommen und abgeändert hab ... funktionierte auf anhieb problemlos .. weiss garnich warum ich da überhaupt imapframe geschrieben hab , hab ja paar zeilen später auch this .....

naja auf alle fälle danke
 
Hi

also eine frage quält mich noch , ich müsste nämlich auch mal einen wert in der tabelle zur laufzeit ändern , also ich vermute mal über :
public void setValueAt(Object arg0, int arg1, int arg2) {
}

muss ich dann über arg1 aus dem Vector MailInfos die entsprechende MailInfo nehmen und dann über arg2 rausfinden welche wert der MailInfo geändert wurde und dann arg0 dafür setzen ?
 
Ja, das sollte so funktionieren.

Normalerweise ist diese Methode dazu da, dass das JTable sein Model verändern kann (wenn der Benutzer was im JTable eingibt). Du bist also nicht gezwungen genau diese Methode zu benutzen, sondern kannst Dir auch eine Abkürzung suchen

(P.S: nicht vergessen das JTable von den Veränderungen zu unterrichten :wink: ).
 
hi

genau solche dinge fallen mir noch ein wenig schwer , ich vermute mal irgendeiner dingsdaChange listener muss da noch irgendwie irgendwo benachrichtigt werdne , abgesehen von der tatsache das ich probleme hab überhaupt was mit der setValue methode anzufangen

ich hab erstmal meine MailInfo ergänzt durch die set aufrufe

Code:
public class MailInfo {
	private boolean read ;
	private boolean down ;
	private boolean delete ;
	private String to ;
	private String from ;
	private String subj ;
	private String date ;
	
	public MailInfo( boolean read , boolean delete , boolean down , String from , String to , String subj , String date ){
		this.date = date ;
		this.down = down ;
		this.read = read ;
		this.delete = delete ;
		this.from = from ;
		this.to = to ;
		this.subj = subj ;		
	}
	public boolean isRead(){return read;}
	public boolean isDown(){return down;}
	public boolean isDelete(){return delete;}
	public String getTo(){return to;}
	public String getFrom(){return from;}
	public String getSubj(){return subj;}
	public String getDate(){return date;}
	public void setRead(boolean isread){read=isread;}
	public void setDown(boolean isdown){down=isdown;}
	public void setDelete(boolean isdelete){delete=isdelete;}
	
}

also diese :
Code:
	public void setRead(boolean isread){read=isread;}
	public void setDown(boolean isdown){down=isdown;}
	public void setDelete(boolean isdelete){delete=isdelete;}

die sind doch erstmal richtig oder ?

Dann müsste ich ja bei setValueAt irgendwie mal was brauchbares reinschreiben aber ich weiss nich wie ich aus dem Object arg0 einen boolean wert machen soll ..

Code:
	public void setValueAt(Object arg0, int arg1, int arg2) {
		MailInfo mailinfo = (MailInfo)MailInfos.get(arg1);
		switch(arg2){
		case 0:mailinfo.setRead(arg0);
		case 1:mailinfo.setDown(arg0);
		case 2:mailinfo.setDelete(arg0);
		}
	}

da bräuchte ich mal hilfe und dann halt wie ich das JTable von den Veränderungen unterrichte ..
 
Du benötigst einen Cast um ein Object in was anderes zu verwandeln.
Code:
Object obj = ...
Boolean bool = (Boolean)obj;
Sollte obj kein Boolean sein, gibts eine ClassCastException.


Mit "das JTable unterrichten" meine ich z.B. das hier:
Code:
      public void addMailInfo ( MailInfo mailinfo){
         int index = MailInfos.size();
         MailInfos.add(mailinfo);
  // ####################  ab hier wird unterrichtet #############
         //Zuerst ein Event, "neue Row an der Stelle index" herstellen
         TableModelEvent e = new TableModelEvent( this, index, index,
               TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT );
        
         // Nun das Event verschicken
         for( int i = 0, n = listeners.size(); i<n; i++ ){
            ((TableModelListener)listeners.get( i )).tableChanged( e );
         }
  // #################################################
      }

Das kannst du eigentlich so kopieren, Du musst nur das TableModelEvent anders zusammenbauen.
In der API hat es beim TableModelEvent ganz oben 7 Beispiele, wie man ein Event zusammenbauen kann, das 5. kann man benutzen, wenn eine einzige Zelle verändert wurde. Guck mal nach.
 
hi

Code:
case 0:mailinfo.setRead((boolean)arg0);

so hab ich das grad probiert und da sagts mir ganz frech "cannot cast from object to boolean"

was da los ?
 
Hi

also wenn ich Boolean verwende ( gibs ne möglichkeit boolean in Boolean umzuwandeln ? ) muss ich diese stelle korrigieren :

case 0:return mailinfo.isRead() ? Boolean.TRUE : Boolean.FALSE ;

wie mach ich das dann ?
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben