# Bestes Layout für die Toolbar



## alex-t (16. Jul 2004)

welches layout kann man für die toolbar verwenden, sodass der inhalt beim verkleinern des fensters sichtbar bleibt und seine grösse nicht verändert? ich habe das schon in mehreren applets gesehen. die toolbar bekommt da eine art "zeilenumbruch".


----------



## Catscratch1 (16. Jul 2004)

Füg das Panel, in dem die Toolbar ist einer JScrollPane zu, dann dürfte es keinen Umbruch mehr geben.
Ich benutze für solche Sachen gerne das BoxLayout. Abstände kann man dann gut über leere Boxen erzeugen!


----------



## alex-t unterwegs (16. Jul 2004)

tut mir leid, ich habe mich unverständlich ausgedrückt. ich möchte so einen zeilenumbruch haben! momentan wird immer nur eine zeile angezeigt und wenn sich das applet verkleiner, wird diese zeile in der darstellung abgeschnitten und nicht umgebrochen. gibt es da eventuell bei netbeans oder jbuilder eine einstellung oä.?


----------



## L-ectron-X (17. Jul 2004)

Versuche mal das FlowLayout. Das kann Komponenten, die nicht mehr auf eine "Zeile" passen auf der nächsten "Zeile" fort führen, quasi umbrechen.
http://java.sun.com/j2se/1.4.2/docs/api/java/awt/FlowLayout.html


----------



## macfreakz (19. Jul 2004)

Wenn du flexibel sein möchtest, erstelle doch ein eigenes LayoutManager!

Implementiere zuerst das Interface LayoutManager2 oder Layoutmanager und überschreibe die Methoden. Du kannst alles entscheiden, wie die Komponenten sich verhalten sollen. Ist nicht so schwer, gelle?


----------



## Isaac (19. Jul 2004)

macfreakz hat gesagt.:
			
		

> Wenn du flexibel sein möchtest, erstelle doch ein eigenes LayoutManager!
> 
> Implementiere zuerst das Interface LayoutManager2 oder Layoutmanager und überschreibe die Methoden. Du kannst alles entscheiden, wie die Komponenten sich verhalten sollen. Ist nicht so schwer, gelle?




Schon mal einen geschrieben? Ich stelle mir das ziemlich komplex vor. Habs aber noch nie gemacht. Wenn du schon mal einen geschrieben hast poste doch mal quellcode, würde mich mal interesieren wie einfach das ist.


----------



## Beni (19. Jul 2004)

Ich hab mal was ähnliches für eine Toolbar geschrieben. Den Manager müsstest du halt anpassen, aber vielleicht nützts Dir was.

(@Isaac: das ist gar nicht so kompliziert, solange man nicht gerade ein GridBagLayout schreibt...)


