2

Please have a look the following code

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

public class GUI extends JFrame
{
    private JButton open, process;
    private JLabel center;
    private JScrollPane scroll;
    private Box box;
    private IplImage image;

    public FirstGUI()
    {
        open = new JButton("Open Image");
        open.setPreferredSize(new Dimension(70,20));
        open.setMaximumSize(new Dimension(100,20));

        open.addActionListener(new OpenImageAction());
        process = new JButton("Process");
        process.setPreferredSize(new Dimension(100,20));
        process.setMinimumSize(new Dimension(100,20));
        process.addActionListener(new ProcessAction());
        System.out.println("Open Size: "+open.getSize()+"      Process size: "+process.getSize());


        box = new Box(BoxLayout.Y_AXIS);
        box.add(open);
        box.add(process);

        center = new JLabel();
        scroll = new JScrollPane(center);

        getContentPane().add(box,"West");
        getContentPane().add(scroll,"Center");

        this.setSize(300,300);
        this.pack();
        this.validate();
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    public static void main(String[]args)
    {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

            new GUI();
        }
        catch(java.lang.Exception e)
        {
            JOptionPane.showMessageDialog(null,"GUI Error");
        }
    }

I want to make all the buttons in same size. In here, first one is wider than the second one. I need same width ans hight for both. As you can see, I have used all the availables like setPrefferedSize(), setMaximumSize(), setMinimumSize(), but it is still not working properly. Please help!

PeakGen
  • 21,894
  • 86
  • 261
  • 463
  • What do you expect to happen if the frame is resized? Should the buttons also be resized in the west panel or should they can be the same size and remain: at the top, in the middle, at the bottom? – Guillaume Polet Jul 18 '12 at 07:23
  • buttons keep in the same size whether it is rezied or not. Buttons need not to be resized when the frame does. Thats what I need. But hey, I like to learn that resize part too :) – PeakGen Jul 18 '12 at 07:26

4 Answers4

9

Here is one way to achieve this using a GridLayout. I also introduced an additional JPanel so that the buttons are not stretched when the JFrame is resized and I chose the GridBagLayout for it so that it will center the button panel vertically. There are definitely other ways to solve your issue.

One thing you should try to avoid is to force preferred/maximum/minimum sizes. Delegate this to the L&F and the LayoutMananager's.

If you call pack() on a JFrame, it is useless to set its size previously, as pack() will change that anyway. Try to make the call to setVisible(true); the last line of your GUI initialization.

If you want to understand properly how layout, positioning, sizing, etc... works in Swing, I would strongly recommend to read the tutorial on LayoutManager's.

