Swing Wieso braucht man nach setVisible mal ein revalidate und mal nicht?

G

Gast2

Gast
Hallo folgendes "Problem" hab ich in meiner GUI:

Nehmen wir an ich habe ein JPanel mit Border Layout.

Wird ein JPanel im EAST Bereich z.B. invisible gesetzt wird der CENTER Bereich automatisch vergrößert.

Habe ich jedoch ein z.B. JTextField im EAST Bereich und setze dieses invisible wird der CENTER Bereich nicht automatisch vergrößert sondern ich muss erst ein revalidate aufrufen.

Wieso ist das mal so und mal so?
 

Michael...

Top Contributor
Manipulationen am Layout zur Laufzeit macht man auch nicht:oops:
Und wenn doch dann sollte man immer revalidat() an der Container Komponente aufrufen.

Der Unterschied zwischen dem Verhalten zwischen JPanel und JTextField könnte darin liegen, dass JTextField getPreferredSize() überschreibt und JPanel die Implementierung von JComponent nutzt.
 

twseitex

Mitglied
Hi,

JComponent
hat revalidate
ist Eltern von JTextComponent --> JTextField
JPanel

JTextField hat
boolean isValidateRoot()
Calls to revalidate that come from within the textfield itself will be handled by validating the
textfield, unless the textfield is contained within a JViewport, in which case this returns false.

setFont public void setFont(Font f)
Sets the current font. This removes cached row height and column width so the new font will be reflected.
revalidate is called after setting the font.

Zur Laufzeit die GUI verändern geht nur sehr begrenzt.
In meinem Java-Audioplayer für Java SE und JApplet wird die GUI zur Laufzeit verändert.
Allerdings nur in den gültigen Varianten einer Klasse z.B. des Box-Layoutes.
(Player per audio, flash and java ansehbar).
 
G

Gast2

Gast
Ich verändere die GUI ja eigentlich nicht.

Was ich mache (und das ist ja üblich) ist einige Komponenten wie z.B. Symbolleisten zur Laufzeit ein und ausblenden zu können.

Dazu verwende ich JGoodies Binding lib um den Visible Status der einzelnen Komponenten mit dem Programm Modell synchron zu halten. Das funktioniert auch wunderbar.

Setze ich nun während der Laufzeit (z.B. per Menü) eine Symbolleiste auf visible(false) funktionierts auch wunderbar. Die Symbolleiste (JToolbar) wird unsichtbar UND die Gesamt Toolbar aktualisiert (ordnet die Child Toolbars) automatisch neu. Sprich irgendwo wird ein revalidate auf das Parent aufgerufen.

In einem anderen JPanel habe ich als CHild aber Beispielsweise ein Textfeld. Dieses kann auch ein und ausgeblendet werden. Es wird auch unsichtbar ABER das dazugehörige JPanel (Parent des Textfield, mit BOrderLayout) aktualisiert sich nicht.

Ich wüsste gerne (Sorry aber ist mir immer noch nicht klar) Wieso in diesem Fall kein Revalidate auf dem JPanel ausgelöst wird.

Wie löst man so ein aus und einblenden denn sonst in einer Applikation? Das ist ja wirklich nichts ungewöhnliches. Vielleicht ist mein Ansatz auch einfach nicht so glücklich gewählt.

Hier noch ein Beispielcode. Zwar ohne Binding aber das Problem ist ja das selbe:

Java:
public class Main {
    
    private JTextField textWest;
    private JTextField textEast;
    private JTextField textCenter;
    private JPanel textPanel;
    
    public Main() {        
        JCheckBoxMenuItem itemWest = new JCheckBoxMenuItem("Show left text");        
        itemWest.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                textWest.setVisible(!textWest.isVisible());                
            }
        });
        
        JCheckBoxMenuItem itemEast = new JCheckBoxMenuItem("Show right text");
        itemEast.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                textPanel.setVisible(!textPanel.isVisible());                
            }
        });

        JMenuBar menuBar = new JMenuBar();        
        menuBar.add(itemWest);
        menuBar.add(itemEast);
        
        textCenter = new JTextField("Center");
        textCenter.setHorizontalAlignment(SwingConstants.CENTER);
        
        textWest = new JTextField("Left");
        
        textEast = new JTextField("East");        
        textPanel = new JPanel();
        textPanel.add(textEast);        
        
        JFrame frame = new JFrame(); 
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(BorderLayout.WEST, textWest);
        panel.add(BorderLayout.CENTER, textCenter);
        panel.add(BorderLayout.EAST, textPanel);
        
         
        frame.setJMenuBar(menuBar);
        frame.add(panel);
        frame.setSize(new Dimension(240, 120));
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        new Main();
    }
}

