# Layout Schwierigkeiten



## Wildcard (9. Nov 2006)

Schon länger her das ich Swing Layout Manager verwendet habe, währe also dankbar wenn mir von euch jemand helfen könnte das hinzubekommen. (André zB gibt doch so gerne Codebeispiele  :wink: )
Mein Layout soll in etwa so aussehen:

```
+Panel1
---------------------------------
|key			    	      value |
|                               |
|key                      value |
|                         value |
|                               |
|key                      value |
|                         value |
---------------------------------

+Panel2
---------------------------------
|key			    	      value |
|                               |
|key                      value |
|                         value |
|                               |
|key                      value |
|                         value |
---------------------------------

-Panel3 (eingeklappt)
---------------------------------
---------------------------------

+Panel4
---------------------------------
|key		                value |
|                               |
|key                      value |
|                         value |
|                               |
|key                      value |
|                         value |
---------------------------------
```

Ein key soll also beliebige viele Values haben können die oben am Key ausgerichtet sind.
Weiterhin sollen die Panels beliebig groß und einklappbar sein.
Für die Panels anzuordnen bräuchte ich ein vertikales FlowLayout das es leider nicht gibt.
Ich hab es mit BoyLayout versucht, jedoch versucht BoxLayout immer den ganzen Platz zu verwenden anstatt 
den unteren Bereich freizulassen...

Wenn also jemand eine idee für das Panel-Layout oder das Key-Value Layout hat:
immer her damit :wink:

Thx, für Vorschläge

PS: optimal währe es übrigens wenn man das je nach Platzbedarf auf zwei Spalten aufteilen könnte, aber das wird vermutlich etwas schwierig  ???:L


----------



## kaie (10. Nov 2006)

Hier eine "Quickhack"-Lösung. Sieht noch nicht wahnsinnig toll aus, erfüllt aber ihren Zweck. Die Optik zu verbessern ist dann Deine Aufgabe!   


```
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.*;

public class FoldablePanel extends JPanel implements ActionListener
{
    // -------------------------------------------------------------------------
    //
    // Attribute
    //
    // -------------------------------------------------------------------------
    private JLabel        text;
    private JToggleButton toggle = new JToggleButton("\u25bc");
    private Component     buffer;

    // -------------------------------------------------------------------------
    //
    // Konstruktor
    //
    // -------------------------------------------------------------------------
    public FoldablePanel(String text, boolean folded)
    {
        this.text = new JLabel(text);
        setLayout(new BorderLayout());
        JPanel p = new JPanel(new BorderLayout());
        p.add(this.text, "Center");
        p.add(toggle, "East");
        add(p, "North");
        toggle.setMargin(new Insets(0, 0, 0, 0));
        toggle.setFont(new Font("Arial", Font.PLAIN, 10));
        toggle.addActionListener(this);
        setBorder(new EtchedBorder());
    }

    public FoldablePanel(String titel, String[] key,
            String[] value)
    {
        this(titel,true);
        JPanel k = new JPanel(new GridLayout(0, 1));
        JPanel v = new JPanel(new GridLayout(0, 1));
        for (int i = 0; i < key.length; i++)
        {
            k.add(new JLabel(key[i]));
            JLabel l = new JLabel(value[i]);
            l.setBorder(new LineBorder(Color.black));
            l.setBackground( new Color(255,255,200) );
            l.setOpaque(true);
            v.add(l);
        }
        JPanel p2 = new JPanel(new BorderLayout());
        p2.add(k, "West");
        p2.add(v, "Center");
        add(p2,"Center");
    }

    // -------------------------------------------------------------------------
    //
    // Hauptmethode zum Testen
    //
    // -------------------------------------------------------------------------
    public static void main(String[] args)
    {
        JFrame f = new JFrame("Beispiel für faltbare Panels");
        
        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p,BoxLayout.Y_AXIS));
        p.add( new FoldablePanel("Person 1", new String[]{"Vorname","Nachname","Alter","Beruf"}, new String[]{"Peter","Mustermann","32","Programmierer"}));
        p.add( new FoldablePanel("Person 2", new String[]{"Vorname","Nachname","Alter","Beruf"}, new String[]{"Petra","Mustermann","27","Hausfrau"}));
        p.add( new FoldablePanel("Person 3", new String[]{"Vorname","Nachname","Alter"}, new String[]{"Paul","Mustermann","7"}));

        f.add(p,"North");
        f.pack();
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    // -------------------------------------------------------------------------
    //
    // Methode zum "Falten" des Panels
    //
    // -------------------------------------------------------------------------
    public void actionPerformed(ActionEvent ae)
    {
        if (toggle.isSelected())
        {
            buffer = getComponent(1);
            remove(buffer);
            toggle.setText("\u25b2");
        } else
        {
            add(buffer, "Center");
            toggle.setText("\u25bc");
        }
        revalidate();
    }
}
```

