我有一个棋盘游戏(想想垄断),多个游戏块可以定位在一个单一的瓷砖。我在一个绿色的背景上画了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);
}
}发布于 2018-09-05 22:18:34
再说一遍,不要玩大小游戏。所有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);发布于 2018-09-05 21:53:33
这是因为GridLayout使用所有可用空间自动扩展内容。
您可以通过使用另一个GraphicsTiles (默认情况下使用FlowLayout)包装您的JPanel来避免这种情况。这样,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?
https://stackoverflow.com/questions/52193240
复制相似问题