Java-动态网格布局

Java-动态网格布局,java,swing,Java,Swing,我正在尝试使用以下代码创建动态GridLayout: package resizablegui; import java.awt.*; import javax.swing.*; import javax.swing.event.*; class GUIHandler extends JFrame { JSpinner widthSpinner; JSpinner heightSpinner; JPanel board; private JPanel res

我正在尝试使用以下代码创建动态GridLayout:

package resizablegui;

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

class GUIHandler extends JFrame {
    JSpinner widthSpinner;
    JSpinner heightSpinner;
    JPanel board;

    private JPanel resizer() {
        final JPanel resizer = new JPanel(new GridLayout(2,2));
        final JPanel resizer_wrapper = new JPanel();

        JLabel widthLabel;
        JLabel heightLabel;

        SpinnerModel widthModel;
        SpinnerModel heightModel;
        resizer_wrapper.setLayout(new BoxLayout(resizer_wrapper, BoxLayout.X_AXIS));

        widthModel = new SpinnerNumberModel(8, 4, 32, 1);
        heightModel = new SpinnerNumberModel(8, 4, 32, 1);

        ResizeWindow onResize = new ResizeWindow();

        widthLabel = new JLabel("Width: ");
        resizer.add(widthLabel);

        widthSpinner = new JSpinner(widthModel);
        resizer.add(widthSpinner);
        widthSpinner.addChangeListener(onResize);

        heightLabel = new JLabel("Height: ");
        resizer.add(heightLabel);

        heightSpinner = new JSpinner(heightModel);
        resizer.add(heightSpinner);
        heightSpinner.addChangeListener(onResize);

        resizer.setMaximumSize(new Dimension(100,100));
        resizer_wrapper.add(resizer);

        return resizer_wrapper;
    }

    private JPanel board(int width, int height) {
        final JPanel board = new JPanel(new GridLayout(width, height));
        for(int x = 0; x < width; x++) {
            for(int y = 0; y < width; y++) {
                JButton button = new JButton(x+", "+y);
                board.add(button);
            }
        }
        return board;
    }

    public GUIHandler() {
        super("Board");
        setLayout(new BorderLayout());

        board = board(8,8);

        add(resizer(), BorderLayout.NORTH);
        add(board, BorderLayout.CENTER);
    }

    private class ResizeWindow implements ChangeListener {
        @Override
        public void stateChanged(ChangeEvent e) {
            int width = (Integer)widthSpinner.getValue() * 45;
            int height = (Integer)heightSpinner.getValue() * 45;

            setSize(width,height);
        }
    }
}

public class ResizableGUI {
    public static void main(String[] args) {
        GUIHandler gui = new GUIHandler();
        gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gui.setSize(350,350);
        gui.setVisible(true);
    }
}
package-resizeblegui;
导入java.awt.*;
导入javax.swing.*;
导入javax.swing.event.*;
类GUIHandler扩展了JFrame{
JSpinner宽度微调器;
JSpinner heightSpinner;
JPanel董事会;
专用JPanel resizer(){
最终JPanel重定器=新JPanel(新网格布局(2,2));
最终JPanel resizer_包装器=新JPanel();
JLabel标签;
JLabel高度标签;
喷丝头模型;
喷丝头模型高度模型;
resizer_wrapper.setLayout(新的BoxLayout(resizer_wrapper,BoxLayout.X_轴));
宽度模型=新喷丝头编号模型(8,4,32,1);
高度模型=新喷丝头编号模型(8,4,32,1);
ResizeWindow onResize=新建ResizeWindow();
宽度标签=新的JLabel(“宽度:”);
添加(宽度标签);
widthSpinner=新的JSpinner(widthModel);
添加(宽度微调器);
widthSpinner.addChangeListener(onResize);
heightLabel=新的JLabel(“高度:”);
添加(高度标签);
heightSpinner=新的JSpinner(heightModel);
添加(高度微调器);
heightSpinner.addChangeListener(onResize);
resizer.setMaximumSize(新尺寸(100100));
resizer_包装器。添加(resizer);
返回resizer\u包装器;
}
专用JPanel板(内部宽度、内部高度){
最终JPanel板=新JPanel(新网格布局(宽度、高度));
对于(int x=0;x

正如您可能知道的那样,目标是拥有一个8x8的按钮网格,可以根据微调器的值使其变大(例如9x10、10x10…)或变小(例如6x8、4x4)。代码编译得很好,但在尝试调整对话框大小时,程序冻结并崩溃。

不确定为什么代码冻结并崩溃,它没有为我这样做

无论如何,我仍然看到你的代码有问题

由于需要动态网格,因此需要能够在使用微调器时删除/添加网格中的按钮。因此,我将创建并清空“board”面板,并将其添加到GUI中。然后我将您的“boar(…)”方法重命名为“resetBoard(…)”,因为此方法应仅用于删除/添加按钮,而不是创建新面板

下一个问题是在这个新的“resetBoard(…)”方法中循环代码。外环应表示高度,内环表示宽度,因为您将向网格中添加一行按钮,一次添加一行

因此,该方法的重组可能如下所示:

private void resetBoard(int width, int height) {
        board.removeAll();
    board.setLayout( new GridLayout(0, width) );
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            JButton button = new JButton(x+", "+y);
            board.add(button);
        }
    }
}
最后,在ChangeListener中,您需要重置电路板上的按钮,而不是更改帧的大小:

int width = (Integer)widthSpinner.getValue();
int height = (Integer)heightSpinner.getValue();
resetBoard(width,height);
board.revalidate();
//pack(); pack the frame is you wish
另外,首次创建框架时,不要手动设置大小,让pack()方法为您完成以下工作:

//gui.setSize(350,350);
gui.pack();

它到底是如何崩溃的?如果您收到异常stacktrace,请在此处发布。如果它进入无限循环,请在调试器下运行它并暂停执行,以查看它挂起的确切位置。@yole它只是运行,没有响应任何进一步的输入。没有错误消息,程序从未真正关闭或说“没有响应”
//gui.setSize(350,350);
gui.pack();