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);
n开发者_运维问答ewButton.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?
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);
}
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.
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))
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.
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);
}
}
精彩评论