PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Panel löschen (GUI neu aufbauen)



lousypoetry
26-06-2006, 19:00
Hallo!

Ich hab in meiner GUI ein contentPane, auf dem verschiedene andere Panels sind. Jetzt möchte ich, dass wenn ein Button geklickt wird, sich das aussehen der GUI ändert, sprich die GUI muss neu aufgebaut werden.

Ich hatte mir folgendes überlegt:



contentPane.removeAll();
contentPane = null;
pane1 = null;
pane2 = null;
initialize();

meine initialize()-Funktion sieht so aus:


private void initialize() {

[...]
this.setJMenuBar(getMyMenuBar());
this.setContentPane(getMyContentPane());
this.setTitle("Titel");
[...]
}


die Funktion getMyContentPane() initialisiert dann die anderen Panels (in dem Stil, wie der Eclipse GUI-Builder das aufbaut).

Leider funktioniert es so nicht richtig, d.h. ein Teil er GUI wird richtig dargestellt, zum Teil werden aber Panels doppelt gezeichnet oder verschoben. Gibt es da vielleicht einen besseren weg?

Danke!

bischi
26-06-2006, 19:39
.updateUI() auf jedes geänderte Element sollte gehen.

MfG Bischi

lousypoetry
27-06-2006, 10:58
Ok, also wenn ich zB 2 Panels hab (wobei das blockPane auf dem contentPane liegt) die neu gezeichnet werden sollen würd ich dann



// null setzen damit sie beim Aufruf von getXXPane() neu intialisiert werden
blockPane = null;
contentPane = null;
getBlockPane().updateUI();
getMyContentPane().updateUI();


schreiben? Dann ändert er leider gar nix... :(

bischi
27-06-2006, 10:59
Yepp - plus auf alle Komponenten, die draufliegen: Buttons, Labels,...

MfG Bischi

lousypoetry
27-06-2006, 14:07
Danke für die schnelle Antwort, aber irgendwas mach ich noch falsch. Hab das Problem erst mal reduziert und möchte ein Panel neu zeichnen. Das Panel ist ein normales JPanel, auf dem sich "Blocks" befinden. "Block" ist eine abgeleitete Klasse von JPanel.

Mein Code:


blockPane = null;

// alle Komponenten updaten


for(int i = 0; i < getBlockPane().getComponentCount(); i++) {

((Block) getBlockPane().getComponent(i)).updateUI();

}
getBlockPane().updateUI();


es kommt kein Fehler, aber leider ändert sich auch nichts.

Waxolunist
27-06-2006, 14:31
Ich hätts mit repaint versucht.

bischi
27-06-2006, 15:25
Versuch mal einfach ein .update() auf die Komponenten.

Frage: Wieso machst du überhaupt nen Typcast?

getBlockPane().getComponent(i).updateUI();

sollte doch auch gehen?

MfG Bischi

PS: .updateUI() funktioniert auf jeden Fall: Ich hab das mal in nem Programm verwendet, um das L&feel bei allen Komponenten umzustellen...

lousypoetry
27-06-2006, 16:25
Wieso machst du überhaupt nen Typcast?

getBlockPane().getComponent(i).updateUI();

sollte doch auch gehen?


Also ohne den Cast gehts nicht. Muss allerdings was korrigieren: "Block" erbt von JLabel, nicht von JPanel.


Versuch mal einfach ein .update() auf die Komponenten.
Nur update()? Ist die nicht für Graphics Objekte? Oder hab ich das jetzt falsch verstanden?

@Waxolunist
hast du mal ein ganz simples Beispiel? reicht es, repaint() auf das Panel anzuwenden? Oder auch auf alle Komponenten?

bischi
27-06-2006, 16:45
ev hilft auch ein setVisible(false) und anschliessendes setVisible(true) auf das ganze Fenster/Pane.

Versuchs mal mit nur einem Button, den du auch gleich als Variable abspeicherst... Ich bin ganz fest der Meinung, dass updateUI gehen müsste...

MfG Bischi

lousypoetry
27-06-2006, 17:12
Versuchs mal mit nur einem Button, den du auch gleich als Variable abspeicherst... Ich bin ganz fest der Meinung, dass updateUI gehen müsste...


Ich hab mal versucht, ein ganz einfaches Beispiel zu erstellen. Ein Label und ein Button auf einem Panel. Wenn der Button geklickt wird, soll sich der Text vom Label ändern, indem die Komponente neu gezeichnet wird.

bischi
27-06-2006, 17:57
Also bei mir funktioniert folgender Code:



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

public class Test extends JFrame {

private JButton jButton;
private JLabel jLabel;
private JPanel jPanel;


public Test() {
this.setSize(300, 200);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);

Container cp = getContentPane();
cp.setLayout(null);

jButton = new JButton("Los!");
jButton.setBounds(0,10,100,50);
jButton.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent e){
jLabel.setText("Nachher");
}
});
cp.add(jButton);

