Java GUI ohne Inhalt

Endless Storm

Commander
Registriert
Dez. 2008
Beiträge
2.139
Hallo zusammen,

ich schreibe zu (erweiterten) Test-und Lernzwecken eine Kochrezeptverwaltung (war eine Aufgabe aus dem Studium).

Doch in einem Fenster wird mir außer dem Titel und die Buttons unten nichts angezeigt... Nach diversen Einbauten von Testausgaben über die Console kann ich ausschließen, dass es am Datenfluss liegen wird.
Die JComboBox-Componente ist definitiv voll funktionsfähig, da sie unverändert vorher auch lief. Im Einzeltest (vor der Implementierung in dieser Klasse) lief auch die JList, welche sich das RezeptModel zieht...


Vorweg: ich nutze den GridBagLayout-Manager, bevor ich den eingebaut hatte, funktionierte alles noch gut. Seltsam finde ich nur, dass ich im Formeditor alles sehen kann und ich absolut keine Fehlermeldungen oder dergleichen erhalte :(

Hoffe es reicht, dass ich nur diese (unbeschnittene) Klasse poste und nicht alle Klassen:


Code:
public class RezeptNeuGUI extends javax.swing.JDialog
{
	private static final long serialVersionUID = 1L;
	private JButton btnAdd, btnDel, btnCanel, btnUebernehmen, btnOK;
	private JComboBox<String> cbZutaten;
	private JTextArea taZubereitung;
	private JComboBox<String> cbSchwierigkeit;
	private JTextField tfZeit, tfKurzname;
	private ZutatenModel zutatenModel = ZutatenModel.getInstance();
	private AktionsAbhoerer einAktionsAbhoerer = new AktionsAbhoerer();
	private FensterAbhoerer einFensterAbhoerer = new FensterAbhoerer();
	private RezeptModel einRezept = null;
	private JList<String> zutatenListe;

	public RezeptNeuGUI(JFrame parentFrame, RezeptModel einRezept)
	{
		super(parentFrame);
		this.einRezept = einRezept;
		addWindowListener(einFensterAbhoerer);		
		initGUI();
	}

	public RezeptNeuGUI(JFrame parentFrame)
	{
		super(parentFrame);
		einRezept = new RezeptModel();
		addWindowListener(einFensterAbhoerer);
		initGUI();
	}

	private void initGUI()
	{
		try
		{
			this.setLocationRelativeTo(null);
			BorderLayout bl = new BorderLayout();
			this.setLayout(bl);

			{ // Titel
				JLabel titel = new JLabel("Eingabe neues Rezept");
				titel.setFont(new java.awt.Font("Segoe UI", 1, 14));
				titel.setBorder(new LineBorder(new java.awt.Color(0, 0, 0), 1,
						false));
				titel.setHorizontalTextPosition(SwingConstants.CENTER);
				titel.setHorizontalAlignment(SwingConstants.CENTER);
				this.add(titel, BorderLayout.NORTH);
			}

			{ // unteres Button-Panel
				JPanel panelButtons = new JPanel();

				this.add(panelButtons, BorderLayout.SOUTH);
				btnOK = new JButton("OK");
				btnOK.setPreferredSize(new Dimension(100, 23));
				btnOK.addActionListener(einAktionsAbhoerer);
				panelButtons.add(btnOK);

				btnUebernehmen = new JButton("Übernehmen");
				btnUebernehmen.setPreferredSize(new Dimension(100, 23));
				btnUebernehmen.addActionListener(einAktionsAbhoerer);
				panelButtons.add(btnUebernehmen);

				btnCanel = new JButton("Abbrechen");
				btnCanel.setPreferredSize(new Dimension(100, 23));
				btnCanel.addActionListener(einAktionsAbhoerer);
				panelButtons.add(btnCanel);
			}

			{ // GridBagPanel
				JPanel panelGbl = new JPanel();
				this.add(panelGbl, BorderLayout.CENTER);
				GridBagLayout gbl = new GridBagLayout();
				panelGbl.setLayout(gbl);
				GridBagConstraints gbc = new GridBagConstraints();
				gbc.insets = new Insets(4, 4, 4, 4);

				gbc.fill = GridBagConstraints.CENTER;

				{ // Labels
					gbc.gridx = 0; // x-Position
					gbc.gridy = 0; // y-Position
					gbc.gridheight = 1;
					gbc.gridwidth = 1;
					gbc.weightx = 1.0;
					gbc.weighty = 0.5;
					JLabel j1 = new JLabel("Kurzname");
					gbl.setConstraints(j1, gbc);
					panelGbl.add(j1, gbc);

					gbc.gridx = 2; // x-Position
					gbc.gridy = 0; // y-Position
					JLabel j2 = new JLabel("Dauer(min)");
					gbl.setConstraints(j2, gbc);
					panelGbl.add(j2, gbc);

					gbc.gridx = 0; // x-Position
					gbc.gridy = 1; // y-Position
					JLabel j3 = new JLabel("Schwierigkeit");
					gbl.setConstraints(j3, gbc);
					panelGbl.add(j3, gbc);

					gbc.gridx = 0; // x-Position
					gbc.gridy = 2; // y-Position
					JLabel j4 = new JLabel("Zubereitung");
					gbl.setConstraints(j4, gbc);
					panelGbl.add(j4, gbc);

					gbc.gridx = 2; // x-Position
					gbc.gridy = 1; // y-Position
					JLabel j5 = new JLabel("Zutaten");
					gbl.setConstraints(j5, gbc);
					panelGbl.add(j5, gbc);
				}

				{ // TextFields
					gbc.gridx = 1; // x-Position
					gbc.gridy = 0; // y-Position
					tfKurzname = new JTextField();
					tfKurzname.setPreferredSize(new Dimension(120, 23));
					gbl.setConstraints(tfKurzname, gbc);
					panelGbl.add(tfKurzname, gbc);

					gbc.gridx = 3; // x-Position
					gbc.gridy = 0; // y-Position
					tfZeit = new JTextField();
					tfZeit.setPreferredSize(new Dimension(120, 23));
					gbl.setConstraints(tfZeit, gbc);
					panelGbl.add(tfZeit, gbc);
				}

				{ // ComboBox Schwierigkeit
					gbc.gridx = 1; // x-Position
					gbc.gridy = 1; // y-Position
					cbSchwierigkeit = new JComboBox<>();
					cbSchwierigkeit.addItem("Leicht");
					cbSchwierigkeit.addItem("Mittelschwer");
					cbSchwierigkeit.addItem("Schwer");
					cbSchwierigkeit.setPreferredSize(new Dimension(120, 23));
					gbl.setConstraints(cbSchwierigkeit, gbc);
					panelGbl.add(cbSchwierigkeit, gbc);
				}

				{ // Kombinierte ComboBox Zutaten
					gbc.gridx = 3; // x-Position
					gbc.gridy = 1; // y-Position
					DefaultComboBoxModel<String> cbZutatenModel = new DefaultComboBoxModel<>(
							zutatenModel.getVector());
					cbZutaten = new JComboBox<>(cbZutatenModel);
					cbZutaten.setPreferredSize(new Dimension(120, 23));
					cbZutaten.setEditable(true);
					gbl.setConstraints(cbZutaten, gbc);
					panelGbl.add(cbZutaten, gbc);
				}

				{ // RezeptZutaten-Feld
					gbc.fill = GridBagConstraints.BOTH;
					gbc.gridx = 3; // x-Position
					gbc.gridy = 3; // y-Position
					gbc.gridheight = 1;
					gbc.gridwidth = 1;
					gbc.weighty = 5;
					zutatenListe = new JList<>();
					setZutatenModel();
					getContentPane().add(zutatenListe);
					zutatenListe.setBorder(new LineBorder(new java.awt.Color(0,
							0, 0), 1, false));
					gbl.setConstraints(zutatenListe, gbc);
					panelGbl.add(zutatenListe, gbc);
				}

				{ // Zubereitungsfeld
					gbc.gridx = 0; // x-Position
					gbc.gridy = 3; // y-Position
					gbc.gridwidth = 3;
					taZubereitung = new JTextArea();
					taZubereitung.setLineWrap(true);
					JScrollPane scrollZutaten = new JScrollPane(taZubereitung);
					gbl.setConstraints(scrollZutaten, gbc);
					panelGbl.add(scrollZutaten, gbc);
				}

				{ // Separates Panel für + und -
					JPanel panelPlusMinus = new JPanel(new GridLayout());
					gbc.fill = GridBagConstraints.HORIZONTAL;
					gbc.gridx = 3; // x-Position
					gbc.gridy = 2; // y-Position
					gbc.gridheight = 1;
					gbc.gridwidth = 1;
					gbc.weighty = 0.5;
					gbl.setConstraints(panelPlusMinus, gbc);
					panelGbl.add(panelPlusMinus, gbc);

					btnAdd = new JButton("+");
					btnAdd.addActionListener(einAktionsAbhoerer);
					panelPlusMinus.add(btnAdd);

					btnDel = new JButton("-");
					btnDel.addActionListener(einAktionsAbhoerer);
					panelPlusMinus.add(btnDel);
				}
				gbl.columnWeights = new double[] { 0.1, 0.1, 0.1, 0.1 };
				gbl.columnWidths = new int[] { 7, 7, 7, 7 };
				gbl.rowWeights = new double[] { 0.1, 0.1, 0.1, 0.1 };
				gbl.rowHeights = new int[] { 7, 7, 7, 7 };
			}

			// this.pack();
			this.setSize(450, 350);
			this.setResizable(false);
			
			this.setVisible(true);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			System.err.println("Fehler: " + e);
		}
	}

	public void setZutatenModel()
	{
		if (einRezept != null)
		zutatenListe.setModel(einRezept);
	}
	
	public void leereTextFields()
	{
		einRezept = new RezeptModel();
		fuelleTextFields();
	}

	public void fuelleTextFields()
	{
		tfKurzname.setText(einRezept.getKurzname());
		tfZeit.setText(einRezept.getZeit());
		cbSchwierigkeit.setSelectedItem(einRezept.getSchwierigkeit());
		taZubereitung.setText(einRezept.getZubereitung());
	}

	public void closeWindow()
	{
		this.dispose();
	}

	public void uebernehmen()
	{
		// TODO
	}

	public void testeingabe()
	{
		RezeptModel r = new RezeptModel();
		r.setKurzname("Testname");
		r.setZeit("1:20");
		r.setZubereitung("Backen, fertig");
		r.setSchwierigkeit("Leicht");
		r.addZutaten("Mehl");
		r.addZutaten("Zucker");
		Container c = Container.getInstance();
		c.addRezept(r);
	}

	// Aktionsabhörer
	// ***********************************************************************
	public class AktionsAbhoerer implements ActionListener
	{
		// Operationen
		public void actionPerformed(ActionEvent event)
		{
			// Auslösendes Kommando feststellen mit getActionCommand
			String eineOption = event.getActionCommand();
			if (eineOption.equals("OK"))
			{
				uebernehmen();
				closeWindow();
			}
			else if (eineOption.equals("Übernehmen"))
			{
				uebernehmen();
				leereTextFields();
			}
			else if (eineOption.equals("Abbrechen"))
			{
				closeWindow();
			}
			else if (eineOption.equals("-"))
			{
				einRezept.deleteZutaten(cbZutaten.getSelectedItem().toString());
			}
			else if (eineOption.equals("+"))
			{
				setZutatenModel();
				einRezept.addZutaten(cbZutaten.getSelectedItem().toString());
				if (!zutatenModel.contains(cbZutaten.getSelectedItem()))
				{
					zutatenModel.addElement((String) cbZutaten
							.getSelectedItem());
				}
			}
		}
	}

	// FensterAbhörer
	// ***********************************************************************
	public class FensterAbhoerer extends WindowAdapter
	{
		// Ereignis Schließen des Fensters
		public void windowClosing(WindowEvent event)
		{
			dispose();
		}
	} // Ende FensterAbhoerer
}

Einmal das Bild wie es aussehen soll und wie es derzeit aussieht...
Hoffe ihr blickt in meinem Durcheinander durch, so ganz fertig ist der Code auch noch nicht. Verbesserungsvorschläge oder Fragen sind natürlich willkommen!

leer.pngsoll.png

Schönen Abend dann noch und vielen Dank im voraus.
Endless Storm
 
Exakt für das bauen der GUI hab ich damals einfach den WindowBuilder benutzt. Der ist sehr einfach zu benutzen und man kann seine Oberfläche relativ schnell zusammen klicken.
http://www.eclipse.org/windowbuilder/
 
Also ich nutze seit Beginn des Studium-Moduls für GUIs: Jigloo.
Das Problem wird wohl dennoch dasselbe bleiben, für sauberen, strukturierten Code muss man selber Hand anlegen und überflüssige (doppelte/identische) Codezeilen entfernen und ggf die Inhalte der GUI nach Themen sortiert untereinanderbringen, wie ich es gemacht habe.

Hat denn sonst niemand eine Idee, woran es liegen könnte? :(

edit

Habe das Problem isoliert, es ist die JList im Paket ab Zeile 155. Hier noch einmal separatiert:

Code:
			{ // RezeptZutaten-Feld
				gbc.fill = GridBagConstraints.BOTH;
				gbc.gridx = 3; // x-Position
				gbc.gridy = 3; // y-Position
				gbc.gridheight = 1;
				gbc.gridwidth = 1;
				gbc.weighty = 5;
				zutatenListe = new JList<>();
				setZutatenModel();
				getContentPane().add(zutatenListe);
				zutatenListe.setBorder(new LineBorder(new java.awt.Color(0, 0,
						0), 1, false));
				gbl.setConstraints(zutatenListe, gbc);
				panelGbl.add(zutatenListe, gbc);
			}

Was ist hier drin mache ist folgendes:
Beim aufrufen der GUI wird entweder ein Rezept mit übergeben, welches zwecks Bearbeitung in die Felder eingelesen wird. Ansonsten wird ein neues Rezept erstellt mit (so habe ich es zumindest geplant und gehofft richtig umgesetzt zu haben) leeren Inhalten (nicht null wie ich hoffe und testen wollte).
Da die Rezepte im "RezeptModel extends DefaultListModel<String> implements Serializable" sitzen und die Rezeptattribute per Klassenattribute und die Zutaten dieses konkreten Rezeptes innerhalb des DefaultListModels gespeichert werden, kann ich um an die Zutatenliste zu kommen, doch das RezeptModel in die JList laden, oder nicht?

Kommentiere ich den oben stehenden Code aus, zeigt er mir wieder alles an...

Hoffe ihr könnt mir nun Tipps geben was ich hier falsch gemacht haben könnte!
Danke im voraus :)
 
Zuletzt bearbeitet:
Funktioniert es, wenn du diese Zeile auskommentierst?
Code:
getContentPane().add(zutatenListe);

Der doppelte Code im 2. Konstruktor lässt sich übrigens vermeiden, indem du this() verwendest.
 
Hey Danke für deine Antwort, es war tatsächlich die Zeile. Jetzt bekomme ich wieder alle Elemente im GUI angezeigt. Danke nochmal :D

Deinen Rat mit dem doppeltem Konstruktor habe ich befolgt, denke so war es gemeint:

Code:
	public RezeptNeuGUI(JFrame parentFrame, RezeptModel einRezept)
	{
		this(parentFrame);
		this.einRezept = einRezept;
	}

	public RezeptNeuGUI(JFrame parentFrame)
	{
		super(parentFrame);
		einRezept = new RezeptModel();
		addWindowListener(einFensterAbhoerer);
		initGUI();
	}

Ist tatsächlich etwas schlanker, bei größeren Konstruktoren sicher eine Überlegung wert anzuwenden!


Jetzt kann ich weiter testen. Mal schauen, aktuell spinnt er noch etwas, wenn ich aus der JComboBox mit der allgemeinen Zutatenauswahl via "Plus-Button" eine Zutat dem Rezept hinzufüge, übernimmt der teilweise irgendeinen Murks, markiere ich nichts und sage "+", kopiert er alle rüber... Ich bastel dann noch etwas :D

Vielen Dank bis hierhin und einen schönen Abend noch!
 
Endless Storm schrieb:
Deinen Rat mit dem doppeltem Konstruktor habe ich befolgt, denke so war es gemeint:
Fast ;)
Code:
	public RezeptNeuGUI(JFrame parentFrame, RezeptModel einRezept)
	{
		super(parentFrame);
		this.einRezept = einRezept;
		addWindowListener(einFensterAbhoerer);
		initGUI();
	}

	public RezeptNeuGUI(JFrame parentFrame)
	{
		this(parentFrame, new RezeptModel());
	}
 
Zurück
Oben