rookie
rookie

Reputation: 7843

alignment in swing

public class Some extends JFrame{
    public Some(){
        //Create panel for the buttons and set Grid Layout
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(20, 20));

        //Add buttons to the panel
        for(int i = 1; i <= 20; i++){
            for(int j = 1; j <= 20; j++){
                JButton newButton = new JButton();
                newButton.setSize(10,10);
                newButton.setBackground(Color.WHITE);
                p1.add(newButton);
            }
        }

        //add contents into the frame
        add(p1);
    }

my question is how can I force my panel p1 to stretch all over my frame, for example I have some gaps now using this class, thanks in advance

Edited in my main I use method

frame.setSize(400, 400);

may it be the problem?

Upvotes: 1

Views: 907

Answers (5)

Manidip Sengupta
Manidip Sengupta

Reputation: 3611

Two points:

[1] On JFrame, you add stuff to its getContentPane(), a Container.

[2] Either (a) setPreferredSize() of the JButton's (use new Dimension()) and pack() the JFrame, or (b) setSize(Dimension) for the JFrame and let the LayoutManager size the JButtons. Using your approach (a), the code looks like the following (I added a main() to have it compile/run)

Sorry, I cannot get the formatting/indentations to work properly :(

import java.awt.*;

import javax.swing.*;

public class Some extends JFrame{     

    public Some(){         
        //Create panel for the buttons and set Grid Layout         
        JPanel p1 = new JPanel();         

        p1.setLayout(new GridLayout(20, 20));  //Add buttons to the panel

        for(int i = 1; i <= 20; i++){
            for(int j = 1; j <= 20; j++){
                JButton newButton = new JButton();
                newButton.setPreferredSize(new Dimension (10,10));
                newButton.setBackground(Color.WHITE);
                p1.add(newButton);
        }}

        //add contents into the frame
        getContentPane().add(p1);

        pack();
    } 

    public static void main (String[] args) {
        new Some().setVisible(true);
    }
}

Upvotes: 0

Russ Hayward
Russ Hayward

Reputation: 5667

The problem is that GridLayout ensures all components are the same size. This means that the width and height of the panel (p1) must be multiples of 20 for the components to reach the edge. You can either ensure that the panel is a fixed size, like this (at the end of the constructor):

setResizable(false);
p1.setPreferredSize(new Dimension(400, 400));
add(p1);
pack();

Your call to frame.setSize(...) did not make the panel 400 by 400 because the frame size includes the border around the frame.

Alternatively you can use a custom layout manager that does not guarantee that all the buttons are exactly the same size. This example will make the buttons fill the entire area of the panel:

private static class FullyJustifiedGridLayout implements LayoutManager {
    private final int rows;
    private final int columns;

    public FullyJustifiedGridLayout(int rows, int columns) {
        this.rows = rows;
        this.columns = columns;
    }

    @Override
    public void layoutContainer(Container parent) {
        synchronized (parent.getTreeLock()) {
            double clientWidth = parent.getWidth() - parent.getInsets().left - parent.getInsets().right; 
            double clientHeight = parent.getHeight() - parent.getInsets().top - parent.getInsets().bottom; 
            for (int i = 0; i < parent.getComponents().length; i++) {
                Component component = parent.getComponents()[i];
                int row = i / rows, column = i % columns;
                int x = (int)(clientWidth * column / columns);
                int y = (int)(clientHeight * row / rows);
                int nextX = (int)(clientWidth * (column + 1) / columns);
                int nextY = (int)(clientHeight * (row + 1) / rows);
                component.setBounds(x, y, nextX - x, nextY - y);
            }
        }
    }

    @Override
    public Dimension minimumLayoutSize(Container parent) {
        return new Dimension(20 * 10, 20 * 10);
    }

    @Override
    public Dimension preferredLayoutSize(Container parent) {
        return new Dimension(20 * 20, 20 * 20);
    }

    @Override
    public void removeLayoutComponent(Component comp) {
    }

    @Override
    public void addLayoutComponent(String name, Component comp) {
    }
}

Simply replace your call to new GridLayout(20, 20) with new FullyJustifiedGridLayout(20, 20).

Additionally, when you are using layout managers there is no need to call setSize, setLocation or setBounds on components - they are called by the layout manager when it lays out the panel. If you want to change sizes of components use setPreferredSize instead.

Upvotes: 0

camickr
camickr

Reputation: 324078

newButton.setSize(10,10);

frame.setSize(400, 400); may it be the problem?

You attempt to set the size to be 10 pixels and you have 20 components so why would you set the size to 400? 200 would be a closer guess, although it would still be wrong (because you need to allow space for the borders of the frame).

Outside of you loop you should create a variable:

Dimension preferred = new Dimension(10, 10);

Then inside you loop you should use:

newButton.setPreferredSize( preferred );

Then you can use:

//frame.setSize(400, 400);
frame.setResizeable(false);
frame.pack();

The frame will size itself to be the proper size so that there is no extra space.

Upvotes: 0

davmac
davmac

Reputation: 20631

It depends largely on the layout manager of the frame, but in general you should set the maximum size of the panel to (Integer.MAX_VALUE, Integer.MAX_VALUE) to allow it to stretch:

p1.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE))

Upvotes: 0

Dsynomic
Dsynomic

Reputation: 29

The easiest way is to set your layout to a BorderLayout, and then insert your panel into the center.

public class Some extends JFrame{
   public Some(){
    //Create panel for the buttons and set Grid Layout
    JPanel p1 = new JPanel();
    p1.setLayout(new GridLayout(20, 20));

    //Add buttons to the panel
    for(int i = 1; i <= 20; i++){
        for(int j = 1; j <= 20; j++){
            JButton newButton = new JButton();
            newButton.setSize(10,10);
            newButton.setBackground(Color.WHITE);
            p1.add(newButton);
        }
    }

    //add contents into the frame
    this.setLayout(new BorderLayout());
    add(p1, BorderLayout.CENTER);
}

Upvotes: 1

Related Questions