Im Beispiel sieht man schön, wie die Center Component die Größe ändert, wenn das East Panel visible(false) gesetzt wird.

Macht man das mit dem JTextField im West Bereich wird es zwar ausgeblendet, jedoch ändert das Layout nicht die Größe der Center Component. Irgendwie verstehe ich das nicht.

Nach meinem Verständnis erben doch JTextField und JPanel von den gleichen Elternklassen die fragliche Methode setVisible.
 
Zuletzt bearbeitet von einem Moderator:

truesoul

Top Contributor
Hi.

Bei einen Aufruf von frame.pack() sollte das Problem nicht mehr auftauchen. Voraussetzung ist das man setPreferredSize verwendet.
Siehe Beispiel:
Java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;

public class Main {

    private JTextField textWest;
    private JTextField textEast;
    private JTextField textCenter;
    private JPanel textPanel;
    private JFrame frame;

    public void updateGUI(){  
        frame.pack();
    }

    public Main() {
        frame = new JFrame();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JCheckBoxMenuItem itemWest = new JCheckBoxMenuItem("Show left text");
        itemWest.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                textWest.setVisible(!textWest.isVisible());
                updateGUI();
            }
        });

        JCheckBoxMenuItem itemEast = new JCheckBoxMenuItem("Show right text");
        itemEast.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                textPanel.setVisible(!textPanel.isVisible());
            }
        });

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(itemWest);
        menuBar.add(itemEast);

        textCenter = new JTextField("Center");
        textCenter.setHorizontalAlignment(SwingConstants.CENTER);

        textWest = new JTextField("Left");
        
        textEast = new JTextField("East");
        textPanel = new JPanel();
        textPanel.add(textEast);

        
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(BorderLayout.WEST, textWest);
        panel.add(BorderLayout.CENTER, textCenter);
        panel.add(BorderLayout.EAST, textPanel);


        frame.setJMenuBar(menuBar);
        frame.add(panel);
        frame.setSize(new Dimension(240, 120));
        frame.setPreferredSize(new Dimension(240, 120));
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Main();
    }
}

Klingt komisch, ist aber so! (Zitat: Die Sendung mit der Maus)
 
G

Gast2

Gast
Hi.

Bei einen Aufruf von frame.pack() sollte das Problem nicht mehr auftauchen. Voraussetzung ist das man setPreferredSize verwendet.

Das ist klar. Ich wüsste aber gerne wieso das unterschiedlich gehandhabt wird.

Das eine mal brauche ein revalidate (ausgelöst durch pack()) und das andere mal eben nicht. Die Frage war ja nicht wie bekomme ich das ans laufen sondern wieso ist es mal so und mal so.

Mein Problem ist zudem, dass ich das visible per binding setze. Ein manuelles revalidate ist da also nicht möglich.
 

Michael...

Top Contributor
Wie twseitex schon darauf hingewiesen hat überschreibt JTextField die
Code:
public boolean isValidateRoot()
von JComponent und liefert true falls sie nicht in einem JViewport verbaut ist.
Wenn man bei Deiner Demo das BorderLayout beobachtet, stellt man fest, dass bei setVisible() am JTextField keine Neuberechnung des Layouts stattfindet. Man kann zum Spaß die isValidateRoot des Textfeldes überschreibt, dann wird auch das Layout neu berechnet.

Allerdings ist eine Layoutänderung über die direkte Steuerung der Sichtbarkeit von Komponenten in Java nicht üblich. Sowas würde man wohl eher mittels JSplitPane bzw. beim Austauch von Komponenten mit CardLayout machen. Welches das zwar selbst über die Sichtbarkeit löst aber immer ein validate() am Container aufruft. Und das wäre auch die Empfehlung für jeden Anwender der direkt ins Layout eingreift.
 
G

Gast2

Gast
Wie twseitex schon darauf hingewiesen hat überschreibt JTextField die
Code:
public boolean isValidateRoot()
von JComponent und liefert true falls sie nicht in einem JViewport verbaut ist.
Wenn man bei Deiner Demo das BorderLayout beobachtet, stellt man fest, dass bei setVisible() am JTextField keine Neuberechnung des Layouts stattfindet. Man kann zum Spaß die isValidateRoot des Textfeldes überschreibt, dann wird auch das Layout neu berechnet.

