GUI updaten / Aufklappbare Jpanels

nugat-p

Grünschnabel
Hi liebes Tutorials-Team und liebe anderen Communitymember.

Ich habe zwei Fragen zum Thema Swing und zur GUI ansich.

Vorgeschichte:
Projekt, in dem wir eine Kalendersoftware programmieren müssen.

Sieht soweit auch ganz gut aus, aber da ich noch nie in der Ebene programmiert habe, sind mir da einige Fragen aufgekommen.
In unserer Main starten wir nach dem Loginfenster unser Hauptfenster, welches aus mehreren Componenten und somit JSplitpanes
besteht. Viele der Komponenten sind natürlich in anderen Klassen ausgelagert und werden einfach instanziert und dann in die GUI gebunden.

Nun die Frage: Wenn ich etwa in unserem Minikalender (Jcalendar) einen ChangeListener habe, wie kann er denn aus der
Instanz heraus den anderen Komponenten signalisieren, dass sich etwas geändert hat? Brauch ich dafür einen Singleton?

Beispiel: User klickt auf ein Datum im Minikalender -> Wochenansicht muss sich aus der Datenbank neue Termine holen & die Wochenansicht muss sich dem Termin anpassen.


Frage 2:
Wie implementiere ich eine GUI Komponente, die sich oben ( also horizontal ) aufklappt, wenn ich oben auf einen Button drücke?
Über Splitpanes mit Aufklapppfeil? Kann man das auf und zuklappen dann auch per Befehl auf und zuklappen?

Ich wäre Euch ziemlich dankbar für eine Antwort
Philip
 
Zuletzt bearbeitet:
Frage 2:
Wie implementiere ich eine GUI Komponente, die sich oben ( also horizontal ) aufklappt, wenn ich oben auf einen Button drücke?
Über Splitpanes mit Aufklapppfeil? Kann man das auf und zuklappen dann auch per Befehl auf und zuklappen?
Philip

Das "Aufklappteil" nennt sich Devider. Was du versuchst ist nichts anderes, als die Position dessen zu verändern. Dafür gibt es genug Methoden.
http://java.sun.com/javase/7/docs/api/javax/swing/JSplitPane.html
 
Hi!
Zu Frage 1: Suche mal nach Stichpunkten wie "Swing, Observer Pattern". Da finden sich schon einige Beispiele im Netz. Prinzipiell kann man sich überlegen, eine zentrale Instanz, einen MessageDispatcher, anzulegen. Dort könnten sich Komponenten registrieren, in dem sie mitteilen, an welche Art von Informationen sie interessiert sind. Andere Komponeten, die Informationen weiterleiten möchten, schicken ihre Nachrichten an den Messagedispatcher, welcher sie dann an die interessierten Komponenten weiterleitet. Dieses Vorgehen hat den Vorteil, dass du deine Objekte nicht kreuz und quer allen anderen Objekten bekannt machen musst. Dafür muss man aber ein wenig mehr Arbeit reinstecken...

Zu Frage 2:
Meinst du sowas?
http://www.informit.com/guides/content.aspx?g=java&seqNum=236

*grüssle*
 
Zu 1: Danke =) Werd ich mal schauen, hatte auch schon an Observer gedacht, aber ist natürlich bisschen Arbeit ^^

Zu 2: Joa so ähnlich, nur dass der Knopf dann in der Toolbar ist.

Auf jeden Fall Danke für die Antworten!
Ich werd mich da mal irgendwie morgen dransetzen, da ich heute Prüfung habe und heute Abend Fußball ist :D
Gruß
 
Zu 1: Observer implementiert, aber folgendes Problem

Ich habe als Subjekt jetzt einfach eine Klasse mit momentanem Datum.
Dooferweise werden die GUI Elemente im Konstruktor gebaut, sodass ich beim update gar nichts dran ändern kann..
Wie löse ich das jetzt? Ich brauch ja das JPanel in der Main, um das zusammenzubauen. *confused*

Code:
class CalWidgetMenu extends JPanel implements Observer{
	String mydate = new Date().toString();
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public CalWidgetMenu(CurrentDate currentDate){
		currentDate.addObserver(this);
		setLayout(new FlowLayout(FlowLayout.LEFT));
        FileLocations icons = new FileLocations();
        ImageIcon icon;
	    setLayout(new FlowLayout(FlowLayout.LEFT));
	    icon = new ImageIcon(icons.getgotodayIcon());
	    JButton gotoday = new JButton("Heute", icon);
	    gotoday.setFocusPainted(false);
	    add(gotoday);
	    icon = new ImageIcon(icons.getgopreviousIcon());
	    JButton goprevious = new JButton(icon);
	   	goprevious.setFocusPainted(false);
	    add(goprevious);
	    JLabel myDate = new JLabel (mydate);
	    Font f = new Font("Calibri",Font.PLAIN, 20);
	    myDate.setFont(f);
	    add(myDate, BorderLayout.EAST);
	    icon = new ImageIcon(icons.getgonextIcon());
	    JButton gonext = new JButton(icon);
	    gonext.setFocusPainted(false);
	    add(gonext);
	    setVisible(true);
	}