import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class GUI extends JFrame {
    private JButton open, process;
    private JLabel center;
    private JScrollPane scroll;
    private JPanel box;

    public GUI() {
        open = new JButton("Open Image");
        // open.addActionListener(new OpenImageAction());
        process = new JButton("Process");
        // process.addActionListener(new ProcessAction());

        box = new JPanel(new GridLayout(2, 1));
        box.add(open);
        box.add(process);
        JPanel west = new JPanel(new GridBagLayout());
        west.add(box);

        center = new JLabel("Some center label");
        scroll = new JScrollPane(center);

        getContentPane().add(west, BorderLayout.WEST);
        getContentPane().add(scroll);

        this.pack();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (java.lang.Exception e) {
            JOptionPane.showMessageDialog(null, "GUI Error");
        }
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new GUI();
            }
        });
    }
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • @Yohan: Note that the word _size_ appears in neither `GUI`, above, nor [`ButtonTest`](http://stackoverflow.com/a/3420431/230513). See also this [Q&a](http://stackoverflow.com/q/7229226/230513). – trashgod Jul 18 '12 at 19:26
2

You could create your own layout manager that calculates the max size of all the buttons (probably from the preferred size values) and basically assign the same size (via setSize). You'd of course have to provide positional information as well, but this gives the advantage of providing vertical & horizontal layout options

UPDATE

This is the implementation I use, I take no credit for it, as you can see it was authored by Santhosh Kumar. I find it very useful as it not only sizes all the buttons to the same size, but also provides alignment as well. You can find the original post here http://www.jroller.com/santhosh/entry/how_do_you_layout_command

/**
* @author Santhosh Kumar - santhosh@in.fiorano.com
*/
public class ButtonLayout implements LayoutManager, SwingConstants {

    protected static Logger logger = Logger.getLogger(ButtonLayout.class);

    private int gap;
    private int alignment;

    public ButtonLayout() {

        setAlignment(RIGHT);
        setGap(2);

    }

    public ButtonLayout(int alignment, int gap) {
        setGap(gap);
        setAlignment(alignment);
    }

    public ButtonLayout(int gap) {
        this(RIGHT, gap);
    }

    public int getAlignment() {
        return alignment;
    }

    public void setAlignment(int alignment) {
        this.alignment = alignment;
    }

    public int getGap() {
        return gap;
    }

    public void setGap(int gap) {
        this.gap = gap;
    }

    private Dimension[] dimensions(Component children[]) {
        int maxWidth = 0;
        int maxHeight = 0;
        int visibleCount = 0;
        Dimension componentPreferredSize;

        for (int i = 0, c = children.length; i < c; i++) {

            if (children[i].isVisible()) {

                componentPreferredSize = children[i].getPreferredSize();
                maxWidth = Math.max(maxWidth, componentPreferredSize.width);
                maxHeight = Math.max(maxHeight, componentPreferredSize.height);
                visibleCount++;

            }

        }

        int usedWidth = 0;
        int usedHeight = 0;

        switch (alignment) {

            case LEFT:
            case RIGHT:
                usedWidth = maxWidth * visibleCount + gap * (visibleCount - 1);
                usedHeight = maxHeight;
                break;

            case TOP:
            case BOTTOM:
                usedWidth = maxWidth;
                usedHeight = maxHeight * visibleCount + gap * (visibleCount - 1);
                break;

        }

        return new Dimension[]{
                            new Dimension(maxWidth, maxHeight),
                            new Dimension(usedWidth, usedHeight),};
    }

    public void layoutContainer(Container container) {

        Insets insets = container.getInsets();
        int width = container.getWidth() - (insets.left + insets.right);
        int height = container.getHeight() - (insets.top + insets.bottom);

        Component[] children = container.getComponents();
        Dimension dim[] = dimensions(children);

        int maxWidth = dim[0].width;
        int maxHeight = dim[0].height;
        int usedWidth = dim[1].width;
        int usedHeight = dim[1].height;

        for (int i = 0, c = children.length; i < c; i++) {

            if (children[i].isVisible()) {

                switch (alignment) {
                    case LEFT:
                        children[i].setBounds(
                                        insets.left + (maxWidth + gap) * i,
                                        insets.top,
                                        maxWidth,
                                        maxHeight);
                        break;
                    case TOP:
                        children[i].setBounds(
                                        insets.left + ((width - maxWidth) / 2),
                                        insets.top + (maxHeight + gap) * i,
                                        maxWidth,
                                        maxHeight);
                        break;
                    case RIGHT:
                        children[i].setBounds(
                                        width - insets.right - usedWidth + (maxWidth + gap) * i,
                                        insets.top,
                                        maxWidth,
                                        maxHeight);
                        break;
                    case BOTTOM:
                        children[i].setBounds(
                                        insets.left + (maxWidth + gap) * i,
                                        height - insets.bottom - usedHeight + (maxHeight + gap) * i,
//                                      insets.top,
                                        maxWidth,
                                        maxHeight);
                        break;
                }

            }

        }

    }

    public Dimension minimumLayoutSize(Container c) {
        return preferredLayoutSize(c);
    }

    public Dimension preferredLayoutSize(Container container) {

        Insets insets = container.getInsets();

        Component[] children = container.getComponents();
        Dimension dim[] = dimensions(children);

        int usedWidth = dim[1].width;
        int usedHeight = dim[1].height;

        return new Dimension(
                        insets.left + usedWidth + insets.right,
                        insets.top + usedHeight + insets.bottom);
    }

    public void addLayoutComponent(String string, Component comp) {
    }

    public void removeLayoutComponent(Component c) {
    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
-1
  1. Set same dimension for both buttons.
  2. Set maximum and minimum size for both buttons. Now it's only maximum for first and minimum for second. It'll work.
Ictis
  • 1
-2

maybe it because the dimension is not the same for the setPreferredSize() ?

    open.setPreferredSize(new Dimension(70,20));

    process.setPreferredSize(new Dimension(100,20));
Michaël
  • 13
  • 1
  • 4