我昨天才开始使用Java Swing,所以请问这不是一个有效的问题。我一直在尝试创建一个带有网格和面板的简单UI,允许用户指定网格尺寸的大小。
我有两个扩展JPanel的类:GridSizePanel
和GridBoxPanel
。 GridSizePanel
指定设计允许用户更改尺寸的面板时涉及的标题,边框,标签和字段。 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
并与
GroupLayout
或MigLayout
经理一起完全创建解决方案。(
GridLayout
是不可移植的,因为它以像素为单位设置边距。这不是最佳,因为我们选择的固定空间在所有类型的屏幕分辨率上都不正确。
在较小的屏幕上可以正常运行,在较大的屏幕上不能正常运行。通常,我们应该避免
设置尺寸(以像素为单位)。这也适用于您覆盖的
getPreferredSize()
方法。)