	@Override
	public void update(Observable o, Object arg) {
		mydate = arg.toString();
 
Hallo!
Welche Komponente soll das aktuelle Datum anzeigen? Das JLabel "myDate"? Dann erstelle dieses doch einfach als Objektvariable!
Code:
class CalWidgetMenu extends JPanel implements Observer{
	String mydate = new Date().toString();
        private JLabel myDate;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public CalWidgetMenu(CurrentDate currentDate){
		currentDate.addObserver(this);
		setLayout(new FlowLayout(FlowLayout.LEFT));
        FileLocations icons = new FileLocations();
        ImageIcon icon;
	    setLayout(new FlowLayout(FlowLayout.LEFT));
	    icon = new ImageIcon(icons.getgotodayIcon());
	    JButton gotoday = new JButton("Heute", icon);
	    gotoday.setFocusPainted(false);
	    add(gotoday);
	    icon = new ImageIcon(icons.getgopreviousIcon());
	    JButton goprevious = new JButton(icon);
	   	goprevious.setFocusPainted(false);
	    add(goprevious);
	    myDate = new JLabel (mydate);
	    Font f = new Font("Calibri",Font.PLAIN, 20);
	    myDate.setFont(f);
	    add(myDate, BorderLayout.EAST);
	    icon = new ImageIcon(icons.getgonextIcon());
	    JButton gonext = new JButton(icon);
	    gonext.setFocusPainted(false);
	    add(gonext);
	    setVisible(true);
	}

	@Override
	public void update(Observable o, Object arg) {
		mydate = arg.toString();
                myDate.setText(mydate);

*grüssle*
 
Ich Dussel!
Code:
//		remove(2);
//		JLabel myDate = new JLabel (mydate);
//	    Font f = new Font("Calibri",Font.PLAIN, 20);
//	    myDate.setFont(f);
//	    add(myDate, 2);

ging auch, aber nur mit 1-2 Sekunden Rechenzeit :)

Klasse!

Kann ich eigentlich auch beim Observer mir mehrere Dinge beobachten lassen?
So ist es zum Beispiel neben dem Datum noch wichtig, welche Ansicht ich anhabe, also Tages-, Wochen- oder Monatsansicht.
Ich kann zwar getter und setter setzen, jedoch kann ich beim notifyen ja nur einen parameter übertragen.
Wie soll ich bei der Updatemethode dann merken, was sich jetzt geändert hat? Oder muss ich da einfach den Typ checken bei
Code:
@Override
	public void update(Observable o, Object arg) {
und dann je nach dem etwas behandeln?
Vielen Dank für diese flotten guten Antworte =)
Hab in den letzten Monaten wirklich viel dazugelernt!
 
Zuletzt bearbeitet:
Hi!
Erstelle dir doch sowas wie ne Nachrichtenklasse, die beinhaltet, was geändert wurde, und die Information, die geändert wurde.

Mal so auf die Schnelle:
Code:
public class MessageObject {
     private String messageType;
     private Object information;


     public static final  String MESSAGE_DATE_CHANGE = "dateChange";
     public static final String MESSAGE_VIEW_CHANGE= "viewChange";

     public MessageObject(String messageType,Object information ){
         this.messageType = messageType;
         this.information = information;
     }

    /**
     * @return the messageType
     */
    public String getMessageType() {
        return messageType;
    }

    /**
     * @param messageType the messageType to set
     */
    public void setMessageType(String messageType) {
        this.messageType = messageType;
    }

    /**
     * @return the information
     */
    public Object getInformation() {
        return information;
    }

    /**
     * @param information the information to set
     */
    public void setInformation(Object information) {
        this.information = information;
    }

}


Code:
 public void update(Observable o, Object arg) {
        MessageObject msg = (MessageObject)  arg;
        if(msg.messageType == MessageObject.MESSAGE_DATE_CHANGE){
            mydate = msg.getInformation().toString();
            myDate.setText(mydate);
        }
        else{
            
        }

    }

*grüssle*
 
Zurück