jPanel = new JPanel(new BorderLayout());
jPanel.setBounds(0,60,300,100);
cp.add(jPanel);

jPanel.add(jLabel = new JLabel("Vorher"));

this.setVisible(true);
}

public static void main(String[] args){
Test test = new Test();
}
}


Sogar ohne updateUI() (was nach API auch wirklich nur für L&F bestimmt wäre...)

MfG Bischi

lousypoetry
28-06-2006, 08:51
sorry, das war jetzt irgendwie ein Missverständnis. Dass das mit jLabel.setText() funktioniert ist klar Und sicherlich auch die sinnvollste Lösung), ich wollte den Austausch des Textes aber erreichen, indem die Komponente neu gezeichnet wird, war etwas unglücklich als Beispiel gewählt.

Aber wenn du noch mal Zeit hast: wie würdest du es machen, wenn du zB drei JLabels hast und auf Button-Klick sollen zwei verschwinden und das dritte eine neue Größe und Farbe bekommen? Mein Wunsch wäre da, dass die Labels neu initialisiert werden und anschließend neu auf das Panel gelegt werden und genau daran scheiter ich.

bischi
28-06-2006, 17:43
Aber wenn du noch mal Zeit hast: wie würdest du es machen, wenn du zB drei JLabels hast und auf Button-Klick sollen zwei verschwinden und das dritte eine neue Größe und Farbe bekommen?
Panel von contentpane entfernen (cp.remove(jPanel)), danach panel neu erstellen und Knöpfe/Label neu drauf setzen...

MfG Bischi

PS: Ähnliches Problem: http://www.mrunix.de/forums/showthread.php?p=207515&posted=1#post207515

lousypoetry
29-06-2006, 14:16
Panel von contentpane entfernen (cp.remove(jPanel)), danach panel neu erstellen und Knöpfe/Label neu drauf setzen...


Das hört sich logisch und einfach an, aber es will bei mir nicht klappen. :(
ich komm soweit, dass er mir auf das Panel, was ersetzt werden soll, die neuen Komponenten setzt (hab ich per Ausgabe geprüft). Sichtbar sind aber trotzdem nur die alten. Darum dachte ich ja, es liegt daran, dass irgendwas nicht neu gezeichnet wird.

Ich hab mal ein Beispiel angehängt, wo ich das versucht hab. Wenn man auf den Button klickt, soll im Panel ein anderer Button durch ein Label ersetzt werden (d.h. der Button soll runter vom Panel, das Label drauf). Ich find nur meinen Fehler leider nicht.

bischi
29-06-2006, 15:15
Könntest du das Beispiel mal ausführbar machen (mit main und allem gesetzt - so dass ich das nur noch zu kompilieren brauch?). Hab keine Lust, wieder am ganzen Code so lange rumzubasteln, bis ichs überhaupt testen kann...

MfG Bischi

lousypoetry
29-06-2006, 15:32
klar, sorry, hab ich nicht dran gedacht! Müsste jetzt ausführbar sein!

bischi
29-06-2006, 18:09
Ich hab in deinem Code ein wenig die Übersicht verloren, drum hab ich meinen weiterentwickelt:


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

public class Test2 extends JFrame {

private JButton jButton;
private JLabel jLabel;
private JPanel jPanel;
private Container cp;


public Test2() {
this.setSize(300, 200);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);

cp = getContentPane();
cp.setLayout(null);

jButton = new JButton("Los!");
jButton.setBounds(0,10,100,50);
jButton.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent e){
cp.remove(jPanel);
cp.update(cp.getGraphics());
jPanel=new JPanel(new BorderLayout());
jPanel.setBounds(0,60,300,100);
jPanel.add(new JButton("es wurde geklickt."));
cp.add(jPanel);
cp.update(cp.getGraphics());
cp.setVisible(false);
cp.setVisible(true);
}
});
cp.add(jButton);

