bitte mal meinen adressbuch-code checken

Status
Nicht offen für weitere Antworten.

Bwana

Mitglied
Hi,
nachdem ich an der Uni ein Semester lang java-kurs hatte, hab ich mir ein buch gekauft und dieses durchgearbeitet. nun wollte ich mal was eigenes machen und hab gehört ein adressbuch ist eine beliebte anfänger-übung (deshalb auch in dieses Forum gepostet)...gesagt getan.
an hand des JTable Tutorials in den FAQ (ja die hab ich gelesen :wink: ) hab ich auch versucht ein tableModel zu erstellen.
Bevor ich lang rumlaber post ich jetzt einfach mal den code: (ich hoff jemand findet sich bei soviel durcheinander zurecht, da ich wie gesagt noch wenig ahnung von der strukturierung hab)

*Mein größtes Problem ist, dass die Eingabe, die ich gemacht und dem model als neues Eintragsobjekt übergeben habe, nicht in der Tabelle angezeigt wird und ich nicht weiß warum, da es ja im tut auch funktioniert)

*Eine weitere Frage ist, ob meine Klassenaufteilung (+Vererbung etc) sinnvoll ist bzw wie mans besser machen könnte

*Wie speicher ich die geschichte, wenn sie richtig läuft sinnvoll

Klasse Eintrag bündelt einen Adressbuch-Eintrag:
Code:
//	bündelt alle Attribute eines Eintrages und stellt getter/setter zum
//	zugriff zur verfügung
//	Im moment sind der einfachheit halber noch alle atrribute Strings!


package adressbuch2;

public class Eintrag {


		private String name;
		private String vorname;
		private String adresse;
		private String geburtsdatum;
		private String telefonnummer;
		private String email;
		
		public void setName(String neuerName)
		{
			name = neuerName;
		}
		
		public void setVorname(String neuerVorname)
		{
			vorname = neuerVorname;
		}
		
		public void setAdresse(String neueAdresse)
		{
			adresse = neueAdresse;
		}
		
		public void setGeburtsdatum(String neuesDatum)
		{
			geburtsdatum = neuesDatum;
		}
		
		public void setTelefonnummer(String neueNummer)
		{
			telefonnummer = neueNummer;
		}
		
		public void setEmail(String neueEmail)
		{
			email = neueEmail;
		}
		
		public String getName()
		{
			return name;
		}
		
		public String getVorname()
		{
			return vorname;
		}
		
		public String getAdresse()
		{
			return adresse;
		}
		
		public String getGeburtsdatum()
		{
			return geburtsdatum;
		}
		
		public String getTelefonnummer()
		{
			return telefonnummer;
		}
		
		public String getEmail()
		{
			return email;
		}
		
	}

GUI-Gesamt (die oberklasse über der GUI für den Eintrag und der für die Tabellendarstellung)
Code:
package adressbuch2;

import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.*;

public class GuiGesamt extends JFrame{
	
//	TableModel
    final Model meinmodel = new Model();
    
//	Hilfsmethode zum leichteren handling des gridbaglayouts
	protected GridBagConstraints makegbc(int x, int y, int width, int height)
	   {
	    GridBagConstraints gbc = new GridBagConstraints();
	    gbc.gridx = x;
	    gbc.gridy = y;
	    gbc.gridwidth = width;
	    gbc.gridheight = height;
	    gbc.insets = new Insets(1, 1, 1, 1);
	    return gbc;
	   }
}

