这是我与AWT / Swing合作的第一个项目。我正在尝试设计一个简单的细胞自动机。我在选择布局管理器时遇到了一些问题,现在我正在使用GridLayout,因为它是我最想要的。但是,当尝试在JPanel中放置一个单元格时,坐标不能按我预期的那样工作。也许我不应该从JComponent扩展并使用fillRect()吗?也许GridLayout不是我需要的布局?主要问题是点(0,0)似乎在“移动”。 fillRect是否与GridLayout冲突?
注1:我已经尝试了GridBagLayout,但是没有用(因为我不知道如何配置它)。我也尝试了add(component,x,y)方法,但是没有用。
注2:我没有发布有关单元状态的代码,因为它不相关。
编辑:好的,我在一个公共类中编写了一个示例,我认为我不能更加简洁并重现相同的结果。
解决方案: https://docs.oracle.com/javase/tutorial/uiswing/painting/refining.html
这是我的代码:
public class Example{
class Cell extends JComponent{
private int x = 0; //Cell position ?
private int y = 0;
public Cell(int x, int y){
this.x = x;
this.y = y;
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
//draw cell
g.setColor(Color.white);
g.fillRect(x,y,15,15);
}
}
Example(){
JFrame frame = new JFrame("title");
frame.setBackground(Color.black);
frame.getContentPane().setPreferredSize(new Dimension(300,300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel box = new JPanel(new GridLayout(20,20)){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
setBackground(Color.black);
//draw grid
for(int i = 0; i <= this.getHeight(); i += 15){
g.drawLine(0,0+i,getWidth(),0+i);
}
for(int i = 0; i <= this.getWidth(); i += 15){
g.drawLine(0+i,0,0+i,getHeight());
}
}
};
/*box.add(new Cell(0,0)); //TEST 1
box.add(new Cell(0,0));
box.add(new Cell(0,0));
box.add(new Cell(0,0));*/
box.add(new Cell(0,0)); //TEST 2
box.add(new Cell(15,0));
box.add(new Cell(30,0));
box.add(new Cell(45,0));
frame.add(box);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
new Example();
}
}
这是与TEST 1和TEST 2相对应的结果:
答案 0 :(得分:1)
所有绘制都是相对于包含自定义绘制的组件完成的,而不是相对于您将组件添加到的面板进行的。
因此,在您的情况下,只需从(0,0)开始绘画即可。
布局管理器会将单元格放置在布局管理器确定的位置。
注意:
一种绘画方法仅用于绘画。永远不要像当前Box类那样创建组件。
基本逻辑是:
getPreferredSize()
方法,以便布局管理器可以使用此信息来定位添加到面板中的每个组件。如果要在面板上的不同位置管理绘画,则不要使用实际组件。相反,您保留要绘制的形状的ArrayList。每个形状将包含应绘制的位置。然后,您可以在paintComponent()方法中遍历ArrayList来绘制每个形状。有关此方法的示例,请查看在Custom Painting Approaches中找到的Draw On Component
示例。