```
private class BLayout implements LayoutManager {
		private Dimension[] preferred;
		
		private int getPreferredHeight( int width ){
			Dimension size = new Dimension( width, Integer.MAX_VALUE );
			
			Container parent = BToolbar.this;
			
			int count = parent.getComponentCount();
			if( preferred == null || preferred.length < count )
				preferred = new Dimension[ count ];
			
			for( int i = 0; i < count; i++ )
				preferred[i] = parent.getComponent( i ).getPreferredSize();
			
			int[] breaks = bestRowRatio( parent, preferred, size );
			
			int height = 0;

			for( int i = 0; i < breaks.length; i++ ){
				int max = (i+1<breaks.length) ? breaks[i+1] : preferred.length;
				int maxHeight = 0;
				for( int j = breaks[i]; j<max; j++ ){
					maxHeight = Math.max( maxHeight, preferred[j].height );
				}
				height += maxHeight;
			}
			
			return height;
		}
		
		public Dimension preferredLayoutSize( Container parent ){
			int width = 0;
			int height = 0;
			
			for( int i = 0, n = parent.getComponentCount(); i<n; i++ ){
				Dimension pref = parent.getComponent( i ).getPreferredSize();
				width += pref.width;
				height = Math.max( pref.height, height );
			}
			
			Dimension sizeOf = sizeOf( parent );
			Dimension size = parent.getSize();
			
			return new Dimension( width + size.width - sizeOf.width, 
					height + size.height - sizeOf.height );
		}
		
		
		public void addLayoutComponent(String name, Component comp) {
		}
		
		public Dimension minimumLayoutSize(Container parent) {
			return null;
		}
		
		public void removeLayoutComponent(Component comp) {
		}
		
		private Dimension sizeOf( Container parent ){
			Insets insets = parent.getInsets();
			Dimension size;
			if( insets == null )
				size = new Dimension( parent.getWidth(), parent.getHeight() );
			else{
				size = new Dimension( parent.getWidth() 
					- insets.left - insets.right, parent.getHeight()
					- insets.top - insets.bottom );
			}
			
			size.width = Math.max( 0, size.width - 2*side );
			size.height = Math.max( 0, size.height - 2*side );
			
			return size;
		}
		
		public synchronized void layoutContainer(Container parent) {
			int count = parent.getComponentCount();
			if( preferred == null || preferred.length != count )
				preferred = new Dimension[ count ];
			
			for( int i = 0; i < count; i++ )
				preferred[i] = parent.getComponent( i ).getPreferredSize();
			
			Dimension parentSize = sizeOf( parent );
			int[] breaks = bestRowRatio( parent, preferred, parentSize );
		
			float[] maxHeights = new float[ breaks.length ];
			float[] preferredWidths = new float[ breaks.length ];
			int preferredHeight = 0;
			//int maxWidth = 0;
			
			for( int i = 0; i < breaks.length; i++ ){
				int max = (i+1<breaks.length) ? breaks[i+1] : count;
				for( int j = breaks[i]; j<max; j++ ){
					maxHeights[i] = Math.max( maxHeights[i], preferred[j].height );
					preferredWidths[i] += preferred[j].width;
				}
				preferredHeight += maxHeights[i];
			//	maxWidth = Math.max( maxWidth, preferredWidths[ i ]);
			}
			
			
			float fullHeight = Math.min( parentSize.height, preferredHeight );
			int leftHeight = (int)fullHeight;
			
			int x = side, y = side;
			Insets insets = parent.getInsets();
			if( insets != null ){
				x += insets.left;
				y += insets.top;
			}
			
			int left = x;
			
			for( int i = 0; i < breaks.length; i++ ){
				int max = (i+1<breaks.length) ? breaks[i+1] : count;
				int height = i+1<breaks.length ? Math.round( (maxHeights[ i ] 
						/ preferredHeight) * fullHeight) : leftHeight;
				
				leftHeight -= height;
			
				float fullWidth = Math.min( parentSize.width, preferredWidths[i] );
				int leftWidth = (int)fullWidth;
				
				x = left;
				
				for( int j = breaks[i]; j<max; j++ ){
					int width = j+1<max ? Math.round((preferred[j].width 
							/ preferredWidths[i] ) * fullWidth ): leftWidth;
					leftWidth -= width;
					parent.getComponent( j ).setBounds( x, y, width, height );
					x += width;
				}
				
				y += height;
			
			}
		}
		
		private int[] bestRowRatio( Container parent, Dimension[] preferreds, Dimension containerSize ){
			int rows = 0;
			double oldRatio = 0.0;
			double ratio = Double.POSITIVE_INFINITY;
			int size = preferreds.length;
			
			double fullWidth = 0;
			for( int i = 0, n = preferreds.length; i<n; i++ )
				fullWidth += preferreds[i].width;
			
			do{
				rows++;
				oldRatio = ratio;
				
				double normalWidth = fullWidth / rows;
				double normalHeight = 0;
				double currentWidth = 0;
				double maxWidth = 0;
				double maxHeight = 0;
				
				int index = 0;
				
				for( int i = 0; i<rows; i++ ){
					maxHeight = 0;
					currentWidth = 0;
					
					while( index < size && currentWidth < normalWidth ){
						currentWidth += preferreds[ index ].width;
						maxHeight = Math.max( maxHeight, preferreds[ index ].height );
						
						index++;
					}
					
					maxWidth = Math.max( maxWidth, currentWidth );
					normalHeight += maxHeight;
				}
				
				ratio = Math.abs( Math.min( 0, containerSize.width - maxWidth ) - 
						Math.min( 0, containerSize.height - normalHeight ) );
			}while( ratio < oldRatio );
			rows--;
			
			int[] breaks = new int[ rows ];
			int index = 0;
			double currentWidth = 0;
			double normalWidth = fullWidth / rows;
			
			for( int i = 0; i<rows; i++ ){
				currentWidth = 0;
				breaks[i] = index;
				
				while( index < size && currentWidth < normalWidth ){
					currentWidth += preferreds[ index ].width;
					index++;
				}
			}
			
			return breaks;
		}
	}
```


----------



## macfreakz (19. Jul 2004)

