Announcement

Collapse
No announcement yet.

GroupLayout - Elemente aus/einblenden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • GroupLayout - Elemente aus/einblenden

    Hallo,

    ich habe Probleme mit dem Ein- und Ausblenden von Elementen bei einem GroupLayout.

    So soll die Darstellung sein:
    Eine Liste mit 2 Spalten und mehreren Zeilen.
    In der ersten Spalte kommen die Jlabels und in die zweite Spalte die dazugehörigen JComboBoxen.
    Wichtig ist die erste Zeile. Die darin enthaltene JComboBox hat zwei Einträge.
    Wenn der erste Eintrag angezeigt wird, ist die komplette Liste sichtbar.
    Wenn der zweite Eintrag angezeigt wird, ist nur noch die erste Zeile sichtbar. Die anderen Zeilen werden ausgeblendet.
    Dies wird durch die Methode "Verstecken()" gemacht, welche die Elemente der restlichen Zeilen auf "setVisible(false)" setzt.

    Die Methode "setAutoCreateGaps()" ist auf "true" gestellt. (Ich finde die automatischen Abstände sehen gut aus.)

    Hier der Quellcode zum Versuchsprogramm01:

    Die MainProg-Klasse:
    Code:
    public class MainProg
    {
    	public static void main(String[] args)
    	{
    		GUI x = new GUI();
    	}
    }
    und die GUI-Klasse:
    Code:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.BoxLayout;
    import javax.swing.GroupLayout;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.GroupLayout.Alignment;
    
    public class GUI implements ActionListener
    {	
    	JFrame frmFenster;
    	JPanel pnlDarstellung;
    	JLabel lb1, lb2, lb3, lb4;
    	JComboBox cb1, cb2, cb3, cb4;
    	GroupLayout layout;
    	
    	public GUI()
    	{
    		frmFenster = new JFrame();
    		frmFenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frmFenster.setLayout(new BoxLayout(frmFenster.getContentPane(), BoxLayout.Y_AXIS));
    		
    		pnlDarstellung = new JPanel();
    		
    		layout = new GroupLayout(pnlDarstellung);
    		
    		pnlDarstellung.setLayout(layout);
    		
    		lb1 = new JLabel("Text 1");
    		lb2 = new JLabel("Text 2");
    		lb3 = new JLabel("Text 3 Text3");
    		lb4 = new JLabel("Text 4");
    		
    		cb1 = new JComboBox();
    		cb1.addItem("Anzeige 1");
    		cb1.addItem("Anzeige 2");
    		cb1.addActionListener(this);
    		
    		cb2 = new JComboBox();
    		cb2.addItem("TEST");
    		cb3 = new JComboBox();
    		cb3.addItem("TEST");
    		cb4 = new JComboBox();
    		cb4.addItem("TEST");
    				
    		layout.setHorizontalGroup(layout.createParallelGroup()
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb1)
    							.addComponent(cb1))
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb2)
    							.addComponent(cb2))
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb3)
    							.addComponent(cb3))
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb4)
    							.addComponent(cb4)));
    					
    		layout.setVerticalGroup(layout.createSequentialGroup()
    					.addGap(3)
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb1)
    							.addComponent(cb1))
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb2)
    							.addComponent(cb2))
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb3)
    							.addComponent(cb3))
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb4)
    							.addComponent(cb4))
    					.addGap(3));
    		
    		layout.linkSize(lb1, lb2, lb3, lb4);
    		
    		layout.setAutoCreateGaps(true);
    		
    		frmFenster.add(pnlDarstellung);
    		
    		frmFenster.pack();
    		frmFenster.setVisible(true);
    	}
    	
    	public void Verstecken()
    	{
    		if(cb1.getSelectedItem() == "Anzeige 2")
    		{
    			lb2.setVisible(false);
    			cb2.setVisible(false);
    			lb3.setVisible(false);
    			cb3.setVisible(false);
    			lb4.setVisible(false);
    			cb4.setVisible(false);
    		}
    		else
    		{
    			lb2.setVisible(true);
    			cb2.setVisible(true);
    			lb3.setVisible(true);
    			cb3.setVisible(true);
    			lb4.setVisible(true);
    			cb4.setVisible(true);
    		}
    	}
    	
    	public void Fensterneumalen()
    	{
    		frmFenster.pack();
    		frmFenster.repaint();
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e)
    	{
    		if(e.getSource() == cb1)
    		{
    			Verstecken();
    			Fensterneumalen();
    		}
    	}
    }
    Das Problem ist jetzt, daß wenn die Elemente ausgeblendet werden, die "Gaps" weiter bestehen bleiben und einen unschönen Abstand nach der ersten Zeile bilden.

    Ist das ein Fehler der Klasse GroupLayout oder habe ich irgendetwas nicht berücksichtigt?

    Wie würdet Ihr das Problem lösen?


    Ich war natürlich nicht faul und habe ein paar Sachen ausprobiert.
    Eine Idee war für beide Darstellungen jeweils ein eigenes GroupLayout zu erstellen.
    Diesmal wird über die Methode "Verstecken()" das Layout ausgewechselt.

    Hier der Quellcode zum Versuchsprogramm02:

    Für die MainProg-Klasse:
    Code:
    public class MainProg
    {
    	public static void main(String[] args)
    	{
    		GUI x = new GUI();
    	}
    }
    und die GUI-Klasse:
    Code:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.BoxLayout;
    import javax.swing.GroupLayout;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.GroupLayout.Alignment;
    
    public class GUI implements ActionListener
    {
    	JFrame frmFenster;
    	
    	JPanel pnlDarstellung;
    	JLabel lb1, lb2, lb3, lb4;
    	JComboBox cb1, cb2, cb3, cb4;
    	
    	GroupLayout layout;
    	GroupLayout.Group hgGross, hgKlein, vgGross, vgKlein;
    	
    	public GUI()
    	{
    		frmFenster = new JFrame();
    		frmFenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		
    		frmFenster.setLayout(new BoxLayout(frmFenster.getContentPane(), BoxLayout.Y_AXIS));
    		
    		pnlDarstellung = new JPanel();
    		
    		layout = new GroupLayout(pnlDarstellung);
    		
    		pnlDarstellung.setLayout(layout);
    		
    		lb1 = new JLabel("Text 1");
    		lb2 = new JLabel("Text 2");
    		lb3 = new JLabel("Text 3 Text3");
    		lb4 = new JLabel("Text 4");
    		
    		cb1 = new JComboBox();
    		cb1.addItem("Anzeige 1");
    		cb1.addItem("Anzeige 2");
    		cb1.addActionListener(this);
    		
    		cb2 = new JComboBox();
    		cb2.addItem("TEST");
    		cb3 = new JComboBox();
    		cb3.addItem("TEST");
    		cb4 = new JComboBox();
    		cb4.addItem("TEST");
    				
    		hgGross = layout.createParallelGroup()
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb1)
    							.addComponent(cb1))
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb2)
    							.addComponent(cb2))
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb3)
    							.addComponent(cb3))
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb4)
    							.addComponent(cb4));
    		
    		hgKlein = layout.createParallelGroup()
    					.addGroup(layout.createSequentialGroup()
    							.addComponent(lb1)
    							.addComponent(cb1));
    				
    		vgGross = layout.createSequentialGroup()
    					.addGap(20)
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb1)
    							.addComponent(cb1))
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb2)
    							.addComponent(cb2))
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb3)
    							.addComponent(cb3))
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb4)
    							.addComponent(cb4))
    					.addGap(20);
    					
    		vgKlein = layout.createSequentialGroup()
    					.addGap(20)
    					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
    							.addComponent(lb1)
    							.addComponent(cb1))
    					.addGap(20);
    				
    		layout.setHorizontalGroup(hgGross);
    		layout.setVerticalGroup(vgGross);
    		
    		layout.linkSize(lb1, lb2, lb3, lb4);
    		
    		layout.setAutoCreateGaps(true);
    		
    		frmFenster.add(pnlDarstellung);
    		
    		frmFenster.pack();
    		frmFenster.setVisible(true);
    		
    	}
    	
    	public void Verstecken()
    	{
    		if(cb1.getSelectedItem() == "Anzeige 2")
    		{
    			layout.setHorizontalGroup(hgKlein);
    			layout.setVerticalGroup(vgKlein);
    		}
    		else
    		{
    			layout.setHorizontalGroup(hgGross);
    			layout.setVerticalGroup(vgGross);
    		}
    	}
    	
    	public void Fensterneumalen()
    	{
    		frmFenster.pack();
    		frmFenster.repaint();
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e)
    	{
    		if(e.getSource() == cb1)
    		{
    			Verstecken();
    			Fensterneumalen();
    		}
    	}
    }
    Aber das funktioniert auch nicht richtig.

    Wo ist hier mein Denkfehler? Was mache ich falsch?

    Ich könnte natürlich einfach auf einen anderen Layout-Manager ausweichen, aber mir geht es darum zu verstehen "warum" es nicht funktioniert.

    Ich bedanke mich schon im Voraus für eure Hilfe.

  • #2
    Ich könnte natürlich einfach auf einen anderen Layout-Manager ausweichen, aber mir geht es darum zu verstehen "warum" es nicht funktioniert.
    Würde mal darauf tippen, dass es daran liegt, dass die Elemente ausgeblendet werden. Damit bleibt ja das Layout und die Gaps bestehen.

    Wie würdet Ihr das Problem lösen?
    Mit Panels, die jeweils ein eigenes Layout haben und ein-/ ausgeblendet werden
    Christian

    Comment


    • #3
      Würde mal darauf tippen, dass es daran liegt, dass die Elemente ausgeblendet werden. Damit bleibt ja das Layout und die Gaps bestehen.
      Ja, das Layout soll ja bestehen bleiben (jedenfalls bei meinem Versuchsprogramm01), die Gaps sollten es aber nicht.

      Siehe http://java.sun.com/docs/books/tutor...out/group.html ganz unten bei "Runtime Changes to Your GUI".
      GroupLayout offers two ways to configure how invisible components are treated. The setHonorsVisibility(boolean) method globally sets how invisible components are handled. A value of true, the default, indicates invisible components are treated as if they are not there. On the other hand, a value of false provides space for invisible components, treating them as though they were visible.
      Laut API:

      A value of true indicates that non-visible components should not be treated as part of the layout.
      und
      The default is true.
      Ich habe schon ein ähnliches Layout gemacht, das wie folgt aussah:

      LABELCB.....COMBOBOX
      ............TEXTFIELD
      ............LABEL
      LABELCB.....COMBOBOX
      ............TEXTFIELD
      ............LABEL
      LABELCB.....COMBOBOX
      ............TEXTFIELD
      ............LABEL

      Wenn ich dort die TEXTFIELDs und LABELs ausgeblendet habe (mit setVisible(false)) sah es danach so aus:

      LABELCB.....COMBOBOX
      LABELCB.....COMBOBOX
      LABELCB.....COMBOBOX

      Die Methode "setAutoCreateGaps()" war auch hier auf "true" gestellt.
      ABER: Die Anordnung war perfekt, es wurden nur die Gaps verwendet, die auch wirklich gebraucht wurden. Auch das Wiedereinblenden war kein Problem.

      Warum verteilt GroupLayout bei einem Layout die Gaps alle richtig, aber bei einem anderen alle falsch?
      Auch ist mir nicht klar, warum die Darstellung in mein Versuchsprogramm02 nicht richtig funktioniert.

      Comment


      • #4
        Und hallo!

        Es gibt an der Klasse GroupLayout folgende Methode:

        Code:
        public void setHonorsVisibility(boolean honorsVisibility)
        Damit kann man das GroupLayout entsprechend steuern. Mit true wird das GroupLayout unsichtbare Komponenten aus dem Layout rausrechnen und so tun als ob sie gar nicht vorhanden wären. Mit false werden auch unsichtbare Komponenten mit berücksichtigt!
        Beide Varianten sind, je nach Anwendungsfall, durchaus sinnvoll.

        ...

        Habe ich schon erwähnt, dass ich der Fan des GroupLayouts bin...
        Meiner Ansicht nach der beste LayoutManager überhaupt. Habe bisher noch kein Szenario gehabt, das man mit diesem LayoutManager nicht lösen konnte.

        Schöne Grüße,
        Mathias

        Comment


        • #5
          Hallo Mathias,

          selbst wenn ich
          Code:
          layout.setHonorsVisibility(true);
          in mein Versuchprogramm01 einfüge, bleiben die unnötigen Gaps am Ende.

          Gruß
          hansmueller

          Comment


          • #6
            Es geht wohl.... aber ziemlich umständlich... :-/

            Ok... sorry... du hattest das mit dem setHonorsVisibility ja schon erwähnt.
            Wie unaufmerksam von mir.

            Interessanterweise wird das vom GroupLayout wohl nur korrekt ausgewertet, wenn vertikal die Components direkt aufeinander folgen würden. Dadurch, dass sie in parallelen Gruppen sind, bekommt das GroupLayout das nicht korrekt mit und packt zwischen die parallelen Gruppen trotzdem noch die PreferredGaps. Somit hast du dann am Ende deines Containers effektiv die Höhe von 3 PreferredGaps...

            Ungeschickt...

            Eine Lösung wäre hier die automatischen Gaps vom GroupLayout auszuschalten und eigene Gaps (z.B. RigidArea) einzubauen... aber ist natürlich ziemlich umständlich.

            Hier eine mögliche Lösung:
            Code:
            import java.awt.Component;
            import java.awt.Dimension;
            import java.awt.event.ActionEvent;
            import java.awt.event.ActionListener;
            
            import javax.swing.Box;
            import javax.swing.GroupLayout;
            import javax.swing.JComboBox;
            import javax.swing.JComponent;
            import javax.swing.JFrame;
            import javax.swing.JLabel;
            import javax.swing.JPanel;
            import javax.swing.LayoutStyle;
            import javax.swing.SwingConstants;
            import javax.swing.GroupLayout.Alignment;
            import javax.swing.LayoutStyle.ComponentPlacement;
            
            public class GUI implements ActionListener {
                JFrame frmFenster;
                JPanel pnlDarstellung;
                JLabel lb1, lb2, lb3, lb4;
                JComboBox cb1, cb2, cb3, cb4;
                GroupLayout layout;
                private final Component strut1;
                private final Component strut2;
                private final Component strut3;
                private final Component strut0;
            
                public GUI() {
                    frmFenster = new JFrame();
                    frmFenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
                    pnlDarstellung = new JPanel();
            
                    layout = new GroupLayout(pnlDarstellung);
                    layout.setAutoCreateContainerGaps(true);
                    layout.setAutoCreateGaps(false);
            
                    pnlDarstellung.setLayout(layout);
            
                    lb1 = new JLabel("Text 1");
                    lb2 = new JLabel("Text 2");
                    lb3 = new JLabel("Text 3 Text3");
                    lb4 = new JLabel("Text 4");
            
                    cb1 = new JComboBox();
                    cb1.addItem("Anzeige 1");
                    cb1.addItem("Anzeige 2");
                    cb1.setSelectedIndex(1);
                    cb1.addActionListener(this);
            
                    cb2 = new JComboBox();
                    cb2.addItem("TEST");
                    cb3 = new JComboBox();
                    cb3.addItem("TEST");
                    cb4 = new JComboBox();
                    cb4.addItem("TEST");
            
                    LayoutStyle style = LayoutStyle.getInstance();
                    int horzGap = style.getPreferredGap(cb1, cb2, ComponentPlacement.RELATED, SwingConstants.EAST, pnlDarstellung);
                    int vertGap = style.getPreferredGap(cb1, cb2, ComponentPlacement.RELATED, SwingConstants.SOUTH, pnlDarstellung);
                    strut0 = Box.createRigidArea(new Dimension(horzGap, vertGap));
                    strut1 = Box.createRigidArea(new Dimension(horzGap, vertGap));
                    strut2 = Box.createRigidArea(new Dimension(horzGap, vertGap));
                    strut3 = Box.createRigidArea(new Dimension(horzGap, vertGap));
            
                    layout.setHorizontalGroup(layout.createSequentialGroup()
                            .addGroup(layout.createParallelGroup()
                                    .addComponent(lb1)
                                    .addComponent(lb2)
                                    .addComponent(lb3)
                                    .addComponent(lb4))
                            .addGroup(layout.createParallelGroup()
                                    .addComponent(strut0)
                                    .addComponent(strut1)
                                    .addComponent(strut2)
                                    .addComponent(strut3))
                            .addGroup(layout.createParallelGroup()
                                    .addComponent(cb1)
                                    .addComponent(cb2)
                                    .addComponent(cb3)
                                    .addComponent(cb4))
                            );
            
                    layout.setVerticalGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(Alignment.BASELINE)
                                        .addComponent(lb1)
                                        .addComponent(strut0)
                                        .addComponent(cb1))
                                .addComponent(strut1)
                                .addGroup(layout.createParallelGroup(Alignment.BASELINE)
                                        .addComponent(lb2)
                                        .addComponent(cb2))
                                .addComponent(strut2)
                                .addGroup(layout.createParallelGroup(Alignment.BASELINE)
                                        .addComponent(lb3)
                                        .addComponent(cb3))
                                .addComponent(strut3)
                                .addGroup(layout.createParallelGroup(Alignment.BASELINE)
                                        .addComponent(lb4)
                                        .addComponent(cb4))
                                );
            
                    frmFenster.setContentPane(pnlDarstellung);
                    updateVisibility();
                    frmFenster.pack();
                    frmFenster.setVisible(true);
                }
            
                public void updateVisibility() {
                    boolean visible = cb1.getSelectedItem().equals("Anzeige 1");
                    lb2.setVisible(visible);
                    cb2.setVisible(visible);
                    lb3.setVisible(visible);
                    cb3.setVisible(visible);
                    lb4.setVisible(visible);
                    cb4.setVisible(visible);
                    strut1.setVisible(visible);
                    strut2.setVisible(visible);
                    strut3.setVisible(visible);
                }
            
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (e.getSource() == cb1) {
                        updateVisibility();
                        ((JComponent) frmFenster.getContentPane()).revalidate();
                        frmFenster.pack();
                    }
                }
            }

            Comment


            • #7
              Danke für die Lösung

              Hallo Mathias,

              vielen Dank für deine Lösung. Das hilft mir echt weiter.


              MfG
              hansmueller

              Comment

              Working...
              X