Allerdings ist eine Layoutänderung über die direkte Steuerung der Sichtbarkeit von Komponenten in Java nicht üblich. Sowas würde man wohl eher mittels JSplitPane bzw. beim Austauch von Komponenten mit CardLayout machen. Welches das zwar selbst über die Sichtbarkeit löst aber immer ein validate() am Container aufruft. Und das wäre auch die Empfehlung für jeden Anwender der direkt ins Layout eingreift.

Ah OK jetzt hab ichs glaub ich auch verstanden. :) Durch das Überschreiben der Methode isValidateRoot() wird das validate der Parent Component (in meinem Fall das JPanel) unterdrückt.

Die beiden anderen Vorschläge schau ich mir mal an. Hast du dazu vielleicht noch ein paar links?

EDIT: Ich finde irgendwie macht es doch keinen Sinn eine Splitpane zum aus oder einblenden eines Widgets zu verwenden. Zumal das was ich ein und ausblenden möchte immer eine feste Breite hat.
Könnte wirklich ein Beispiel gebrauchen, wie man Komponenten ein und ausblendet.
Wie "schalte" ich den z.B. Sichtbarkeit von Toolbars dann sinnvollerweise richtig um?
 
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Wieso verändert sich die Framerate nach erneutem Starten des AnimationTimer? AWT, Swing, JavaFX & SWT 18
CptK Wieso wird nur ein Teil meiner Buttons angezeigt? AWT, Swing, JavaFX & SWT 1
J JavaFX CSS einbinden - Wieso will das einfach nicht!!! AWT, Swing, JavaFX & SWT 1
LexeB4F setValueAT geht nicht... wieso? AWT, Swing, JavaFX & SWT 14
Z JComponent's requestFocus() - Wieso nicht immer anwendbar? AWT, Swing, JavaFX & SWT 1
C Wieso nur erster Buchstabe bei Caesar-Entschlüsselung? AWT, Swing, JavaFX & SWT 2
A Swing JTable wird nicht über zurückegebene Referenz geaddet.Wieso nicht? AWT, Swing, JavaFX & SWT 5
K LayoutManager Wieso verschwinden Elemente? AWT, Swing, JavaFX & SWT 20
K Applet Wieso kann ich keine Array im Applet initialisieren AWT, Swing, JavaFX & SWT 13
propra Wieso wird paintComponent() beim Start 2 malausgeführt? AWT, Swing, JavaFX & SWT 4
P 2D-Grafik Wieso wird das Bild nicht angezeigt ? AWT, Swing, JavaFX & SWT 4
T wieso leere Oberfläche? AWT, Swing, JavaFX & SWT 5
C Wieso funktionert der CellRenderer nicht? AWT, Swing, JavaFX & SWT 2
L Wieso werden die Icons nicht dargestellt? AWT, Swing, JavaFX & SWT 2
W Wieso SerialVersionUID bei Swing-Komponenten AWT, Swing, JavaFX & SWT 5
N Freiraum in der GUI - Wieso? AWT, Swing, JavaFX & SWT 6
S Wieso Fenster im EDT sichtbar machen? AWT, Swing, JavaFX & SWT 43
M Wieso geht das nicht! AWT, Swing, JavaFX & SWT 3
S animation Flackern trotz doppelpufferung wieso? AWT, Swing, JavaFX & SWT 2
G Wieso wird meine Scrollbar nicht angezeigt? AWT, Swing, JavaFX & SWT 3
K JTable - wieso funktioniert der Autoscroll nicht? AWT, Swing, JavaFX & SWT 5
Paule JFrame bleibt leer, wieso? AWT, Swing, JavaFX & SWT 2
S Wieso werden die Bilder nicht angezeigt? AWT, Swing, JavaFX & SWT 4
G Progressbar aktualisiert sich nicht (vernünftig). WIESO? AWT, Swing, JavaFX & SWT 2
N Braucht man fxml AWT, Swing, JavaFX & SWT 3
K Swing DefaultListModel braucht zu lange, um Wert zu setzen AWT, Swing, JavaFX & SWT 7
Furtano AWT paint braucht ein Graphics Objekt ? AWT, Swing, JavaFX & SWT 2
J Schulprojekt und braucht hilfe AWT, Swing, JavaFX & SWT 54
L JFileChooser braucht lang zum öffnen AWT, Swing, JavaFX & SWT 2
R JTable Darstellen der selektierten Zelle braucht lange AWT, Swing, JavaFX & SWT 7
K noob braucht unterstützung AWT, Swing, JavaFX & SWT 2
D Grafikeinsteiger sucht/braucht Hilfe. Wäre Nett ! AWT, Swing, JavaFX & SWT 3
P Warum braucht mein kleines Programm 20 MB Speicher? AWT, Swing, JavaFX & SWT 13
berserkerdq2 Buttons und Shapes sehen ja nach Screengröße klein oder zu groß aus, jemand eine Idee, was man tun kann? AWT, Swing, JavaFX & SWT 1
W JEditorPane textausrichtung nach settext funktioniert nicht mehr AWT, Swing, JavaFX & SWT 11
H Swing Buttons erst nach Klick sichtbar AWT, Swing, JavaFX & SWT 13
H JavaFX Fenstergröße nach maximieren erkennen AWT, Swing, JavaFX & SWT 6
D Swing Komponenten nicht sichtbar nach Start AWT, Swing, JavaFX & SWT 12
T Elemente auf vorheriger Stage, nach Wechsel der Stage ansprechen AWT, Swing, JavaFX & SWT 32
berserkerdq2 Mein Rechteck hat 4 Seiten, ich soll je nach dem, welche Seite berührt wurde, etwas ausführen, wie prüfe ich das? AWT, Swing, JavaFX & SWT 12
Ernesto95 JavaFX Return Value nach Beendigung einer Animation AWT, Swing, JavaFX & SWT 15
K Textarea aktuallisiert sich nicht, nach Auswahl (Itemlistener) AWT, Swing, JavaFX & SWT 3
M Nach Export als Runnable Jar wird css nicht merh gefunden AWT, Swing, JavaFX & SWT 22
P kein Scrollen nach affinertransformation bei mouse dragged AWT, Swing, JavaFX & SWT 2
T ListView nach Erweiterung Fehler in CellFactory AWT, Swing, JavaFX & SWT 8
N JavaFX Tableview nach Löschen von Element falscher Index AWT, Swing, JavaFX & SWT 4
B JavaFX TextInputDialog: Focus auf Eingabefeldinhalt setzen und nach OK Inhalt leeren AWT, Swing, JavaFX & SWT 5
VPChief Nach abspielen von Sound reagiert das Program nichtmehr AWT, Swing, JavaFX & SWT 9
VPChief Swing Eclipse: Nach Exportieren, Button funktioniert nicht mehr AWT, Swing, JavaFX & SWT 26
E Swing Componenten werden nach Änderung des display modes verzerrt dargestellt AWT, Swing, JavaFX & SWT 8
L JavaFX Exception nach includieren einer fxml // nested controller AWT, Swing, JavaFX & SWT 1
Zrebna Problem bei Eventhandling (Value soll nach jedem erneutem Klick gelöscht werden) AWT, Swing, JavaFX & SWT 4
R Swing JTextField - Schriftgröße je nach Länge und Größe ändern AWT, Swing, JavaFX & SWT 0
F AWT awt KeyEvent - Zeichen direkt nach Eingabe löschen AWT, Swing, JavaFX & SWT 2
L Komponenten eines Panels werden erst nach Klick darauf angezeigt AWT, Swing, JavaFX & SWT 13
K JavaFX Element in HBOX nach rechts verschieben AWT, Swing, JavaFX & SWT 2
S JavaFX Slider freezt nach Benutzung AWT, Swing, JavaFX & SWT 3
M Swing GUI wird nach invokeLater() langsam AWT, Swing, JavaFX & SWT 19
Fiedlerdan Image-Pfad Probleme nach Export aus Eclipse AWT, Swing, JavaFX & SWT 31
T JavaFX Nach Zoomen wird an falscher Stelle gezeichnet AWT, Swing, JavaFX & SWT 0
S Ausgabe aktualisiert sich nur nach 2. Klick AWT, Swing, JavaFX & SWT 17
F JavaFX Zustand der CheckMenuItems behalten nach Programmneustart AWT, Swing, JavaFX & SWT 7
J jButton soll nach klicken eine Variable um 1 erhöhen AWT, Swing, JavaFX & SWT 2
S Nach scrollen verschwindet das zuvor im JPanel gezeichnete AWT, Swing, JavaFX & SWT 2
stroggi Swing Suche nach Kurveneditor (UI-Element) AWT, Swing, JavaFX & SWT 1
Neumi5694 java.awt.Window nach javafx.stage.Window AWT, Swing, JavaFX & SWT 1
L Swing Komponenten erst nach Resize sichtbar AWT, Swing, JavaFX & SWT 2
F Swing Frame nach vorne holen AWT, Swing, JavaFX & SWT 2
T Swing Änderung des ActionListener Events nach Klick auf JButton AWT, Swing, JavaFX & SWT 2
S Swing JButton verschwindet nach Compilieren AWT, Swing, JavaFX & SWT 8
D JTable nach INSERT aktualisieren /refreshen AWT, Swing, JavaFX & SWT 1
robinab JavaFX TableView column resize nach setItems() AWT, Swing, JavaFX & SWT 0
MiMa Java, Maven Projekte nach JavaFX? AWT, Swing, JavaFX & SWT 3
S JavaFX Node soll auch nach Skalierung zentriert platziert sein AWT, Swing, JavaFX & SWT 3
J Suche nach einer horizontal aufklappbaren Toolbar AWT, Swing, JavaFX & SWT 1
Bluedaishi JTextArea gefundene Zeile nach Oben Scrollen AWT, Swing, JavaFX & SWT 13
MiMa Java Projekt nach JavaFX convertieren AWT, Swing, JavaFX & SWT 4
it_is_all JPanel verschwindet nach Button-Klick AWT, Swing, JavaFX & SWT 2
N Swing JButtons werden nach repaint() doppelt dargestellt AWT, Swing, JavaFX & SWT 12
U JavaFX Wechsel der Scene nach betätigen eines Button AWT, Swing, JavaFX & SWT 2
L JTextField erscheint erst nach Veränderung der Framegröße AWT, Swing, JavaFX & SWT 5
C Nach Aufruf von anderer Klasse streikt Grafik AWT, Swing, JavaFX & SWT 1
F AWT Robot Klasse Screenshot nach Pixelmustern in bestimmten Radius um Bildschirmmittelpunkt absuchen AWT, Swing, JavaFX & SWT 13
H Musik wird nach dem erstellen der .jar Datei nicht mehr abgespielt AWT, Swing, JavaFX & SWT 1
D iText PDF wird nach Neustart nicht importiert AWT, Swing, JavaFX & SWT 0
J Java FX Koordinaten NACH Animation setzen, wie? AWT, Swing, JavaFX & SWT 9
A Nach klick auf Button neuen Inhalt im gleichen Fenster AWT, Swing, JavaFX & SWT 3
Pr0m3theus Animation nach Event AWT, Swing, JavaFX & SWT 6
N Swing Abfrage durch JTextField nach Button betätigung AWT, Swing, JavaFX & SWT 3
S JTextArea Text nach oben wandern lassen AWT, Swing, JavaFX & SWT 7
Thallius JScrollPane Scrollpos setzen nach Neuzeichnen AWT, Swing, JavaFX & SWT 3
C JavaFX mehrere Kreise nach Eingabeprozess ausgeben AWT, Swing, JavaFX & SWT 2
J 2D-Grafik Linie wird nach Mausklick nicht am richtigen Ort gezeichnet AWT, Swing, JavaFX & SWT 11
C Memory Karten nach Paar offen bleiben sonst wieder umdrehen AWT, Swing, JavaFX & SWT 1
C Benutzername in GUI eingeben und nach Spiel neues Fenster Benutzername wieder anzeigen AWT, Swing, JavaFX & SWT 1
W Swing JPanel nur einmal nach mehreren Änderungen neu zeichnen AWT, Swing, JavaFX & SWT 1
L JavaFX Java FX Anwendung nach MVC mit Observer Pattern AWT, Swing, JavaFX & SWT 15
M JavaFX Methode nach initialize() aufrufen AWT, Swing, JavaFX & SWT 6
MrSnake Tabelle nach 2 Strings Filtern AWT, Swing, JavaFX & SWT 3
N Swing JFormattedTextField keine Werte nach Formatzuweisung AWT, Swing, JavaFX & SWT 0

Ähnliche Java Themen

Neue Themen


Oben