我昨天才开始使用Java Swing,所以请问这不是一个有效的问题。我一直在尝试创建一个带有网格和面板的简单UI,允许用户指定网格尺寸的大小。

我有两个扩展JPanel的类:GridSizePanelGridBoxPanelGridSizePanel指定设计允许用户更改尺寸的面板时涉及的标题,边框,标签和字段。 GridBoxPanel显示实际的网格(从here采纳)。 GridSizePanel使用GroupLayout作为其LayoutManager,而GridBoxPanel使用GridBagLayout。协调这些子面板的父JFrame类(MazeSolverInterface)使用GroupLayout作为其LayoutManager。

问题是,如果仅将GridSizePanel添加到MazeSolverInterface的GroupLayout中,则当我手动调整窗口大小时,我会看到GridSizePanel自动调整大小。都好。

但是,当我将GridBoxPanel添加到MazeSolverInterface时,现在当我手动调整窗口大小时,只有GridBoxPanel似乎会调整大小。 GridSizePanel完全不改变尺寸!

到目前为止,这是我的代码:

GridSizePanel:

public class GridSizePanel extends JPanel implements PropertyChangeListener {


    public GridSizePanel() throws ParseException {

        // set the border properties
        TitledBorder title = BorderFactory.createTitledBorder("Grid Size");
        title.setTitleColor(Color.BLACK);
        title.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED,
                Color.DARK_GRAY, Color.GRAY));
        this.setBorder(title);

        // wire up the group layout and panel to
        // each other
        GroupLayout gl = new GroupLayout(this);
        this.setLayout(gl);

        // Turn on automatically adding gaps between components
        gl.setAutoCreateGaps(true);

        // Turn on automatically creating gaps between components that touch
        // the edge of the container and the container.
        gl.setAutoCreateContainerGaps(true);

        JLabel numRowsLabel = new JLabel("rows");
        JLabel numColsLabel = new JLabel("columns");

        MaskFormatter textMask = new MaskFormatter("##");
        textMask.setPlaceholder("16");
        JFormattedTextField rowsText = new JFormattedTextField(textMask);
        JFormattedTextField colsText = new JFormattedTextField(textMask);

        // configure the text fields
        rowsText.setColumns(50);
        colsText.setColumns(50);
        rowsText.addPropertyChangeListener("value", this);
        colsText.addPropertyChangeListener("value", this);

        GroupLayout.SequentialGroup horGroup = gl.createSequentialGroup();
        horGroup.addGroup(gl.createParallelGroup().addComponent(numRowsLabel).addComponent(numColsLabel))
                .addGroup(gl.createParallelGroup().addComponent(rowsText).addComponent(colsText));
        gl.setHorizontalGroup(horGroup);

        GroupLayout.SequentialGroup verGroup = gl.createSequentialGroup();
        verGroup.addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(numRowsLabel).addComponent(rowsText))
                .addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(numColsLabel).addComponent(colsText));
        gl.setVerticalGroup(verGroup);
    }

    //public GridSize getSize() {
    //    return new GridSize()
    //}

    @Override
    public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
        // TODO: fill this with logic to relay grid dimensions to the model
    }
}


GridBoxPanel:

public class GridBoxPanel extends JPanel {

    public GridBoxPanel() {
        setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        for (int row = 0; row < 32; row++) {
            for (int col = 0; col < 32; col++) {
                gbc.gridx = col;
                gbc.gridy = row;

                GridCell gridCell = new GridCell();
                Border border = null;
                if (row < 4) {
                    if (col < 4) {
                        border = new MatteBorder(1, 1, 0, 0, Color.GRAY);
                    } else {
                        border = new MatteBorder(1, 1, 0, 1, Color.GRAY);
                    }
                } else {
                    if (col < 4) {
                        border = new MatteBorder(1, 1, 1, 0, Color.GRAY);
                    } else {
                        border = new MatteBorder(1, 1, 1, 1, Color.GRAY);
                    }
                }
                gridCell.setBorder(border);
                add(gridCell, gbc);
            }
        }
    }
}


MazeSolver接口:

public class MazeSolverInterface extends JFrame {

    public MazeSolverInterface(String[] args) throws ParseException {
        checkArgs(args);
        initMaze(args);
    }

    public void initMaze(String[] args) throws ParseException {
        Container pane = getContentPane();
        GroupLayout gl = new GroupLayout(pane);
        pane.setLayout(gl);

        gl.setAutoCreateContainerGaps(true);

        // create required panels to integrate
        GridSizePanel gridSizeComponent = new GridSizePanel();
        GridBoxPanel gridDrawComponent = new GridBoxPanel();

        gl.setHorizontalGroup(gl.createSequentialGroup().addComponent(gridDrawComponent).addGap(50).addComponent(gridSizeComponent));
        gl.setVerticalGroup(gl.createParallelGroup().addComponent(gridDrawComponent).addGap(50).addComponent(gridSizeComponent));
        pack();

        setTitle("v0.0.1");
        setSize(700, 700);  // TODO: change to something configurable
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void checkArgs(String[] args) {
        // TODO: fill with logic to check valid arguments (initial window dimensions)
    }
}


主要:

public class Main {