Der Trick für das "vertikale Flowlayout" ist einfach ein BoxLayout in den Norden eines BorderLayouts zu packen. Wenn Du das dann noch in ein GridLayout packst, kannst Du auch mehrere Spalten nebeneinander haben.

Hoffe geholfen zu haben!


----------



## Wildcard (10. Nov 2006)

kaie hat gesagt.:
			
		

> Der Trick für das "vertikale Flowlayout" ist einfach ein BoxLayout in den Norden eines BorderLayouts zu packen.


Spitzen Idee, so passt's  :applaus: 
Muss zu meiner Schande gestehen das ich mittlerweile mit den verhaßten SWT LayoutMangern besser klar komme  :? 

Vielen Dank


----------



## André Uhres (11. Nov 2006)

Wildcard hat gesagt.:
			
		

> ..André zB gibt doch so gerne Codebeispiele  :wink:


Aha   . Na dann stell ich einfach auch mal meine Version rein. 
Es ist eine Verschachtelung *nur von Flow- und BorderLayout*:

```
/*
 * ShowHideDetailsDemo.java
 */
package layout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class ShowHideDetailsDemo extends JFrame {
    private JScrollPane scrollingInfo;
    private InfoPanel infoPanel;
    public ShowHideDetailsDemo() {
        super("ShowHideDetailsDemo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400,300);
        setLocationRelativeTo(null);
        //Info Panel:
        infoPanel = new InfoPanel(180, 65, 23);//width, keywidth, lineheight
        infoPanel.add( "Person 1",//titel
                new String[]{"Vorname","Nachname","Alter","Beruf"},//keys
                new String[]{"Peter","Mustermann","32","Programmierer"});//values
        infoPanel.add( "Person 2",//titel
                new String[]{"Vorname","Nachname","Alter","Beruf"},//keys
                new String[]{"Petra","Mustermann","27","Hausfrau"});//values
        infoPanel.add( "Person 3",//titel
                new String[]{"Vorname","Nachname","Alter"},//keys
                new String[]{"Paul","Mustermann","7"});//values
        scrollingInfo = new JScrollPane(infoPanel);
        scrollingInfo.setPreferredSize(new Dimension(200, 200));
        scrollingInfo.setHorizontalScrollBarPolicy(
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        getContentPane().add(scrollingInfo, BorderLayout.WEST);
    }
    public static void main(final String args[]) {new ShowHideDetailsDemo().setVisible(true);}
}
class InfoPanel extends JPanel{
    private InfoPanel infoPanel;
    private int infoPanelWidth;
    private int keyWidth;
    private int lineHeight;
    public InfoPanel(int infoPanelWidth, int keyWidth, int lineHeight){
        this.infoPanelWidth = infoPanelWidth;
        this.lineHeight = lineHeight;
        this.keyWidth = keyWidth;
        infoPanel = this;
    }
    public Dimension getPreferredSize(){
        Component[] components = getComponents();
        int infoPanelHeight = 0;
        for (int i = 0; i < components.length; i++) {
            infoPanelHeight += ((SummaryDetailPanel)components[i]).getSummaryHeight();
            infoPanelHeight += ((SummaryDetailPanel)components[i]).getDetailHeight();
            infoPanelHeight += ((FlowLayout)this.getLayout()).getVgap();
        }
        return new Dimension(infoPanelWidth, infoPanelHeight);
    }
    public void add(String titel, String[] keys, String[] values) {
        add(new SummaryDetailPanel(titel, keys, values));
    }
    class SummaryDetailPanel extends JPanel{
        private JPanel summary;
        private DetailPanel detailPanel;
        private JToggleButton detailButton;
        public SummaryDetailPanel(String titel, String[] keys, String[] values){
            setLayout(new BorderLayout());
            //Summary:
            summary = new JPanel();
            summary.setBackground(Color.LIGHT_GRAY);
            summary.add(new JLabel(titel));
            detailButton = new JToggleButton("Hide", true);
            detailButton.setFont(detailButton.getFont().deriveFont(10f));
            detailButton.setPreferredSize(new Dimension(34,15));
            detailButton.setMargin(new Insets(0,0,0,0));
            summary.add(detailButton);
            add(summary, BorderLayout.CENTER);
            //Detail:
            detailPanel = new DetailPanel();
            for (int i = 0; i < keys.length; i++) {
                detailPanel.add(keys[i], values[i]);
            }
            add(detailPanel, BorderLayout.SOUTH);
            //Listener:
            detailButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    detailButtonActionPerformed(evt);
                }
            });
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    detailButton.doClick();
                }
            });
        }
        private void detailButtonActionPerformed(ActionEvent evt) {
            detailPanel.setVisible( !detailPanel.isVisible() );
            detailButton.setText(detailPanel.isVisible()?"Hide":"Detail");
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    infoPanel.scrollRectToVisible(getBounds());
                    revalidate();
                }
            });
        }
        public int getSummaryHeight() {return summary.getHeight();}
        public int getDetailHeight() {
            return detailPanel.isVisible()?(int)detailPanel.getHeight():0;
        }
        class DetailPanel extends JPanel{
            private int detailPanelWidth, detailPanelHeight; 
            public DetailPanel(){
                detailPanelWidth = infoPanelWidth;
                detailPanelHeight = lineHeight;
            }
            public Dimension getPreferredSize(){
                return new Dimension(detailPanelWidth, detailPanelHeight);
            }
            private void add(String key, String value) {
                super.add(new DetailLine(key, value));
            }
            class DetailLine extends JPanel{
                private JPanel keyPanel, valuePanel;
                public DetailLine(String key, String value){
                    setLayout(new BorderLayout());
                    setPreferredSize(new Dimension(infoPanelWidth,lineHeight));
                    keyPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
                    keyPanel.setPreferredSize(new Dimension(keyWidth,lineHeight));
                    valuePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
                    keyPanel.add(new JLabel(key));
                    JLabel valueLabel = new JLabel(value);
                    valueLabel.setBorder(new LineBorder(Color.black));
                    valueLabel.setBackground( new Color(255,255,200) );
                    valueLabel.setOpaque(true);
                    valuePanel.add(valueLabel);
                    add(keyPanel, BorderLayout.WEST);
                    add(valuePanel, BorderLayout.CENTER);
                    detailPanelHeight += lineHeight;
                }
            }
        }
    }
}
```


----------



## Wildcard (11. Nov 2006)

hehe.
Etwas mehr arbeit aber auch 'ne schöne Lösung. 
Danke sehr


----------



## Tobias (30. Jan 2007)

SwingX hat ein VerticalLayout. Und eine JXCollapsiblePane. Damit baue ich gerade etwas ganz ähnliches...

mpG
Tobias


----------



## André Uhres (30. Jan 2007)

Tobias hat gesagt.:
			
		

> SwingX hat ein VerticalLayout. Und eine JXCollapsiblePane. Damit baue ich gerade etwas ganz ähnliches...


Stell's doch bitte hier rein, wenn's fertig ist  :toll:


----------



## jakob (13. Dez 2007)

Hallo zusammen, 

danke fuer die tollen Codebeispiele. Wie kann ich den Auf/Zuklappvorgang langsamer gestalten? Also nicht pop auf pop zu sondern ein langsames gleichmaessiges Hoch- und Runterfahren.

Bin auf Antworten gespannt.

Liebe Gruesse,
Jakob


----------

