GUI Programmierung: wie kommunizieren Klassen?

Manuel Jung

Grünschnabel
Hallo zusammen, ich habe ein Problem dass mich bereits seit Tagen beschäftigt. Ich habe ein JFrame, darunter liegt ein JPanel welches einen JButton beinhaltet. Wenn ich auf den button klicke soll dem JFrame ein weiteres JPanel hinugefügt werden. Allerdings weiß ich nicht wie ich genau auf diese eine Instanz von JFrame zugreifen soll. Hier mal ein Beispielcode:


##Main Klasse
Code:
import javax.swing.JFrame;


public class Main {

	static JFrame frame;
	static DP dp = new DP();
	
	
	public static void main(String[] args) 
	{
		frame = new JFrame();
		frame.setSize(1000, 700);
		
		frame.add(dp);
		
		frame.setVisible(true);
		
	}

}

##DP Klasse
Code:
import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JDesktopPane;


public class DP extends JDesktopPane
{
	Menu menu;
	Output out;
	
	DP()
	{
		setBackground(Color.WHITE);
		setLayout(new BorderLayout());
		
		menu = new Menu();
		out = new Output();
		
		add(menu, BorderLayout.NORTH);
		
		
	}
}

##Menu Klasse
Code:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;


public class Menu extends JPanel implements ActionListener
{
	JButton button;
	Output out;
	DP dp = new DP(); 	// <-- wie referenziert man auf eine bestimmte Klasse?
						// ich will auf die in Main erstelle Instanz von DP verweisen,
						// allerdings liefert DP dp = Main.dp null zurück.
	
	Menu()
	{
		setPreferredSize(new Dimension(0,50));
		button = new JButton("Button");
		out = new Output();
		setLayout(null);
		add(button);
		
		
		button.setBounds(0, 0, 100, 50);
		button.addActionListener(this);
		button.setActionCommand("button");
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		if("button".equals(e.getActionCommand()));
		{
			dp.add(out, BorderLayout.WEST);  	// Soll dp ein weiteres JPanel hinzufügen
												 
												
		}
	}
}

## Output Klasse (soll hinzugefügt werden über einen User Klick)
Code:
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JPanel;


public class Output extends JPanel
{
	Output()
	{
		setPreferredSize(new Dimension(400,0));
		setBackground(Color.BLUE);
	}
}


Mir würden 3 theoretische Möglichkeiten einfallen, wobei ich nicht weiß ob und wie sie realisierbar sind:

1: Referenzierung über eine ID
2: Instanz der Klasse über Konstruktor mitgeben
3: auf Main.dp referenzieren ( liefert allerdings NULL zurück)

Ich danke schon mal für das lösen meines Problems.

Beste Grüße,

Manu
 

youza

Erfahrenes Mitglied
Also ich hab dir den Code mal korrigiert allerdings find ich dein Aufteilung etwas übertrieben Kapselung in allen Ehren :D
erstmal hab ich ein Package erstellt - man sollte nicht das Default Package verwenden.
Das Frame hab ich in eine extra Klasse aufgeteilt da du hier nicht mit einem statischen JFrame arbeiten solltest.
Also jetzt mal meine Klassen:
(Package: com.youza.tutorial)
Main:
Java:
package com.youza.tutorial;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new MyFrame();
	}

}
DP
Java:
package com.youza.tutorial;

import java.awt.BorderLayout;
import java.awt.Color;
 
import javax.swing.JDesktopPane;
 
 
public class DP extends JDesktopPane
{
    /**
	 * 
	 */
	private static final long serialVersionUID = -1307553122008648953L;
	private Menu menu;
    
    public DP()
    {
        setBackground(Color.WHITE);
        setLayout(new BorderLayout());  
        menu = new Menu(this);
        add(menu, BorderLayout.NORTH);        
    }
}
Menu
Java:
package com.youza.tutorial;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JPanel;
 
 
public class Menu extends JPanel implements ActionListener
{
    /**
	 * 
	 */
	private static final long serialVersionUID = -1317124069890045291L;
	private JButton button;
    private Output out;
    private DP dp;
    
    public Menu(DP dp)
    {
    	this.dp = dp;
        setPreferredSize(new Dimension(0,50));
        button = new JButton("Button");
        out = new Output();
        setLayout(null);
 
        button.setBounds(0, 0, 100, 50);
        button.addActionListener(this);
        button.setActionCommand("button");
        
        add(button);
    }
 
    @Override
    public void actionPerformed(ActionEvent e) 
    {
        if("button".equals(e.getActionCommand()));
        {
            dp.add(out, BorderLayout.WEST);     // Soll dp ein weiteres JPanel hinzufügen     
            dp.validate();
            dp.invalidate();
            dp.repaint();
        }
    }
}
MyFrame
Java:
package com.youza.tutorial;

import javax.swing.JFrame;

public class MyFrame extends JFrame{
    /**
	 * 
	 */
	private static final long serialVersionUID = 8993685616545338820L;
	
	private DP dp = new DP();
	public MyFrame(){
		
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setSize(1000, 700);
        this.add(dp);
        this.setVisible(true);
	}
	public DP getDp() {
		return dp;
	}
	public void setDp(DP dp) {
		this.dp = dp;
	}
}
Output
Java:
package com.youza.tutorial;

import java.awt.Color;
import java.awt.Dimension;
 
import javax.swing.JPanel;
 
 
public class Output extends JPanel
{
    /**
	 * 
	 */
	private static final long serialVersionUID = 4751416366154904125L;

	public Output()
    {
        setPreferredSize(new Dimension(400,0));
        setBackground(Color.BLUE);
    }
}

Funktioniert.

Edit:
Was hab ich überhaupt gemacht vielleicht noch. Ich hab dem Menu() Konstruktor eine Übergabe Variable gegeben um dem Menu auch die DP dp zu übergeben btw. dp ist kein allzu bezeichnender Name.

Grüße
Youza
 
Zuletzt bearbeitet:

Manuel Jung

Grünschnabel
Besten Dank :)

noch eine kurze Frage:

kann man das auch lösen, ohne DP über den Konstruktor zu übergeben?
Also, zb. indem man über die serialVersionUID referenziert?
 
Zuletzt bearbeitet:

youza

Erfahrenes Mitglied
nope die ist ja private auf Private kann man nicht zugreifen außerdem musst du dann aufpassen da du ja mehr als eine Instanze von dem Objekt haben kannst und wenn du dann drauf zugreifen würdes über irgend eine ID die der Klasse zugewiesen ist kann das Programm ja nicht wissen worauf es zugreifen soll.

Beispiel:
Test
Java:
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Objekt1 instance1 = new Objekt1();
		instance1.setSag_was("hallo");
		Objekt1 instance2 = new Objekt1();
		instance2.setSag_was(" welt!");
		System.out.println(instance1.getSag_was() + instance2.getSag_was());
	}

}
Objekt1
Java:
import javax.swing.JFrame;


public class Objekt1 extends JFrame{	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String sag_was;
	public Objekt1() {
		
	}
	public String getSag_was() {
		return sag_was;
	}
	public void setSag_was(String sag_was) {
		this.sag_was = sag_was;
	}
	
}