```
import java.awt.*;
import java.util.*;
import javax.swing.*;

public class ResizeLayout 
implements LayoutManager2 
{
    // Unsichtbare Komponenten liegen hier
    private JComboBox cb_otherComp;
    Vector theRest = new Vector();
    
    // Konstruktor
    public ResizeLayout()
    {
        cb_otherComp = new JComboBox();
    }
    
    public void layoutContainer(Container parent) 
    {        
        // Maximale Größe holen
        Dimension maxSize = maximumLayoutSize(parent);
        
        int x=0; // Position X für Komponent
        int y=0; // Position Y für Komponent
        
        // Vektor theRest entleeren
        theRest.clear();

        for(int i=0; i<parent.getComponentCount(); i++)
        {
            Component c = parent.getComponent(i);
            c.setVisible(true);
            
            // Sichtbarkeit prüfen
            if(!c.isVisible())
                continue;
            
            c.setVisible(false);
            
            // Größe ermitteln
            int width = c.getPreferredSize().width;
            int height = c.getPreferredSize().height;

            if((width+x)<maxSize.width)
            {
	            // Komponent Position u. Größe setzen
                c.setVisible(true);
	            c.setBounds(x, y, width, height);
            }
            else
            {
                // Falls notwendig, die unsichtbare Komponenten
                // in die ComboBox stekcen!
                cb_otherComp.setVisible(true);
                
                theRest.add(">>");
                
                for(int z=i; z<parent.getComponentCount(); z++)
                {
                    Component rc = parent.getComponent(z);
                    if(!(rc instanceof JButton))
                        continue;
                    
                    JButton bt = (JButton)rc;
	                theRest.add(bt.getText());
                }
                DefaultComboBoxModel cbm = new DefaultComboBoxModel(theRest);
                cb_otherComp.setModel(cbm);
                parent.add(cb_otherComp);
                cb_otherComp.setBounds(x, y, cb_otherComp.getPreferredSize().width, cb_otherComp.getPreferredSize().height);
                
                // diese Methode verlassen
                return;
            
            }
            
            // position X verschieben für nächste Komponent
            x=x+width;
                
        }
     }

    // Empfohlene Größe ermitteln
    public Dimension preferredLayoutSize(Container parent) 
    {
        Component c = null;
        int width=0; 
        int height=0;
        
        for(int i=0; i<parent.getComponentCount(); i++)
        {
            c = parent.getComponent(i);
            
            if(!c.isVisible())
                continue;
            
            width=width+c.getPreferredSize().width;
            if(height<c.getPreferredSize().height)
                height=c.getPreferredSize().height;
        }
        
        return new Dimension(width, height);
    }
    
    // maximale Größe ermitteln
    public Dimension maximumLayoutSize(Container target) 
    {
        int width = target.getFocusCycleRootAncestor().getWidth();
        int height = preferredLayoutSize(target).height;
        return new Dimension(width, height);
    }
    
    // minimale Größe ermitteln
    public Dimension minimumLayoutSize(Container parent) 
    {
        return preferredLayoutSize(parent);
    }
    
    public void addLayoutComponent(String name, Component comp) 
    {
    }

    public void addLayoutComponent(Component comp, Object constraints) 
    {
    }

    public void removeLayoutComponent(Component comp) 
    {
    }
    
    // Unwichtige Methoden ... 
    public float getLayoutAlignmentX(Container target) 
    {
        return 0;
    }

    public float getLayoutAlignmentY(Container target) 
    {
        return 0;
    }

    public void invalidateLayout(Container target) 
    {
    }
    
    
    // Test main methode zum Testen
    
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("ResizeLayout");
        JPanel toolbar = new JPanel(new ResizeLayout());
        
        toolbar.add(new JButton("Neu..."));
        toolbar.add(new JButton("Bearbeiten"));
        toolbar.add(new JButton("Einstellungen"));
        toolbar.add(new JButton("Hilfe"));
        toolbar.add(new JButton("Forum"));
        toolbar.add(new JButton("Java"));
        toolbar.add(new JButton("Echt grovy?"));
        toolbar.add(new JButton("Praktisch"));
        toolbar.add(new JButton("Aha"));
        toolbar.add(new JButton("Blabla"));
        toolbar.add(new JButton("so funzt!"));
        
        frame.getContentPane().add(toolbar);
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setVisible(true);
    }

}
```

@Isaac: Ja, habe es irgendwo gespeichert! Aber ich habe ein neues für dich extra ganz schnell erstellt, dir zuliebe ;-) Dieses LayoutManager eignet nur zum Toolbar. Es ist etwas schlampig programmiert. Du kannst es optimieren bzw. feilen und Aktionen zum ComboBox hinfügen!

Und noch Fragen???

@Beni: yap! GridBagLayout ist am kompliziersten!!! puh, ...


----------

