Java - 动态网格布局

标签 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 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);
    }
}

正如您可能所知,目标是拥有一个 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);
        }
    }
}

现在您需要创建面板并向其中添加按钮:

//board = board(8,8);
board = new JPanel();
resetBoard(8, 8);

最后,在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();

关于Java - 动态网格布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29195918/

相关文章:

Java Swing : consuming key events

java - 我正在从命令行运行 testng 但没有执行任何测试

java - 高级自定义 Swing 组件

java - 如何在 FreeMarker 中调用公共(public) Java 变量

java - 使用可扩展 ListView 在我的 ImageView 中填充联系人图像

Java Swing : Make a dialog partially transparent.

Java JFrame 布局

java - 获取触摸屏上的点击计数鼠标监听器

java - 使用日期和时间戳为每次运行创建 log4j 日志文件

java - Java JButton 的两半 (+/-)