我昨天才开始使用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);
}
}
}
}
MazeSolverInterface:
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
类。我忘了把它添加到这篇文章,所以在这里。希望这有帮助!
栅格单元:
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);
}
}
答案 0 :(得分:2)
GroupLayout
,但它可以
手动使用没有问题。从内置的经理那里就是一个
我建议使用。
我稍微修改了你的例子:
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()
方法。)