    public static void main(final String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MazeSolverInterface ex = null;
                try {
                    ex = new MazeSolverInterface(args);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                ex.setVisible(true);
            }
        });
    }
}


在将GridBoxLabel添加到MazeSolverInterface之前,UI如下所示:



...并将GridBoxLabel添加到MazeSolverInterface之后:



任何/所有帮助表示赞赏。谢谢!

编辑:
如上所示,GridBoxPanel使用GridCell类。我忘了将其添加到这篇文章中,所以在这里。希望这可以帮助!

GridCell:

public class GridCell extends JPanel {

    private Color defaultBackground;

    public GridCell() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                defaultBackground = getBackground();
                setBackground(Color.BLUE);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setBackground(defaultBackground);
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(50, 50);
    }
}

最佳答案

GroupLayout确实是为GUI工具创建的,但是可以
手动使用没有问题。从内置的经理那里
我建议使用。

我对您的示例进行了一些修改:

MazeSolverInterface.java

import java.awt.Container;
import java.text.ParseException;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.BASELINE;
import static javax.swing.GroupLayout.Alignment.TRAILING;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.text.MaskFormatter;

public class MazeSolverInterface extends JFrame {

    public MazeSolverInterface(String[] args) throws ParseException {

        initMaze(args);
    }

    private void initMaze(String[] args) throws ParseException {

        Container pane = getContentPane();
        GroupLayout gl = new GroupLayout(pane);
        pane.setLayout(gl);

        gl.setAutoCreateContainerGaps(true);

        gl.setAutoCreateGaps(true);

        JLabel numRowsLabel = new JLabel("Rows:");
        JLabel numColsLabel = new JLabel("Columns:");

        MaskFormatter textMask = new MaskFormatter("##");
        //textMask.setPlaceholder("16");
        JFormattedTextField rowsText = new JFormattedTextField(textMask);
        JFormattedTextField colsText = new JFormattedTextField(textMask);

        rowsText.setColumns(20);
        colsText.setColumns(20);

        GridBoxPanel gridDrawComponent = new GridBoxPanel();

        gl.setHorizontalGroup(gl.createParallelGroup()
                .addGroup(gl.createSequentialGroup()
                        .addGroup(gl.createParallelGroup(TRAILING)
                                .addComponent(numRowsLabel)
                                .addComponent(numColsLabel))
                        .addGroup(gl.createParallelGroup()
                                .addComponent(rowsText)
                                .addComponent(colsText)))
                .addComponent(gridDrawComponent));

        gl.setVerticalGroup(gl.createSequentialGroup()
                .addGroup(gl.createParallelGroup(BASELINE)
                        .addComponent(numRowsLabel)
                        .addComponent(rowsText))
                .addGroup(gl.createParallelGroup(BASELINE)
                        .addComponent(numColsLabel)
                        .addComponent(colsText))
                .addComponent(gridDrawComponent));

        pack();

        setTitle("v0.0.1");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}


我摆脱了GridSizePanel并将代码移到MazeSolverInterface中。从设计的角度来看,如果没有其他特定的说明,则无需标题面板
面板。标签是右对齐的。当文本字段和迷宫对象增加或缩小时,
调整窗口大小。

setSize()方法已被删除,因为最好使用pack()方法。
您可以使用其中一个,但不能同时使用两者。

GridBoxPanel.java

import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

public class GridBoxPanel extends JPanel {

    public GridBoxPanel() {
        setLayout(new GridLayout(32, 32, 1, 1));

        for (int row = 0; row < 32; row++) {
            for (int col = 0; col < 32; col++) {

                GridCell gridCell = new GridCell();
                Border border = null;
                if (row < 4) {
                    if (col < 4) {
                        border = new MatteBorder(1, 1, 0, 0, Color.GRAY);
                    } else {
                        border = new MatteBorder(1, 1, 0, 1, Color.GRAY);
                    }
                } else {
                    if (col < 4) {
                        border = new MatteBorder(1, 1, 1, 0, Color.GRAY);
                    } else {
                        border = new MatteBorder(1, 1, 1, 1, Color.GRAY);
                    }
                }
                gridCell.setBorder(border);
                add(gridCell);
            }
        }
    }
}


在这里,我使用了GridLayout管理器而不是GridBagLayout。 (也许是
只有我发现GridLayout有用的第三个示例。)
我进行了此修改以使事情变得更容易,但是我个人不会使用GridLayout
并与GroupLayoutMigLayout经理一起完全创建解决方案。
GridLayout是不可移植的,因为它以像素为单位设置边距。这不是
最佳,因为我们选择的固定空间在所有类型的屏幕分辨率上都不正确。
在较小的屏幕上可以正常运行,在较大的屏幕上不能正常运行。通常,我们应该避免
设置尺寸(以像素为单位)。这也适用于您覆盖的getPreferredSize()方法。)

10-08 13:11