Die Klasse für das Anlegen eines neuen Eintrags + Gui
Code:
package adressbuch2;
//erzeugt das Fenster in dem ein neuer Eintrag angelegt werden kann

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class EintragGui extends GuiGesamt implements ActionListener {
	
	
	
	//Erzeugung der einzelnen Textfelder und Buttons
	JTextField nameField = new JTextField(15);
	JTextField vornameField = new JTextField(15);
 	JTextField adressField = new JTextField(15);
	JTextField geburtsdatumField = new JTextField(15);
 	JTextField telefonnummerField = new JTextField(15);
 	JTextField emailField = new JTextField(15);
 	JButton cancelButton = new JButton("cancel");
	JButton addEntry	= new JButton("Hinzufügen");
	
	//Konstruktor für die grafische Oberfläche
	public EintragGui()
	{
		setTitle("Neuen Eintrag anlegen");
		
		//verwendung eines gridbaglayouts zur positionierung der Elemente
		GridBagLayout gbl = new GridBagLayout();
    	GridBagConstraints gbc;
	    setLayout(gbl);
	
	    gbc = makegbc(0, 0, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbl.setConstraints(nameField, gbc);
       	add(nameField);
       	
       	gbc = makegbc(0, 1, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbl.setConstraints(vornameField, gbc);
       	add(vornameField);
       	
       	gbc = makegbc(0, 2, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbl.setConstraints(adressField, gbc);
       	add(adressField);
	    
      	gbc = makegbc(0, 3, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbl.setConstraints(geburtsdatumField, gbc);
       	add(geburtsdatumField);
	    
       	gbc = makegbc(0, 4, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbl.setConstraints(telefonnummerField, gbc);
       	add(telefonnummerField);
       	
       	gbc = makegbc(0, 5, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbl.setConstraints(emailField, gbc);
       	add(emailField);
       	
	    gbc = makegbc(1, 0, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.WEST;
       	JLabel nameText = new JLabel("Name");
       	gbl.setConstraints(nameText, gbc);
       	add(nameText);
       	
       	gbc = makegbc(1, 1, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.WEST;
       	JLabel vornameText = new JLabel("Vorname");
       	gbl.setConstraints(vornameText, gbc);
       	add(vornameText);
       	
       	gbc = makegbc(1, 2, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.WEST;
       	JLabel adressText = new JLabel("Adresse");
       	gbl.setConstraints(adressText, gbc);
       	add(adressText);
       
       	gbc = makegbc(1, 3, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.WEST;
       	JLabel geburtsdatumText = new JLabel("Geburtsdatum");
       	gbl.setConstraints(geburtsdatumText, gbc);
       	add(geburtsdatumText);
       	
       	gbc = makegbc(1, 4, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.WEST;
       	JLabel telefonnummerText = new JLabel("Telefonnummer");
       	gbl.setConstraints(telefonnummerText, gbc);
       	add(telefonnummerText);
       	
       	gbc = makegbc(1, 5, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.WEST;
       	JLabel emailText = new JLabel("Email");
       	gbl.setConstraints(emailText, gbc);
       	add(emailText);
     	
       	gbc = makegbc(0, 6, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.EAST;
       	gbl.setConstraints(addEntry, gbc);
       	add(addEntry);
       	
       	gbc = makegbc(1, 6, 1, 1);
       	gbc.fill = GridBagConstraints.BOTH;
       	gbc.anchor = GridBagConstraints.WEST;
       	gbl.setConstraints(cancelButton, gbc);
       	add(cancelButton);
       	
       	addEntry.addActionListener(this);
		cancelButton.addActionListener(this);
		
		WindowListener listener = new WindowAdapter()  
		{
			public void windowClosing(WindowEvent we)
			{
				//versteckt nur das Fenster und gibt den Speicherplatz frei,
				//schließt jedoch nicht die ganze Anwendung
				setVisible(false);
				dispose();
			}
		};
	    addWindowListener(listener);
	}
	
	public void actionPerformed(ActionEvent ae)
	{
		Object eventQuelle = ae.getSource();
		
		if(eventQuelle == addEntry)
		{
			         
// einen neue Instanz vom Typ Eintrag anlegen
            Eintrag neuerEintrag = createEintrag();
            
// den Eintrag dem model hinzufügen
            meinmodel.addEintrag( neuerEintrag );
            
// !! test: in zelle 0,0 steht neu.getName() !!
//           System.out.println(model.getValueAt(0,0));
            
			setVisible(false);
			dispose();
		}

		if(eventQuelle == cancelButton)
		{
			setVisible(false);
			dispose();
		}
	}
	
	public Eintrag createEintrag()
	{
		Eintrag neu = new Eintrag();
		neu.setName(nameField.getText());
		neu.setVorname(vornameField.getText());
		neu.setAdresse(adressField.getText());
		neu.setGeburtsdatum(geburtsdatumField.getText());
		neu.setTelefonnummer(telefonnummerField.getText());
		neu.setEmail(emailField.getText());
		return neu;
	}
}

Das eigentlich Hauptfenster + Tabelle
Code:
package adressbuch2;

//Beinhaltet das eigentliche Hauptfenster

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class MainGui extends GuiGesamt implements ActionListener{

	public MainGui()
	{
		setTitle("Adressbuch");

//Menüleiste
		JMenuBar menubar = new JMenuBar();
		menubar.add(createFileMenu()); 
		setJMenuBar(menubar);
		tabelleAnlegen();
	}
	
	public void tabelleAnlegen()
	{    
// Das JTable initialisieren
	      JTable adresstabelle = new JTable( meinmodel );
	      Container content = getContentPane();
	      content.add( new JScrollPane( adresstabelle ), BorderLayout.CENTER ); 
	}
	
	 public void actionPerformed(ActionEvent event)
	    {
	      if (event.getActionCommand() == "Neuen Eintrag anlegen")
	      {
	    	JFrame eintragRahmen = new EintragGui();
	  		eintragRahmen.setSize(400, 200);
	  		eintragRahmen.setLocationRelativeTo(null);
	  		eintragRahmen.setVisible(true);
	  		eintragRahmen.setResizable(false);
	  		eintragRahmen.setAlwaysOnTop(true);
	      }
	      
	      if (event.getActionCommand() == "Beenden")
	      {
	    	System.exit(0);
	      }
	    }
	
	private JMenu createFileMenu()
	  {
	     JMenu datei = new JMenu("Datei");
	     datei.setMnemonic('D');
	     JMenuItem newEntry;
	     JMenuItem save;
	     JMenuItem quit;
	     
	     //Neuer Eintrag
	     newEntry = new JMenuItem("Neuen Eintrag anlegen");
	     newEntry.addActionListener(this);
	     newEntry.setMnemonic('N');
	     datei.add(newEntry);
	     
	     //Speichern
	     //Noch nicht implementiert, soll aber später mal das array mit seinen
	     //beinhalteten objekten speichern
	     save = new JMenuItem("Speichern");
	     save.addActionListener(this);
	     save.setMnemonic('S');
	     datei.add(save);
	     
	     //Separator
	     datei.addSeparator();
	     
	     //Beenden
	     quit = new JMenuItem("Beenden");
	     quit.addActionListener(this);
	     quit.setMnemonic('B');
	     //hat keinen Konstruktor! Erzeugung nur mit "Factory Methode" getKeyStroke
	     KeyStroke shortcut = KeyStroke.getKeyStroke('B',InputEvent.CTRL_MASK); 
	     quit.setAccelerator(shortcut);
	     datei.add(quit);
	     return datei;
	  }
		
	
}

TableModel (bei dem ich gar nicht wusste, wie ich die Klasse irgendwie mit anderen verbinden soll ?!)
Hier ist auch der einzige codeschnipsel den ich copy/pasted habe, jedoch nicht ganz verstehe, was da genau passiert, nämlich beim verschicken des events/for-schleife.
Code:
package adressbuch2;

import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import javax.swing.event.TableModelEvent;
import java.util.Vector; 

public class Model implements TableModel {

	private Vector eintraege = new Vector();
	private Vector listeners = new Vector(); 
	
    
	public void addEintrag( Eintrag einEintrag )
	{    
//		Das wird der Index des Eintrags
	    int index = eintraege.size();
	    
	    eintraege.add(einEintrag);
	
//	 Jetzt werden alle Listeners benachrichtigt
     
// 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 );
     } 
     
//!!test    System.out.println(this.getValueAt(0,0));
	}
     
//	Anzahl der Einträge
	public int getRowCount()
	{
		return eintraege.size();
	}

//	Anzahl der Attribute von Eintrag (Name, Adresse etc) 
	public int getColumnCount()
	{
		return 6;
	}

//	Die Titel der einzelnen Columns
	public String getColumnName(int column)
	{ 	
		 switch( column )
		 {
		         case 0: return "Name";
		         case 1: return "Vorname";
		         case 2: return "Adresse";
		         case 3: return "Geburtsdatum";
		         case 4: return "Telefonnummer";
		         case 5: return "email";
		         default: return null; 
		 }	         
	}

//	 Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll
	 public Class getColumnClass(int columnIndex)
	 {
		   
	      switch( columnIndex )
	      {
	         case 0: return String.class;
	         case 1: return String.class;
	         case 2: return String.class;
	         case 3: return String.class;
	         case 4: return String.class;
	         case 5: return String.class;
	         default: return null;
	      }
	  }

	  public boolean isCellEditable(int rowIndex, int columnIndex)
	  {
		      return true;
	  }

//	  Der Wert der Zelle (rowIndex, columnIndex)
	  public Object getValueAt(int rowIndex, int columnIndex)
	  {
	      Eintrag eintrag = (Eintrag)eintraege.get( rowIndex );
	      
	      switch( columnIndex )
	      {
	         case 0: return eintrag.getName();
	         case 1: return new String( eintrag.getVorname() );
	         case 2: return new String( eintrag.getAdresse() );
	         case 3: return new String( eintrag.getGeburtsdatum() );
	         case 4: return new String( eintrag.getTelefonnummer() );
	         case 5: return new String( eintrag.getEmail() );
	         default: return null;
	      }
	  }

	public void setValueAt(Object aValue, int rowIndex, int columnIndex)
	{
		      // vorerst keine Implementierung
	}
	public void addTableModelListener(TableModelListener l) {
		 listeners.add( l );

	}

	public void removeTableModelListener(TableModelListener l) {
		 listeners.remove( l );

	}

}

Zu guter letzt die Anwendungsklasse:
Code:
//Erstellt das Hauptfenster und ermöglicht sein schließen

package adressbuch2;
import javax.swing.*;

public class Anwendung {
	
	public static void main(String[] args) {
		
		JFrame mainRahmen = new MainGui();
		mainRahmen.setSize(611, 500);
		mainRahmen.setLocationRelativeTo(null);
		mainRahmen.setVisible(true);
		mainRahmen.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		
	}

}

Ich weiß dass es bestimmt irrsinnig unübersichtlich ist, aber ich wäre sehr sehr dankbar, wenn jemand mal n auge drauf werfen könnte, weil ich allein leider nicht mehr weiter weiss :bahnhof:.
Wie gesagt, die sache kompiliert sich einwandfrei, nur anzeigen will die tabelle nix.

THX im Voraus
 
Bwana hat gesagt.:
*Mein größtes Problem ist, dass die Eingabe, die ich gemacht und dem model als neues Eintragsobjekt übergeben habe, nicht in der Tabelle angezeigt wird und ich nicht weiß warum, da es ja im tut auch funktioniert)

*Eine weitere Frage ist, ob meine Klassenaufteilung (+Vererbung etc) sinnvoll ist bzw wie mans besser machen könnte

*Wie speicher ich die geschichte, wenn sie richtig läuft sinnvoll

Ich weiß dass es bestimmt irrsinnig unübersichtlich ist, aber ich wäre sehr sehr dankbar, wenn jemand mal n auge drauf werfen könnte, weil ich allein leider nicht mehr weiter weiss :bahnhof:.
Wie gesagt, die sache kompiliert sich einwandfrei, nur anzeigen will die tabelle nix.

THX im Voraus

Sieht schon gar nicht schlecht aus!

Erstens: Das Interface TableModel ist etwas sehr dürr, für den Anfang tust du dich deutlich leichter, wenn du von DefaultTableModel erbst - da ist das meiste dann schon drin. Wenn du das tust, müsstest du nach dem Einfügen eines Eintrags noch eine der 'fire...()'-Methoden absenden, dann müsste die Tabelle das auch anzeigen.

Zwotens: Die Klassenaufteilung. Momentan hast du die Oberfläche und die Logik immer in der gleichen Klasse. Schöner (und besser zu Warten) ist eine Aufteilung in Richtung 'Model-View-Control' (MVC). Für den Anfang würde ich vorschlagen, mal aus den Listenern eigene Klassen zu machen.

Drittens: Speichern -- hier hast du vielfältige Möglichkeiten. Du kannst deine einzelnen Adressen oder den ganzen Vektor serialisieren, du kannst die Daten in ein CSV-File schreiben, du kannst anfangen, eine Datenbank einzubauen (z.B. HSQLDB) ...

Viertens: In deinem Model.getValueAt() benutzt du den Copy-Konstruktor von String. Prinzipiell ist das nicht schlecht, aber grad bei String ist das sinnlos. Einfach 'return eintrag.getVorname()' etc. reicht.

Fünftens: Gültigkeitsprüfungen könntest du einbauen (bspw. keine leeren Namen etc.)

Sechstens: Was machst du, wenn jemand mehrere Telefonnummern oder/und E-Mail-Adressen hat?

Für's erste genug? 😉
 
also ich erbe jetzt wie vorgeschlagen von DefaultTableModel

meine add-methode sieht nun folgendermaßen aus:
Code:
public void addEintrag( Eintrag einEintrag )
	{
//	Das neu erstellte Eintragsobjekt wird zum Vektor hinzugefügt
         eintraege.add(einEintrag);

//      Eine ne Row wird geadded und der Vektor übergeben
	    addRow(eintraege);	

//      Jetzt noch eine der geforderten fire-methoden   
	    fireTableDataChanged();
	}

Leider wird immer noch keine neuen zeile angezeigt (nicht mal ne leere). Es wird nur die head-Zeile mit den korrekten column-names angezeigt.
aus der API und anderen Forumseinträgen mit ähnlichen Problemen, schloss ich, dass ich eigentlich keine Listener brauchen ?!
 
Dieses hier funktioniert - hoffe, dass es dir hilft:
Code:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class TableModelTest {

    /**
     * @param args
     */
    public static void main(String[] args) {

        TableModelTest modelTest = new TableModelTest();
        MeinTableModel model = modelTest.new MeinTableModel();

        JTable table = new JTable(model);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        JScrollPane pane = new JScrollPane(table,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        JButton button = new JButton("Zeile anfügen");
        MeinActionListener listener = modelTest.new MeinActionListener(model);
        button.addActionListener(listener);

        JFrame frame = new JFrame();
        frame.setSize(400, 300);
        // Inhalt
        Container contentPane = frame.getContentPane();
        contentPane.add(pane, BorderLayout.CENTER);
        contentPane.add(button, BorderLayout.SOUTH);
        frame.setVisible(true);

    }

    class MeinTableModel extends DefaultTableModel {

        int anzZeilen = 20;

        int anzSpalten = 5;

        Object[] spaltenNamen = new String[anzSpalten];

        Object[][] daten = new String[anzZeilen][anzSpalten];

        MeinTableModel() {
            for (int spalte = 0; spalte < anzSpalten; spalte++) {
                spaltenNamen[spalte] = "Spalte " + spalte;
                for (int zeile = 0; zeile < anzZeilen; zeile++) {
                    daten[zeile][spalte] = "Wert (" + zeile + ", " + spalte
                            + ")";
                }
            }
            super.setDataVector(daten, spaltenNamen);
        }


    }

    class MeinActionListener implements ActionListener {

        private final MeinTableModel model_;

        public MeinActionListener(MeinTableModel model) {
            this.model_ = model;
        }

        public void actionPerformed(ActionEvent e) {
            int anzSpalten = model_.getColumnCount();
            Object[] neueZeile = new Object[anzSpalten];
            for (int i = 0; i < anzSpalten; i++) {
                neueZeile[i] = "Wert";
            }
            model_.addRow(neueZeile);
        }

    }

}
 
Also ein Vorschlag von mir wäre, die Klasse Eintrag zu optimieren. Du könntest einen Konstruktor verwenden und die 6 Strings als public deklarieren, dann hättest einen deutlich kürzeren Code

Code:
public class Eintrag { 


      public String name; 
      public String vorname; 
      public String adresse; 
      public String geburtsdatum; 
      public String telefonnummer; 
      public String email; 

       public Eintrag(String n, String v, String a, String g, String t, String e){
        name=n;
        vorname=v;
        adresse=a;
        geburtsdatum=g;
        telefonnummer=t;
        email=e;
        }
              
   }

Wenn du jetz die Telefonnummer haben willst, greifste einfach per Objektname.telefonnummer drauf zu.


Hoffe durch die Public deklerationen geht nicht all zu viel performance verloren. Sollte es doch so sein, dann kannst ja den Konstruktor behalten. Willst du nachträglich was ändern, so kannst per Objektname.email = "bla" Zuweisungen machen

mfg Tomot
 
@Tomot:
Tolle Idee, diese Mega-Design-Sünde als Tipp an einen Anfänger zu schicken *kopfschüttel*
Du hast noch nie etwas von "Kapeslung" gehört, oder?

@Bwana:
Lass deinen Eintrag so, wie er ist!
 
@SamHotte: wie bereits im post geschrieben, weiß ich nicht, inwiefern das performance zieht. glaub ich beschränke mich dann wohl auf fragestellen als auf hilfsversuche.

Da du dich ja anscheinend bestens mit java auskennst, darfst du mir jetz erklären, wieso ein Konstruktor schlechter ist, als variablen in der klasse per funktionen zu füllen, damit ich auch noch was lerne.
 
Tomot hat gesagt.:
Da du dich ja anscheinend bestens mit java auskennst, darfst du mir jetz erklären, wieso ein Konstruktor schlechter ist, als variablen in der klasse per funktionen zu füllen, damit ich auch noch was lerne.
Das Problem sind die public Variablen. Das durchbricht das Prinzip der Kapselung.
 
Danke, das meinte ich (public-Attribute). Und wenn die Attribute privat sind, dann braucht man Getter-Methoden, um darauf zugreifen zu können.

Das mit dem Konstruktor ist nicht so problematisch, aber du möchtest ja vielleicht auch noch später einen Attributwert ändern, und dann benötigst du - wenn du die Attribute privat gemacht hast - natürlich trotzdem Setter-Methoden.
 
Tomot hat gesagt.:
@SamHotte: wie bereits im post geschrieben, weiß ich nicht, inwiefern das performance zieht. glaub ich beschränke mich dann wohl auf fragestellen als auf hilfsversuche.

Da du dich ja anscheinend bestens mit java auskennst, ...

1. nicht beleidigt sein 😉
2. hat nichts mit Java zu tun, sondern sind allgemeine Grundsätze der OOP - Stichworte Datenkapselung und Kommunikation nur über Schnittstellen.
 
so hab nun versucht das ganze mal bei mir in die verschiedenen Klassen einzubinden und hab auch gleich noch versucht den Rat mit einer eigenen Klassen nur für alle Listener zu verwirklichen.
Mein Problem bleibt aber bestehen: die neu geaddeten zeilen werden nicht angezeigt;
Ich hab zu Testzwecken mal bei jedem Druck auf die "Hinzufügen"-Taste getRowCount() ausgeben lassen und siehe da, die zählt er prima hoch (ist nur in der Tabelle jedoch nicht sichtbar). Drück ich "cancel", nochmal auf "neuer Eintrag" und "hinzufügen", fängt er jedoch wieder von vorne an! Meine Vermutung ist, dass es irgendwie damit zusammenhängt, dass der Hinzufügen-Button in einem anderen Fenster ist, als die Tabelle.
tut mir echt sry, dass ichs immer noch nich auf die Reihe gebracht hab, obwohl ihr mir so tollen code spendiert habt (großes dankeschön dafür nochmal) !

ich poste einfach nochmal meine veränderten Klassen (Eintrag und Anwendung sind gleich wie oben, MainGui und EintragGui sind auch gleich, nur die Listener sind halt jetzt ausgelagert):
Code:
package adressbuch2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;

public class Listener implements ActionListener {

	 private final Model model_;
	 private final JFrame frame_;

     public Listener(Model model, JFrame frame)
     {
         this.model_ = model;
         this.frame_ = frame;
     }

     public void actionPerformed(ActionEvent e) 
     {
    	 if (e.getActionCommand() == "Hinzufügen")
    	 {
         int anzSpalten = model_.getColumnCount();
         Object[] neueZeile = new Object[anzSpalten];
         for (int i = 0; i < anzSpalten; i++) {
             neueZeile[i] = "Wert";
         }
         
         model_.addRow(neueZeile);
         System.out.println(model_.getRowCount());   ///\\\TEST///\\\
        // frame_.setVisible(false);
   	    // frame_.dispose();
   	 
    	 }
    	 
	      if (e.getActionCommand() == "Neuen Eintrag anlegen")
	      {
	    	JFrame eintragRahmen = new EintragGui();
	  		eintragRahmen.setSize(400, 200);
	  		eintragRahmen.setLocationRelativeTo(null);
	  		eintragRahmen.setVisible(true);
	  		eintragRahmen.setResizable(false);
	  		eintragRahmen.setAlwaysOnTop(true);
	      }
	      
	      if (e.getActionCommand() == "Beenden")
	      {
	    	System.exit(0);
	      }
	      
	      if (e.getActionCommand() == "cancel")
	      {
	    	  frame_.setVisible(false);
	    	  frame_.dispose();;
	      }
	      
     }
}
Code:
package adressbuch2;

import javax.swing.table.DefaultTableModel;

public class Model extends DefaultTableModel
{	
	  int anzZeilen = 5;

	  int anzSpalten = 6;

      Object[] spaltenNamen = new String[anzSpalten];
     
      Object[][] daten = new String[anzZeilen][anzSpalten];
      
      Model() {
          for (int spalte = 0; spalte < anzSpalten; spalte++) {
              spaltenNamen[spalte] = "Spalte " + spalte;
              for (int zeile = 0; zeile < anzZeilen; zeile++) {
                  daten[zeile][spalte] = "Wert (" + zeile + ", " + spalte
                          + ")";
              }
          }
          super.setDataVector(daten, spaltenNamen);
          
      } 
	public int getColumnCount()
	{
		    return anzSpalten;
	}
	
	public String getColumnName(int column)
	{ 	
		 switch( column )
		 {
		         case 0: return "Name";
		         case 1: return "Vorname";
		         case 2: return "Adresse";
		         case 3: return "Geburtsdatum";
		         case 4: return "Telefonnummer";
		         case 5: return "email";
		         default: return null; 
		 }	         
	}
	
//	  Der Wert der Zelle (rowIndex, columnIndex)
	  public Object getValueAt(int rowIndex, int columnIndex)
	  {
	     return daten[rowIndex][columnIndex];
	  }
}
Code:
package adressbuch2;

import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.*;

public class GuiGesamt extends JFrame{
	
    final Model meinmodel = new Model();
    Listener ActionListener = new Listener(meinmodel, this);
    
//	Hilfsmethode zum leichteren handling des gridbaglayouts
	protected GridBagConstraints makegbc(int x, int y, int width, int height)
	   {
	    GridBagConstraints gbc = new GridBagConstraints();
	    gbc.gridx = x;
	    gbc.gridy = y;
	    gbc.gridwidth = width;
	    gbc.gridheight = height;
	    gbc.insets = new Insets(1, 1, 1, 1);
	    return gbc;
	   }
	
}

Falls es hilft sind hier zum download die class und java dateien. die Dialog-Klasse die da noch dabei ist, soll mal den user informieren, falls bei irgendwas nich korrekt ist.
 
Hab's jetzt nicht probiert, aber ich würde den Listener auftrennen. Momentan hast du dort das Problem, dass du

1. die ActionCommands nicht über .equals() vergleichst,
2. keine Fehlermeldung erzeugst, wenn keiner deiner Fälle zutrifft.

Mach' aus jeder Alternative einen eigenen, eindeutigen Listener für genau die gewünschte Aktion, dann ist die Fehlersuche einfacher.
 
hmm versteh ich nich so ganz, aber habs mal versucht:
also hab jetzt mal für jede Aktion ein eigenes Listener Objekt gemacht und mit einem Action-Command versehen ala
Code:
Listener addEntryActionListener = new Listener(meinmodel, meinJFrame);
       	addEntry.addActionListener(addEntryActionListener);
       	addEntry.setActionCommand("addEntry");
und die alternativen bei actionPerformed(ActionEvent e) mit equals() mit dem ActionCommand verglichen
Code:
public void actionPerformed(ActionEvent e) 
     {
    	
    	 if ("addEntry".equals(e.getActionCommand()))
    	 {
    		 int anzSpalten = model_.getColumnCount();
    		 Object[] neueZeile = new Object[anzSpalten];
    		 
    		 for (int i = 0; i < anzSpalten; i++)
    		 {
             neueZeile[i] = "Wert";
    		 }
           
    		 model_.addRow(neueZeile);
         
    		 System.out.println(model_.getRowCount());   ///TEST (zählt hoch)
    		 // frame_.setVisible(false);
    		 // frame_.dispose(); 
    	 }
    	 
    	 else if ("newEntry".equals(e.getActionCommand()))
	     {...}
	      
    	 else if ("quit".equals(e.getActionCommand()))
	      {...}
	      
    	 else if ("cancel".equals(e.getActionCommand()))
	      {...}	 
    	 
    	 else // FEHLERMELDUNG
    	 {
    		 JOptionPane.showMessageDialog(frame_, "Fehler");
    	 }	 
    	 
     }

dass man je nachdem von welchem Objekt die Action kommt innerhalb der Methode mit "if" verschiedene Reaktionen zur Wahl stellt, so machen die das auch in nem Tutorial von sun Auch das man mit equals den ActionCommand abgleicht, hab ich von dort...oder meinst du ich soll für jeden Button ne eigene Klasse anlegen, die jeweils ActionListener implementiert und dort jeweils nur die eine Action in actionPerformed() reinschreiben, die der eine spezifische Button machen soll (kam mir bisschen komisch vor).

Die Buttons/Menü tut ja eigentlich auch das was ich erwarte, nur die ver*** Tabelle zeigt einfach keine neue Zeile an. Hab schon aufgehört zu zählen wie oft ich den Laptop heut schon gegen die Wand schmeißen wollt...
 
1. ruhig bleiben
2. mal in Zeile 3 von actionPerformed das ActionCommand ausgeben -- evtl. liegt da der Hase im Pfeffer
3. muss leider für heute off gehen - gute Nacht 😉
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben