我有一个棋盘游戏(认为是专卖),可以在单个图块上放置多个游戏块。我在绿色背景上绘制了4个圆圈,但是圆圈没有居中,当我调整它们的大小时,圆圈会在整个位置上移动,而不是停留在图块上。
CirclePanel:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class CirclePanel extends JPanel {
public static final Dimension SIZE = new Dimension(35, 35);
public CirclePanel() {
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(Color.RED);
g.fillOval(0, 0, 35, 35);
System.out.println(getSize());
}
@Override
public Dimension getPreferredSize() {
return SIZE;
}
}
GraphicsTile:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
@SuppressWarnings("serial")
public class GraphicsTile extends JPanel {
public static final Dimension SIZE = new Dimension(140, 140);
public static final GridLayout MGR = new GridLayout(2, 2);
public GraphicsTile() {
super();
setLayout(MGR);
add(new CirclePanel());
add(new CirclePanel());
add(new CirclePanel());
add(new CirclePanel());
}
@Override
public Dimension getPreferredSize() {
return SIZE;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillRect(0, 0, 140, 140);
}
}
GraphicsRunner:
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
public class GraphicsRunner {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(4, 0, 5, 5));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1280, 720);
frame.setPreferredSize(new Dimension(140, 140));
frame.add(new GraphicsTile());
frame.add(new GraphicsTile());
frame.setVisible(true);
}
}
答案 0 :(得分:3)
再一次,不要玩大号了。所有Swing组件都应确定自己的首选大小。这包括面板和框架。
面板将根据添加到面板中的组件确定其大小。
框架将根据添加到框架的面板确定其大小。添加面板后,您可以使用pack()方法。
然后所有组件将以其首选大小显示。然后,您可以使用以下方法将框架固定为固定大小:
frame.setResizable( false );
但是,如果您不执行上述操作,则需要确定调整框架大小后会发生什么。然后,您需要更加注意所使用的布局管理器。
对于GridLayout
,所有组件的大小都会进行调整以填充所有可用空间。通过将GraphicsTile`中的绘画代码更改为:
//g.fillRect(0, 0, 140, 140);
g.fillRect(0, 0, getWidth(), getHeight());
这是更好的绘画技术。您不应该对值进行硬编码。在适当的时候使用组件的属性来指定参数。
如果执行此操作,您会看到磁贴会扩大以填充该区域,并且CirclePanel
位于GraphicsTile的开头(同样是因为您对位置进行了硬编码)。
为防止GraphicsTile扩大尺寸,您需要将其包装在另一个面板中,该面板应遵守添加到其中的组件的首选大小。
一种简单的方法是将GridBagLayout
与默认GridBagConstraints
一起使用。现在,添加到其中的所有组件都将位于可用空间的中心。
所以您对main()方法的重组看起来像:
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
JPanel tilePanel = new JPanel( new GridLayout(0, 1, 5, 5) );
tilePanel.add(new GraphicsTile());
tilePanel.add(new GraphicsTile());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(tilePanel, new GridBagConstraints());
frame.pack();
frame.setVisible(true);
答案 1 :(得分:0)
这是因为GridLayout
会使用所有可用空间自动扩展内容。
您可以通过将GraphicsTiles
用另一个JPanel
(默认情况下使用FlowLayout
)包装来避免这种情况。这样,GridLayout
将被迫保留在包装中。
例如,在GraphicsRunner
中,您可以使用panel
作为包装器:
JPanel panel = new JPanel();
panel.add(new GraphicsTile());
frame.add(panel);
panel = new JPanel();
panel.add(new GraphicsTile());
frame.add(panel);
但是您可能想研究其他布局(甚至根本不使用布局)是否更适合您的需求。
这里有一个类似的问题可能会有所帮助:How to set the component size with GridLayout? Is there a better way?