Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to align swing buttons vertically ?

1,483 views
Skip to first unread message

Olivier Scalbert

unread,
Nov 13, 2011, 5:30:40 AM11/13/11
to
Hello !

I want to create a swing application with a main frame and a panel
containing vertically aligned buttons at the right side. Here is the code:

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

public class TestViewer {

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new ViewerFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setVisible(true);
}
});
}
}

class ViewerFrame extends JFrame {

public ViewerFrame() {
getContentPane().add(new JPanel(), BorderLayout.CENTER);
getContentPane().add(createBtnPanel(), BorderLayout.EAST);
}

private JPanel createBtnPanel() {
JPanel btnPanel = new JPanel();

btnPanel.setLayout(new GridLayout(0, 1));

btnPanel.add(new JButton("Button 1"));
btnPanel.add(new JButton("Button 2"));
btnPanel.add(new JButton("Long Button 3"));
btnPanel.add(new JButton("Button 4"));
btnPanel.add(new JButton("Button 5"));

// Trick here !
// I put the btnPanel at the NORTH of a "dummy" panel to have
// the correct button sizes !!!
// Other solutions ??
JPanel dummyPanel = new JPanel();
dummyPanel.setLayout(new BorderLayout());
dummyPanel.add(btnPanel, BorderLayout.NORTH);

return dummyPanel;
}
}

It works, but is there an other way to avoid the dummyPanel trick ?

Thanks a lot !

Olivier

Martin Gregorie

unread,
Nov 13, 2011, 7:50:40 AM11/13/11
to
On Sun, 13 Nov 2011 11:30:40 +0100, Olivier Scalbert wrote:

> It works, but is there an other way to avoid the dummyPanel trick ?
>
Use a BoxLayout specifying the axis as Y-AXIS.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

Olivier Scalbert

unread,
Nov 13, 2011, 8:21:55 AM11/13/11
to
On 11/13/2011 01:50 PM, Martin Gregorie wrote:
> Use a BoxLayout specifying the axis as Y-AXIS.
>
>
Thanks !
But with the BoxLayout they are aligned but they have not the same size!

Martin Gregorie

unread,
Nov 13, 2011, 9:38:42 AM11/13/11
to
That's nothing to do with the layout. It aligns the objects you're laying
out by doing its best with the sizes of the objects you created.

JButton inherits size setting methods (setMaximumSize, setMinimumSize,
setPreferredSize) from JComponent. Use them to control button size.

Roedy Green

unread,
Nov 13, 2011, 12:27:50 PM11/13/11
to
On Sun, 13 Nov 2011 11:30:40 +0100, Olivier Scalbert
<olivier....@algosyn.com> wrote, quoted or indirectly quoted
someone who said :

>I want to create a swing application with a main frame and a panel
>containing vertically aligned buttons at the right side. Here is the code:

How Components align is decided by the Layout Manager. It might take
clues from fields in the Components, or it may not. Usually when you
start having trouble intimidating your LayoutManager into ever higher
levels of aesthetic perfection, it is time for a more advanced
LayoutManager, or cannibalising ideas from other users of your current
LayoutManager. It is amazing how much source code you can find with
Google with some package, class or method names.


See http://mindprod.com/jgloss/layout.html
--
Roedy Green Canadian Mind Products
http://mindprod.com
I can't come to bed just yet. Somebody is wrong on the Internet.

Olivier Scalbert

unread,
Nov 13, 2011, 12:28:44 PM11/13/11
to
On 11/13/2011 03:38 PM, Martin Gregorie wrote:
> That's nothing to do with the layout. It aligns the objects you're laying
> out by doing its best with the sizes of the objects you created.
>
> JButton inherits size setting methods (setMaximumSize, setMinimumSize,
> setPreferredSize) from JComponent. Use them to control button size.
>
>
>

Perhaps I have not understand, but with the following code, buttons are
not well aligned:

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

public class TestViewer {

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new ViewerFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setVisible(true);
}
});
}
}

class ViewerFrame extends JFrame {

public ViewerFrame() {
getContentPane().add(new JPanel(), BorderLayout.CENTER);
getContentPane().add(createBtnPanel(), BorderLayout.EAST);
}

private JPanel createBtnPanel() {
JPanel btnPanel = new JPanel();

btnPanel.setLayout(new BoxLayout(btnPanel, BoxLayout.Y_AXIS));

btnPanel.add(new JButton("Button 1"));
btnPanel.add(new JButton("Button 2"));
btnPanel.add(new JButton("Long Button 3"));
btnPanel.add(new JButton("Button 4"));
btnPanel.add(new JButton("Button 5"));

return btnPanel;
}
}

Olivier

Knute Johnson

unread,
Nov 13, 2011, 2:01:24 PM11/13/11
to
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
public test() {
super(new GridBagLayout());

GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridy = 0;

String labels[] = {"Button 1","Button 2",
"Long Button 3","Button 4","Button 5"};

for (int i=0; i<labels.length; i++) {
add(new JButton(labels[i]),c);
++c.gridy;
}
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new test(),BorderLayout.EAST);
f.setSize(700,500);
f.setVisible(true);
}
});
}
}

