Link to home
Start Free TrialLog in
Avatar of AntoniRyszard
AntoniRyszard

asked on

Alternative to using jpanels?

Hello,

I wrote this panel to display a column of buttons, and to make them all the same width.

I tried adding the panel to a frame using the borderlayout.CENTER method. But as I expected this stretches the buttons to fill the frame.

I would like to keep the buttons as a column all the same width, but wondered if to avoid the buttons becomming stretched, if there was any alternative to the jpanel? And I hoped to stop the buttons from stretching when the frame is maximised.

Thank you

      JPanel panel = new JPanel(new GridLayout(0,1));
      panel.add(JButton button1 = new JButton("Ten"));
      button1.addActionListener(this);
      panel.add(JButton button2 = new JButton("Eleven"));
      button2.addActionListener(this);
      panel.add(JButton button3l =  new JButton("Twelve"));
      button3.addActionListener(this);
      panel.add(JButton button4 = new JButton("Thirteen"));
      button4.addActionListener(this);
      panel.add(JButton button5 = new JButton("Fourteen"));
      button5.addActionListener(this);
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Avatar of AntoniRyszard
AntoniRyszard

ASKER

Thanks

Would I replace the Gridlayout with boxlayout? And if I used the boxlayout, will all the buttons have the same width as they do currently?

      JPanel panel = new JPanel(new GridLayout(0,1));
      panel.add(JButton button1 = new JButton("Ten"));
      button1.addActionListener(this);
      panel.add(JButton button2 = new JButton("Eleven"));
      button2.addActionListener(this);
      panel.add(JButton button3l =  new JButton("Twelve"));
      button3.addActionListener(this);
      panel.add(JButton button4 = new JButton("Thirteen"));
      button4.addActionListener(this);
      panel.add(JButton button5 = new JButton("Fourteen"));
      button5.addActionListener(this);
No your buttons get the same width by specifying:

      buttonY.setPreferredSize(....................);
sometimes together with:
      buttonY.setMaximumSize(....................);

;JOOP!
In general the layout manager does not directly dictate the component's size.
;JOOP!
Using the jpanel makes the buttons all the same width.

But I was trying avoid when I use BorderLayout.CENTER, not the panel from filling the screen.

(CEHJ) recommended the boxlayout: http://java.sun.com/docs/books/tutorial/uiswing/layout/box.html

Could I use the BoxLayout?
Sorry sciuri, but that setPreferredSize is really not needed.

Antoni,

the code you have is perfectly OK. You just have to place "panel" in another JPanel (panel2) having the default FlowLayout.
Then place panel2 in the panel you have now with BorderLayout.CENTER
So,

   1) The first panel having the BorderLayout contains in the CENTER
   2) a second JPanel having the (default) FlowLayout. This pabel contains
   3) the JPanel "panel" from your posted code having the GridLayout(0,1)
Rather than uisng two panels, do you think this could work?

      JPanel panel = new JPanel(new BoxLayout(panel, BoxLayout.Y_AXIS));
      panel.add(JButton button1 = new JButton("Ten"));
      button1.addActionListener(this);
      panel.add(JButton button2 = new JButton("Eleven"));
      button2.addActionListener(this);
      panel.add(JButton button3l =  new JButton("Twelve"));
      button3.addActionListener(this);
      panel.add(JButton button4 = new JButton("Thirteen"));
      button4.addActionListener(this);
      panel.add(JButton button5 = new JButton("Fourteen"));
      button5.addActionListener(this);
You can do this sort of thing:

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


public class F extends JFrame {

      private void setGui() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            getContentPane().add(new BoxPanel(), BorderLayout.CENTER);
      }

class BoxPanel extends JPanel {

      public BoxPanel() {
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            JButton[] buttons = new JButton[5];
            for(int i = 0;i < buttons.length;i++) {
                  buttons[i] = new JButton("Button " + i);
                  buttons[i].setAlignmentX(Component.CENTER_ALIGNMENT);
                  add(buttons[i]);
            }
      }

}


      public static void main(String[] args) throws Exception {
            F f = new F();
            f.setGui();
            f.pack();
            f.setVisible(true);
      }

}
>> Rather than uisng two panels
What's the problem with that?

>>do you think this could work?
I don't think all your buttons will have the same width then


Remark that this

      panel.add(JButton button2 = new JButton("Eleven"));
      button2.addActionListener(this);

doesn't compile. It should be

      JButton button2 = new JButton("Eleven");
      panel.add(button2);
      button2.addActionListener(this);
>> I don't think all your buttons will have the same width then
Then you need to use setPreferredSize() on all your buttons.
But, hey that's exactly what GridLayout is made for...
Hello,

I changed the code a little, and found the width of each button was different.

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

public class F extends JFrame{

     JButton button1, button2, button3, button4, button5;  

     private void setGui() {
          JPanel panel = new JPanel();
          panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
          panel.add(button1 = new JButton("Ten"));
          panel.add(button2 = new JButton("Eleven"));
          panel.add(button3 =  new JButton("Twelve"));
          panel.add(button4 = new JButton("Thirteen"));
          panel.add(button5 = new JButton("Fourteen"));

          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          getContentPane().add(panel, BorderLayout.CENTER);
     }

     public static void main(String[] args) throws Exception {
          F f = new F();
          f.setGui();
          f.pack();
          f.setVisible(true);
     }

}
>> and found the width of each button was different.
Told you
Replace
         panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
with
         panel.setLayout(new GridLayout(0,1));
Sorry, then the sizing isn't OK.

Try this:

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

public class F extends JFrame{

     JButton button1, button2, button3, button4, button5;  

     private void setGui() {
          JPanel panel = new JPanel();
          panel.setLayout(new GridLayout(0,1));
          panel.add(button1 = new JButton("Ten"));
          panel.add(button2 = new JButton("Eleven"));
          panel.add(button3 =  new JButton("Twelve"));
          panel.add(button4 = new JButton("Thirteen"));
          panel.add(button5 = new JButton("Fourteen"));

          JPanel panel2 = new JPanel();
          panel2.add(panel);
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          getContentPane().add(panel2, BorderLayout.CENTER);
     }

     public static void main(String[] args) throws Exception {
          F f = new F();
          f.setGui();
          f.pack();
          f.setVisible(true);
     }

}
Yes I can see using 2 panels corrects this.

I was just concerned about from 2 panels each time, rather than 1.

Its a shame I could not use the BoxLayout, I thought this was sun's solution to use 1 panel.

Would you recommand here again to use two panels, to stop textfield and buttons from stretching when the frame is maximised?

JPanel secPanel = new JPanel(new GridLayout(0,2,15,10));
secPanel.add(new JLabel("Some Text"));
secPanel.add(searchTf = new JTextField(20));
secPanel.add(searchBt = new JButton("Search"));
searchBt.addActionListener(this);

Thanks
Ho, ho. Wait a minute!

If you don't want that stretching, why do you use the BorderLayout?

This works:

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

public class F extends JFrame{

     JButton button1, button2, button3, button4, button5;  

     private void setGui() {
             JPanel secPanel = new JPanel(new GridLayout(0,2,15,10));
             secPanel.add(new JLabel("Some Text"));
             secPanel.add(new JTextField(20));
             secPanel.add(new JButton("Search"));
         
             setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             getContentPane().setLayout(new FlowLayout());              // <<<<<<<< set FlowLayout !!! (instead of the default BorderLayout for JFrame's)
             getContentPane().add(secPanel);
     }

     public static void main(String[] args) throws Exception {
          F f = new F();
          f.setGui();
          f.pack();
          f.setVisible(true);
     }

}
And the one panel solution for the previous is:

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

public class F extends JFrame{

     JButton button1, button2, button3, button4, button5;  

     private void setGui() {
          JPanel panel = new JPanel();
          panel.setLayout(new GridLayout(0,1));
          panel.add(button1 = new JButton("Ten"));
          panel.add(button2 = new JButton("Eleven"));
          panel.add(button3 =  new JButton("Twelve"));
          panel.add(button4 = new JButton("Thirteen"));
          panel.add(button5 = new JButton("Fourteen"));

          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          getContentPane().setLayout(new FlowLayout());
          getContentPane().add(panel);
     }

     public static void main(String[] args) throws Exception {
          F f = new F();
          f.setGui();
          f.pack();
          f.setVisible(true);
     }
}

Important to remember:
- the default layout of a JPanel is FlowLayout(FlowLayout.CENTER)
- the default layout of a JFrame's content pane is BorderLayout
And if you really want to use the BoxLayout (which is somewhat "unnatural" if you want the buttons to have the same size)
apparently you have to set the maximum size:


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

public class F extends JFrame{

     JButton button1, button2, button3, button4, button5;  

     private void setGui() {
          JPanel panel = new JPanel();
          panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
          panel.add(button1 = new JButton("Ten"));
          panel.add(button2 = new JButton("Eleven"));
          panel.add(button3 =  new JButton("Twelve"));
          panel.add(button4 = new JButton("Thirteen"));
          panel.add(button5 = new JButton("Fourteen"));
          Dimension d = new Dimension(100, 25);
          button1.setMaximumSize(d);
          button2.setMaximumSize(d);
          button3.setMaximumSize(d);
          button4.setMaximumSize(d);
          button5.setMaximumSize(d);

          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          getContentPane().setLayout(new FlowLayout());
          getContentPane().add(panel);
     }

     public static void main(String[] args) throws Exception {
          F f = new F();
          f.setGui();
          f.pack();
          f.setVisible(true);
     }

}
So, I think you have enough alternatives to choose from
 ;°)
Thanks

I will look through all the examples, I feel happy using the 2 panels to create a constant width in the column of buttons.

I will just need to look over the other code.

I will reply tomorrow, its 10.30pm here:)
>> I will reply tomorrow, its 10.30pm here:)
OK.

(Here it's midnight ;°)
Hi Antoni,
What about this one?
Hello,

I tried this code, which displays the column of buttons with even widths, which is great.

The problem is with this secPanel, I was hoping to display the column of buttons of the left and this panel on the right. With these two next to each other. And when the frame is maximised the buttons, textfields and labels do not stretch.

I wondered if I should be using the Box manager Box.createHorizontalBox(); to display the button panel on the left and secPanel on the right?

Thanks                

JPanel secPanel = new JPanel(new GridLayout(0,2,15,10));
secPanel.add(new JLabel("Some Text"));
secPanel.add(new JTextField(15));
secPanel.add(new JButton("Search"));

import com.sun.java.swing.*;
import java.awt.*;

public class F extends JFrame{

     JButton button1, button2, button3, button4, button5;  

     private void setGui() {
          JPanel panel = new JPanel();
          panel.setLayout(new GridLayout(0,1));
          panel.add(button1 = new JButton("Ten"));
          panel.add(button2 = new JButton("Eleven"));
          panel.add(button3 =  new JButton("Twelve"));
          panel.add(button4 = new JButton("Thirteen"));
          panel.add(button5 = new JButton("Fourteen"));
         
          getContentPane().setLayout(new FlowLayout());
          getContentPane().add(panel);
     }

     public static void main(String[] args) throws Exception {
          F f = new F();
          f.setGui();
          f.pack();
          f.setVisible(true);
     }
}
ASKER CERTIFIED SOLUTION
Avatar of zzynx
zzynx
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks again,

To display a JTextArea under the two panels, and a medium sizeed label above the panels could I also use the flowLayout?

Or would your recommend using the gridbaglayout?

Don't think so.
What layout you use depends on the behaviour you want when resizing.
What do you want the text area to do? Fill all the available space under the two panels?
What do you mean by a "medium sized label"?
Hello,

The jtextarea is declared as JTextArea text = new JTextArea(2,30);

At the moment I have not added the textarea to a jpanel, I thought this was the correct approach.

I was hoping the textarea would be displayed under the two panels at its defined size, even when the frame is maximised.

And display above the two jpanels a label, about the size of the textarea, so not that big.

I have used the gridbaylayout before, I found it quite difficult to use and wondered if the panels, textarea would stretch when the frame is maximised?

Thanks
>> I have used the gridbaylayout before, I found it quite difficult to use
Once you got it, it isn't. Imo the clue is: just consider it as a matrix.
>> and wondered if the panels, textarea would stretch when the frame is maximised?
No. In a GBL all components take their preferred sizes.

I feel like reading http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html would be a good thing for you.