Java,与Gridlayout有关的问题。难以放置组件

时间:2014-05-01 09:17:46

标签: java swing layout-manager grid-layout

我认为GridLayout存在问题。 我试着在Jpanel" lightJpanel"上放置25个按钮。但是所有按钮都只在我的lightJpanel左上角的一个按钮上。我尝试了很多东西,但我找不到问题...... 按钮已创建,但它们不可见。 解决问题的解决方案?

这是我的代码当前给我的信息:

enter image description here

这是我的代码:

public class Window extends JFrame {

    /**
     * Main JPanel
     */
    private JPanel container = new JPanel();
    /**
     * Message area
     */
    private JLabel screen = new JLabel();
    /**
     * table light
     */
    private Light light[][] = new Light[5][5];
    /**
     * button who allows to configure the start of game
     */
    private JButton configure = new JButton("Configure the lights");
    /**
     * button who allows to start the game
     */
    private JButton play = new JButton("Play");
    /**
     * button who allows to place random lights
     */
    private JButton random = new JButton("Random configuration");
    /**
     * stop button for stop the game
     */
    private JButton stop = new JButton("Stop");


    /**
     * construct a window
     *
     * @param controller the controller of the window
     */
    public Window() {
        this.setSize(500, 500);
        this.setTitle("Game of life");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setResizable(false);
        initComponents();
        this.setContentPane(container);
        this.setVisible(true);
    }

    /**
     * Initialization of graphical components
     */
    private void initComponents() {

        //for the message
        Font font = new Font("Arial", Font.BOLD, 20);
        screen = new JLabel("Game of life");
        screen.setFont(font);
        screen.setForeground(Color.white);

        JPanel panScreen = new JPanel();
        panScreen.setPreferredSize(new Dimension(480, 40));

        JPanel menuButton = new JPanel();
        menuButton.setPreferredSize(new Dimension(480, 100));

        JPanel lightJpanel = new JPanel();
        lightJpanel.setPreferredSize(new Dimension(300, 300));

        //listeners for menu buttons
        MenuListener menuListener = new MenuListener();

        lightJpanel.setLayout(new GridLayout(5, 5, 0, 0));

        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                light[i][j] = new Light(i, j);
                lightJpanel.add(light[i][j]);
            }
        }

        //size button
        stop.setPreferredSize(new Dimension(70, 40));
        play.setPreferredSize(new Dimension(70, 40));
        random.setPreferredSize(new Dimension(200, 40));
        configure.setPreferredSize(new Dimension(200, 40));

        //add listener
        play.addActionListener(menuListener);
        random.addActionListener(menuListener);
        configure.addActionListener(menuListener);
        stop.addActionListener(menuListener);

        //add buttons to JPanel menuButton
        menuButton.add(configure);
        menuButton.add(random);
        menuButton.add(play);
        menuButton.add(stop);

        stop.setEnabled(false);

        //decoration JLabel screen
        panScreen.add(screen);
        panScreen.setBackground(Color.blue);
        panScreen.setBorder(new javax.swing.border.BevelBorder(BevelBorder.RAISED));
        Border borderLine = BorderFactory.createLineBorder(Color.BLACK);
        panScreen.setBorder(borderLine);

        //test jpanel
        lightJpanel.setBackground(Color.CYAN);
        menuButton.setBackground(Color.black);
        container.setBackground(Color.green);

        //positioning different JPanel to main JPanel
        container.add(panScreen);
        container.add(menuButton);
        container.add(lightJpanel);
    }

这是我的Light类:

    import java.awt.Color;

    import javax.swing.JButton;

public class Light extends JButton{

    /**
     * coordonates of the light according to the GridLayout
     */
    private int x;
    /**
     * coordonates of the light according to the GridLayout
     */
    private int y;
    /**
     * define if the light is lit or not
     */
    private boolean lit;

    /**
     * construct a light
     * @param abs the abscissa of the light
     * @param ord the ordered of the light
     */
    public Light(int abs, int ord){
        super();
        this.x = abs;
        this.y = ord;
        // Default color
        this.setBackground(Color.gray);
        this.lit = false;
    }

    public boolean getLit(){
        return lit;
    }

    public int getX(){
        return this.x;
    }
    public int getY(){
        return this.y;
    }

    /**
     * turn on the light
     */
    public void setOn(){
        this.setBackground(Color.green);
        this.lit = true;
    }
    /**
     * turn off the light
     */
    public void setOff(){
        this.setBackground(Color.gray);
        this.lit = false;
    }   

    public void changeState(){
        if(lit)
            setOff();
        else 
            setOn();
    }
}

2 个答案:

答案 0 :(得分:1)

没有竞争的例子,很难说;但您可以将您的方法与显示here的方法进行比较,如下图所示。特别是,

  • 确认Light具有预期的首选尺寸和位置。

  • 如果你真的要覆盖setPreferredSize(),请不要使用getPreferredSize(),如here所示。

image

答案 1 :(得分:1)

最初调查后我的想法是:

我认为您的Light课程可能存在问题。

有更多时间研究

问题肯定在于您的Light课程。

具体来说,您已覆盖getY()getX()中的JcomponentComponent方法。这些方法在渲染组件时使用,所以我认为它们是造成问题的原因。

我所做的是改变你的灯光类看起来像这样:

    //Make the two fields represent the x and y positions in your grid
/**
 * coordonates of the light according to the GridLayout
 */
private int xPositionInGrid;

/**
 * coordonates of the light according to the GridLayout
 */
private int yPositionInGrid;


    //Alter the constructor to set these two new named fields.
/**
 * construct a light
 * @param abs the abscissa of the light
 * @param ord the ordered of the light
 */
public Light( final int abs, final int ord ) {
    super();
    this.xPositionInGrid = abs;
    this.yPositionInGrid = ord;
    // Default color
    setBackground(Color.gray);
    this.lit = false;
}


    //Rename the two methods so they're not overriding the superclass methods anymore.
public int getXPositionInGrid() {
    return this.xPositionInGrid;
}

public int getYPositionInGrid() {
    return this.yPositionInGrid;
}

Light类看起来像这样,我能够得到以下屏幕,我相信这是你所期待的:

enter image description here


以下是我的初步证据,即该问题不属于Window类

你说你正在添加25个按钮,但你实际添加的是25个Light个实例

没有Light课程,我使用了您的Window代码并将所有对Light的引用替换为JButton,这对我来说很好。 (我还必须删除MenuListener的实例,因为我没有该类,但这与我不相信的问题无关

以下是我改变的一点点:

//Made these explicit JButtons
private JButton light[][] = new JButton[5][5];



for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
        //Made these explicit JButtons
        this.light[i][j] = new JButton();
        lightJpanel.add(this.light[i][j]);
    }
}

我还在main方法中添加了运行所有内容:

public static void main(final String[] args) {
    final Window window = new Window();
    window.setVisible(true);
}

这就是我得到的:(所有活跃的JButtons)

enter image description here