--

Knute Johnson

Martin Gregorie

unread,
Nov 13, 2011, 2:17:31 PM11/13/11
to
On Sun, 13 Nov 2011 18:28:44 +0100, Olivier Scalbert wrote:

> On 11/13/2011 03:38 PM, Martin Gregorie wrote:
>> That's nothing to do with the layout. It aligns the objects you're
>> laying out by doing its best with the sizes of the objects you created.
>>
>> JButton inherits size setting methods (setMaximumSize, setMinimumSize,
>> setPreferredSize) from JComponent. Use them to control button size.
>>
> Perhaps I have not understand, but with the following code, buttons are
> not well aligned:
>
They aligned as I'd expect:
- btnPanel is sized to contain the buttons and nothing else
and is placed as you asked, on the east side of the content pane.

- The buttons have their centres aligned.

I don't understand what you mean by "not well aligned":

- If you want the buttons to appear as other than a close-packed block,
take a look at "How to use BoxLayout" in the Java tutorial. It is also
referenced from the the class description in the BoxLayout javadocs
entry.

- If you want all buttons to be the same size, use a custom class in
place of JButton:

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

class MyButton extends JButton
{

public MyButton(String label)
{
super(label);

Dimension d = new Dimension(120, 30);
setMinimumSize(d);
setMaximumSize(d);
setPreferredSize(d);

Lew

unread,
Nov 13, 2011, 2:03:39 PM11/13/11
to
Olivier Scalbert wrote:
> Perhaps I have not understand, but with the following code, buttons are
> not well aligned:
>
> import java.awt.*;
> import javax.swing.*;
>
> public class TestViewer {
>
> public static void main(String[] args) {
> EventQueue.invokeLater(new Runnable() {
> public void run() {
> JFrame frame = new ViewerFrame();
> frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
> frame.setSize(800, 600);

Shouldn't you call 'pack()' right here? Layouts often don't work well without it.

> frame.setVisible(true);
> }
> });
> }
> }
>
> class ViewerFrame extends JFrame {
>
> public ViewerFrame() {
> getContentPane().add(new JPanel(), BorderLayout.CENTER);
> getContentPane().add(createBtnPanel(), BorderLayout.EAST);
> }
>
> private JPanel createBtnPanel() {
> JPanel btnPanel = new JPanel();
>
> btnPanel.setLayout(new BoxLayout(btnPanel, BoxLayout.Y_AXIS));
>
> btnPanel.add(new JButton("Button 1"));
> btnPanel.add(new JButton("Button 2"));
> btnPanel.add(new JButton("Long Button 3"));
> btnPanel.add(new JButton("Button 4"));
> btnPanel.add(new JButton("Button 5"));
>
> return btnPanel;
> }
> }

--
Lew

Olivier Scalbert

unread,
Nov 13, 2011, 3:01:23 PM11/13/11
to
On 11/13/2011 08:17 PM, Martin Gregorie wrote:

> They aligned as I'd expect:
> - btnPanel is sized to contain the buttons and nothing else
> and is placed as you asked, on the east side of the content pane.
>
> - The buttons have their centres aligned.
>
> I don't understand what you mean by "not well aligned":
>
> - If you want the buttons to appear as other than a close-packed block,
> take a look at "How to use BoxLayout" in the Java tutorial. It is also
> referenced from the the class description in the BoxLayout javadocs
> entry.
>
> - If you want all buttons to be the same size, use a custom class in
> place of JButton:
>
> import java.awt.*;
> import javax.swing.*;
>
> class MyButton extends JButton
> {
>
> public MyButton(String label)
> {
> super(label);
>
> Dimension d = new Dimension(120, 30);
> setMinimumSize(d);
> setMaximumSize(d);
> setPreferredSize(d);
> }
> }
>
>

Hi,

With "my version", I have (at least on my machine):
-----------------
| button 1 |
-----------------
| button 2 |
-----------------
| Long Button 3 |
-----------------
| button 4 |
-----------------
| button 5 |
-----------------

With "yours" (at least the one I post with the BoxLayout):

------------
| button 1 |
------------
| button 2 |
-----------------
| Long Button 3 |
-----------------
| button 4 |
------------
| button 5 |
------------

Olivier Scalbert

unread,
Nov 13, 2011, 3:17:17 PM11/13/11
to
On 11/13/2011 08:01 PM, Knute Johnson wrote:
>
> import java.awt.*;
> import java.awt.event.*;
> import javax.swing.*;
>
> public class test extends JPanel {
> public test() {
> super(new GridBagLayout());
>
> GridBagConstraints c = new GridBagConstraints();
> c.fill = GridBagConstraints.HORIZONTAL;
> c.gridy = 0;
>
> String labels[] = {"Button 1","Button 2",
> "Long Button 3","Button 4","Button 5"};
>
> for (int i=0; i<labels.length; i++) {
> add(new JButton(labels[i]),c);
> ++c.gridy;
> }
> }
>
> public static void main(String[] args) {
> EventQueue.invokeLater(new Runnable() {
> public void run() {
> JFrame f = new JFrame();
> f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
> f.add(new test(),BorderLayout.EAST);
> f.setSize(700,500);
> f.setVisible(true);
> }
> });
> }
> }
>
Ok, all the buttons have the same size and are aligned ! When I resize
the main frame, the group of buttons is in the EAST part but in the
middle of the frame height. Is it possible the have this group on top
(of the EAST part) ?

John B. Matthews

unread,
Nov 13, 2011, 5:33:13 PM11/13/11
to
In article <4ec02213$0$5039$ba62...@news.skynet.be>,
Lew is correct about using pack(), and I'm with Martin on BoxLayout.
One problem with using setXXXSize is that the values statically replace
those computed by the component's Look & Feel. Instead override just
the one needed by BoxLayout to make the buttons "as wide as their
container."

<http://download.oracle.com/javase/tutorial/uiswing/layout/box.html>

As an aside, your center panel contains no components, so it would
pack() to the L&F's minimum. I've given it an arbitrary size by
overriding getPreferredSize(), but setPreferredSize() would do as well
for the fixed value.

I defer to Knute on GridBagLayout.

Here's an <http://sscce.org/>:

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

public class TestViewer {

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
JFrame frame = new ViewerFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

class ViewerFrame extends JFrame {

public ViewerFrame() {
// a panel of aribtrary size
this.add(new JPanel() {

@Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
}, BorderLayout.CENTER);
this.add(createBtnPanel(), BorderLayout.EAST);
}

private JPanel createBtnPanel() {
JPanel btnPanel = new JPanel();
btnPanel.setLayout(new BoxLayout(btnPanel, BoxLayout.Y_AXIS));
btnPanel.add(createButton("Button 1"));
btnPanel.add(createButton("Button 2"));
btnPanel.add(createButton("Long Button 3"));
btnPanel.add(createButton("Button 4"));
btnPanel.add(createButton("Button 5"));
return btnPanel;
}

private JButton createButton(String name) {
final JButton b = new JButton(name) {

@Override
public Dimension getMaximumSize() {
return new Dimension(
Short.MAX_VALUE, getPreferredSize().height);
}
};
b.setAlignmentX(0.5f);
return b;
}
}

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Knute Johnson

unread,
Nov 13, 2011, 7:16:13 PM11/13/11
to
On 11/13/2011 12:17 PM, Olivier Scalbert wrote:
> On 11/13/2011 08:01 PM, Knute Johnson wrote:
>>
>> import java.awt.*;
>> import java.awt.event.*;
>> import javax.swing.*;
>>
>> public class test extends JPanel {
>> public test() {
>> super(new GridBagLayout());
>>
>> GridBagConstraints c = new GridBagConstraints();
>> c.fill = GridBagConstraints.HORIZONTAL;
>> c.gridy = 0;
>>
>> String labels[] = {"Button 1","Button 2",
>> "Long Button 3","Button 4","Button 5"};
>>
>> for (int i=0; i<labels.length; i++) {

if (i == labels.length - 1) { // last label
// anchor last button to north and give it
// a weighty of 1.0. this will tell that
// button to take all remaining vertical
// space and will push all the other
// buttons to top of the container
c.anchor = GridBagConstraints.NORTH;
c.weighty = 1.0
}

>> add(new JButton(labels[i]),c);
>> ++c.gridy;
>> }
>> }
>>
>> public static void main(String[] args) {
>> EventQueue.invokeLater(new Runnable() {
>> public void run() {
>> JFrame f = new JFrame();
>> f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>> f.add(new test(),BorderLayout.EAST);
>> f.setSize(700,500);
>> f.setVisible(true);
>> }
>> });
>> }
>> }
>>
> Ok, all the buttons have the same size and are aligned ! When I resize
> the main frame, the group of buttons is in the EAST part but in the
> middle of the frame height. Is it possible the have this group on top
> (of the EAST part) ?


--

Knute Johnson

Knute Johnson

unread,
Nov 13, 2011, 7:28:05 PM11/13/11
to
On 11/13/2011 11:03 AM, Lew wrote:
> Olivier Scalbert wrote:
>> Perhaps I have not understand, but with the following code, buttons are
>> not well aligned:
>>
>> import java.awt.*;
>> import javax.swing.*;
>>
>> public class TestViewer {
>>
>> public static void main(String[] args) {
>> EventQueue.invokeLater(new Runnable() {
>> public void run() {
>> JFrame frame = new ViewerFrame();
>> frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>> frame.setSize(800, 600);
>
> Shouldn't you call 'pack()' right here? Layouts often don't work well without it.

The OP created a pretty good SSCCE here and for that purpose pack()
would not demonstrate what he wanted to show. The only possible problem
he would have with the LayoutManager is too little space to display his
example. Most of the time, having extra space in a frame isn't going to
cause any display problems. I think he can be forgiven for not packing
this time (as I hope I can for my example :-).

--

Knute Johnson
0 new messages