jPanel = new JPanel(new BorderLayout());
jPanel.setBounds(0,60,300,100);
cp.add(jPanel);

jPanel.add(jLabel = new JLabel("Vorher"));

this.setVisible(true);
}

public static void main(String[] args){
Test2 test = new Test2();
}
}

So gehts bei mir.

MfG Bischi

Jana
29-06-2006, 21:16
Vielleicht hilft ja mein Fund weiter.

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

/** Erzeuge ein Swing-Fenster, das mit Buttons und
* Combo-Box sein Look and feel aendern kann
*/
public class LookAndFeel extends JFrame {
Container c; // Container dieses Frames
JButton b1, b2, b3; // Buttons
JComboBox cb; // Combo-Box
JFrame f = this; // Referenz auf dieses Frame

public LookAndFeel() { // Konstruktor
c = getContentPane(); // Container bestimmen
c.setLayout(new FlowLayout()); // Layout setzen

// Erzeuge die Buttons und die Combo-Box
b1 = new JButton("Metal");
b2 = new JButton("Motif");
b3 = new JButton("Windows");
cb = new JComboBox();
cb.addItem("Metal");
cb.addItem("Motif");
cb.addItem("Windows");

// Fuege die Komponenten dem Frame hinzu
c.add(b1);
c.add(b2);
c.add(b3);
c.add(cb);

// Erzeuge den Listener und registriere ihn
LafListener ll = new LafListener();
b1.addActionListener(ll);
b2.addActionListener(ll);
b3.addActionListener(ll);
// cb.addItemListener(ll);
}

// Innere Listener-Klasse
public class LafListener implements ActionListener {//ItemListener,
//
String[] laf =
{"javax.swing.plaf.metal.MetalLookAndFeel",
"com.sun.java.swing.plaf.motif.MotifLookAndFeel",
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"};

/* // Fuer das ItemListener-Interface
public void itemStateChanged(ItemEvent e) {
try {
int i = cb.getSelectedIndex();
UIManager.setLookAndFeel(laf[i]);
}
catch (Exception ex) {
System.err.println(ex);
}
SwingUtilities.updateComponentTreeUI(f);
}
*/
// Fuer das ActionListener-Interface
public void actionPerformed(ActionEvent e) {
try {
int i;
if (e.getSource() == b1)
i = 0;
else if (e.getSource() == b2)
i = 1;
else
i = 2;
UIManager.setLookAndFeel(laf[i]);
//cb.setSelectedIndex(i);
}
catch (Exception ex) {
System.err.println(ex);
}
SwingUtilities.updateComponentTreeUI(f);
}
}

public static void main(String[] args) {
LookAndFeel fenster = new LookAndFeel();
fenster.setTitle("Look and feel einstellen");
fenster.setSize(250,100);
fenster.setVisible(true);
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CL OSE);
}
}

lousypoetry
29-06-2006, 22:38
Ich hab in deinem Code ein wenig die Übersicht verloren, drum hab ich meinen weiterentwickelt


Kann ich gut verstehen. Ist halt auf die schnelle zusammengeklickt und alles Andere als gut lesbar.

Danke für deine Hilfe, ich habs jetzt so gemacht wie in deinem Code und es scheint zu funktionieren! :) Sonst meld ich mich nochmal (natürlich mit klarer Fehlermeldung und verständlichem Code ;) )

bischi
30-06-2006, 13:29
Danke für deine Hilfe, ich habs jetzt so gemacht wie in deinem Code und es scheint zu funktionieren! :) Sonst meld ich mich nochmal (natürlich mit klarer Fehlermeldung und verständlichem Code ;) )

Gut wenns funktioniert! (ich musste zuerst auch wieder ein wenig rumprobieren - hab schon zu lange nichts mehr mit Java gemacht...)

MfG Bischi