Results 1 to 4 of 4
  1. #1
    JavaDummy is offline Member
    Join Date
    Sep 2008
    Posts
    2
    Rep Power
    0

    Question How to control layout for multiple toolbars?

    Hi,

    I'm trying to add a second toolbar to an existing app. The app frame is in BorderLayout. I think a panel with FlowLayout suffices for the arrangement of the toolbars, but I don't get the expected behavior:

    I would like both toolbars arranged next each other horizontally if the app frame is wide enough.

    If the frame is resized (smaller), I would like the second toolbar wrap around into a second 'line' and the containing (FlowLayout) panel be increased in height.

    What's going wrong is that the toolbars panel does not get higher so the second toolbar is not visible if it has wrapped around.

    I created an empty sample showing the problem:

    Java Code:
    package swingtest;
    
    public class mainform extends javax.swing.JFrame
    {
          public mainform()
       {
          initComponents();
       }
       // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
       private void initComponents()
       {
          jPanel1 = new javax.swing.JPanel();
          jToolBar1 = new javax.swing.JToolBar();
          jButton1 = new javax.swing.JButton();
          jButton2 = new javax.swing.JButton();
          jToggleButton2 = new javax.swing.JToggleButton();
          jToolBar2 = new javax.swing.JToolBar();
          jButton3 = new javax.swing.JButton();
          jToggleButton1 = new javax.swing.JToggleButton();
          jSplitPane1 = new javax.swing.JSplitPane();
    
          setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
          addComponentListener(new java.awt.event.ComponentAdapter()
          {
             public void componentResized(java.awt.event.ComponentEvent evt)
             {
                frameResized(evt);
             }
          });
    
          jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 1, 1));
    
          jButton1.setText("jButton1");
          jToolBar1.add(jButton1);
    
          jButton2.setText("jButton2");
          jToolBar1.add(jButton2);
    
          jToggleButton2.setText("jToggleButton2");
          jToolBar1.add(jToggleButton2);
    
          jPanel1.add(jToolBar1);
    
          jButton3.setText("jButton3");
          jToolBar2.add(jButton3);
    
          jToggleButton1.setText("jToggleButton1");
          jToolBar2.add(jToggleButton1);
    
          jPanel1.add(jToolBar2);
    
          getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);
    
          jSplitPane1.setDividerLocation(200);
          getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);
    
          pack();
       }// </editor-fold>//GEN-END:initComponents
    
       private void frameResized(java.awt.event.ComponentEvent evt)//GEN-FIRST:event_frameResized
       {//GEN-HEADEREND:event_frameResized
       validate();
       }//GEN-LAST:event_frameResized
    
       public static void main(String args[])
       {
          java.awt.EventQueue.invokeLater(new Runnable()
          {
             public void run()
             {
                new mainform().setVisible(true);
             }
          });
       }
    
       // Variables declaration - do not modify//GEN-BEGIN:variables
       private javax.swing.JButton jButton1;
       private javax.swing.JButton jButton2;
       private javax.swing.JButton jButton3;
       private javax.swing.JPanel jPanel1;
       private javax.swing.JSplitPane jSplitPane1;
       private javax.swing.JToggleButton jToggleButton1;
       private javax.swing.JToggleButton jToggleButton2;
       private javax.swing.JToolBar jToolBar1;
       private javax.swing.JToolBar jToolBar2;
       // End of variables declaration//GEN-END:variables
    }
    How can I tell jPanel1 to use more space if the toolbars have wrapped around?

    Thanks,
    Thomas

  2. #2
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    I copied and pasted most of the code from the FlowLayout source file and made changes to the preferredLayoutSize method to get it to wrap. It's a start.
    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class MainFormRx extends JFrame
    {
        public MainFormRx()
        {
            initComponents();
        }
    
        private void initComponents()
        {
            jPanel1 = new JPanel();
            jToolBar1 = new JToolBar();
            jButton1 = new JButton();
            jButton2 = new JButton();
            jToggleButton2 = new JToggleButton();
            jToolBar2 = new JToolBar();
            jButton3 = new JButton();
            jToggleButton1 = new JToggleButton();
            jSplitPane1 = new JSplitPane();
    
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            addComponentListener(new ComponentAdapter()
            {
                public void componentResized(ComponentEvent evt)
                {
                    frameResized(evt);
                }
            });
    
            jPanel1.setLayout(//new FlowLayout(FlowLayout.LEFT, 1, 1));
                              new WrappingLayout(WrappingLayout.LEFT, 1, 1));
    
            jButton1.setText("jButton1");
            jToolBar1.add(jButton1);
    
            jButton2.setText("jButton2");
            jToolBar1.add(jButton2);
    
            jToggleButton2.setText("jToggleButton2");
            jToolBar1.add(jToggleButton2);
    
            jPanel1.add(jToolBar1);
    
            jButton3.setText("jButton3");
            jToolBar2.add(jButton3);
    
            jToggleButton1.setText("jToggleButton1");
            jToolBar2.add(jToggleButton1);
    
            jPanel1.add(jToolBar2);
    
            getContentPane().add(jPanel1, BorderLayout.NORTH);
    
            jSplitPane1.setDividerLocation(200);
            getContentPane().add(jSplitPane1, BorderLayout.CENTER);
            setLocation(100,300);
            pack();
        }
    
        private void frameResized(ComponentEvent evt)
        {
            validate();
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    new MainFormRx().setVisible(true);
                }
            });
        }
    
        private javax.swing.JButton jButton1;
        private javax.swing.JButton jButton2;
        private javax.swing.JButton jButton3;
        private javax.swing.JPanel jPanel1;
        private javax.swing.JSplitPane jSplitPane1;
        private javax.swing.JToggleButton jToggleButton1;
        private javax.swing.JToggleButton jToggleButton2;
        private javax.swing.JToolBar jToolBar1;
        private javax.swing.JToolBar jToolBar2;
    }
    
    class WrappingLayout implements LayoutManager {
        public static final int LEFT     = 0;
        public static final int CENTER   = 1;
        public static final int RIGHT    = 2;
        public static final int LEADING  = 3;
        public static final int TRAILING = 4;
    
        int align;    
        int hgap;
        int vgap;
    
        public WrappingLayout() {
            this(CENTER, 5, 5);
        }
    
        public WrappingLayout(int align) {
            this(align, 5, 5);
        }
    
        public WrappingLayout(int align, int hgap, int vgap) {
            this.hgap = hgap;
            this.vgap = vgap;
            setAlignment(align);
        }
    
        public int getAlignment() {
            return align;
        }
    
        public void setAlignment(int align) {
            switch (align) {
            case LEADING:
                this.align = LEFT;
                break;
            case TRAILING:
                this.align = RIGHT;
                break;
            default:
                this.align = align;
                break;
            }
        }
    
        public int getHgap() {
            return hgap;
        }
    
        public void setHgap(int hgap) {
            this.hgap = hgap;
        }
    
        public int getVgap() {
            return vgap;
        }
    
        public void setVgap(int vgap) {
            this.vgap = vgap;
        }
    
        public Dimension preferredLayoutSize(Container parent) {
            synchronized(parent.getTreeLock()) {
                Dimension dim = new Dimension(0,0);
                int maxWidth = 0;
                int componentCount = parent.getComponentCount();
    
                for(int i = 0; i < componentCount; i++) {
                    Component c = parent.getComponent(i);
                    if(c.isVisible()) {
                        Dimension d = c.getPreferredSize();
                        if((dim.width + d.width + hgap) <= parent.getWidth()) {
                            dim.height = Math.max(dim.height, d.height);
                        } else {
                            dim.height += vgap + d.height;
                            dim.width = 0;
                        }
                        if(dim.width > 0) {
                            dim.width += hgap;
                        }
                        dim.width += d.width;
                        if(dim.width > maxWidth) {
                            maxWidth = dim.width;
                        }
                    }
                }
                Insets insets = parent.getInsets();
                dim.width = Math.max(dim.width, maxWidth);
                dim.width += insets.left + insets.right + 2*hgap;
                dim.height += insets.top + insets.bottom + 2*vgap;
                return dim;
            }
        }
    
        public Dimension minimumLayoutSize(Container parent) {
            synchronized(parent.getTreeLock()) {
                Dimension dim = new Dimension(0,0);
                int componentCount = parent.getComponentCount();
    
                for(int i = 0; i < componentCount; i++) {
                    Component c = parent.getComponent(i);
                    if(c.isVisible()) {
                        Dimension d = c.getMinimumSize();
                        dim.height = Math.max(dim.height, d.height);
                        if(i > 0) {
                            dim.width += hgap;
                        }
                        dim.width += d.width;
                    }
                }
                Insets insets = parent.getInsets();
                dim.width += insets.left + insets.right + 2*hgap;
                dim.height += insets.top + insets.bottom + 2*vgap;
                return dim;
            }
        }
    
        public void layoutContainer(Container parent) {
            synchronized(parent.getTreeLock()) {
                Insets insets = parent.getInsets();
                int maxWidth = parent.getWidth() -
                    (insets.left + insets.right + hgap*2);
                int componentCount = parent.getComponentCount();
                int x = 0, y = insets.top + vgap;
                int rowh = 0, start = 0;
                boolean ltr = parent.getComponentOrientation().isLeftToRight();
    
                for(int i = 0; i < componentCount; i++) {
                    Component c = parent.getComponent(i);
                    if(c.isVisible()) {
                        Dimension d = c.getPreferredSize();
                        c.setSize(d.width, d.height);
                        if((x == 0) || ((x + d.width) <= maxWidth)) {
                            if(x > 0) {
                                x += hgap;
                            }
                            x += d.width;
                            rowh = Math.max(rowh, d.height);
                        } else {
                            rowh = moveComponents(parent, insets.left + hgap, y,
                                              maxWidth - x, rowh, start, i, ltr);
                            x = d.width;
                            y += vgap + rowh;
                            rowh = d.height;
                            start = i;
                        }            
                    }
                }
                moveComponents(parent, insets.left + hgap, y, maxWidth - x,
                               rowh, start, componentCount, ltr);
            }        
        }
    
        private int moveComponents(Container parent, int x, int y, int width,
                                   int height, int rowStart, int rowEnd,
                                   boolean ltr) {
            switch(align) {
                case LEFT:
                    x += ltr ? 0 : width;
                    break;
                case CENTER:
                    x += width/2;
                    break;
                case RIGHT:
                    x += ltr ? width : 0;
                    break;
                case LEADING:
                    break;
                case TRAILING:
                    x += width;
                    break;
            }
            for(int i = rowStart; i < rowEnd; i++) {
                Component c = parent.getComponent(i);
                if(c.isVisible()) {
                    int cy;
                    cy = y + (height - c.getHeight())/2;
                    if(ltr) {
                        c.setLocation(x, cy);
                    } else {
                        c.setLocation(parent.getWidth() - x - c.getWidth(), cy);
                    }
                    x += c.getWidth() + hgap;
                }
            }
            return height;
        }
    
        public void addLayoutComponent(String name, Component comp) { }
        public void removeLayoutComponent(Component comp) { }
    }

  3. #3
    JavaDummy is offline Member
    Join Date
    Sep 2008
    Posts
    2
    Rep Power
    0

    Default Great Answer!

    Great!

    That's how I expected it to work.

    Thank you very much, hardwired!

    Thomas

  4. #4
    famousj is offline Member
    Join Date
    Mar 2012
    Posts
    1
    Rep Power
    0

    Default Re: Great Answer!

    I know it's four years later, so perhaps it's a change to Java, but I found an easier way to do this by simply extending FlowLayout and overriding the setPreferredSize method:

    import java.awt.*;

    public class CustomToolbarLayout extends FlowLayout
    {
    private static final long serialVersionUID = 1L;

    public CustomToolbarLayout()
    {
    super(FlowLayout.LEADING);
    }

    @Override
    public Dimension preferredLayoutSize(Container parent)
    {
    synchronized(parent.getTreeLock())
    {
    Dimension size = super.minimumLayoutSize(parent);

    int nComponents = parent.getComponentCount();
    if (nComponents > 0)
    {
    int firstY = parent.getComponent(0).getY();
    Component last = parent.getComponent(nComponents - 1);
    int lastY = last.getY();

    if (lastY != firstY)
    {
    size = new Dimension((int)size.getWidth(), lastY + last.getHeight());
    }
    }

    return size;
    }
    }
    }

Similar Threads

  1. Control on exe
    By jazz2k8 in forum New To Java
    Replies: 3
    Last Post: 08-14-2008, 02:06 PM
  2. control app width based on certain control
    By thebillybobjr in forum SWT / JFace
    Replies: 0
    Last Post: 05-15-2008, 04:52 PM
  3. Multiple Layout Managers
    By AJG in forum New To Java
    Replies: 0
    Last Post: 04-06-2008, 01:43 AM
  4. X11.Toolkit logging out of control
    By gjsalazar in forum AWT / Swing
    Replies: 0
    Last Post: 11-20-2007, 11:42 PM
  5. Control Structure Question
    By ibanez270dx in forum New To Java
    Replies: 1
    Last Post: 11-12-2007, 10:10 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •