我有一个初学者Swing / AWT问题。
我正在对BoxPanel
扩展JPanel
的对象进行自定义绘制。
我有n
BoxPanels
这些JFrame
,然后使用FormSolutionViewer
在名为FlowLayout
的{{1}}中绘制。
现在我遇到的问题是,在创建JFrame
并使其可见之后,它将在无限循环中重新绘制,而不会对组件进行任何更改。有人可以向我解释为什么会这样以及如何修复它,以便只在窗口调整大小或某些数据实际发生变化时重新绘制它?
public class BoxPanel extends JPanel {
private Box box;
private int scaleFactor;
public BoxPanel(Box box, int scaleFactor) {
super();
this.box = box;
this.scaleFactor = scaleFactor;
this.setLayout(null); // Use null layout for absolute positioning
}
/**
* Need to override getPreferredSize() when using a FlowLayout
*/
@Override
public Dimension getPreferredSize() {
return new Dimension(this.box.getLength() * this.scaleFactor, this.box.getLength() * this.scaleFactor);
}
/**
* Paint the box border, background and its rectangles
* @param g
*/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setBackground(Color.white);
// Display no. of rectangles contained in tooltip
this.setToolTipText("Box contains " + this.box.getRectangles().size() + " rectangles");
// Draw border of box
this.setBorder(BorderFactory.createLineBorder(Color.black));
/* Draw rectangles contained in box */
int i = 1;
for (Rectangle rect : box.getRectangles()) {
System.out.println("Rectangle " + i + ": " + rect.toString());
g.setColor(Color.BLACK); // Set color for border
g.drawRect(rect.getPos().getX() * this.scaleFactor, rect.getPos().getY() * this.scaleFactor,
rect.getWidth() * this.scaleFactor, rect.getHeight() * this.scaleFactor);
i++;
}
}
}
public class FormSolutionViewer extends JFrame {
private JPanel contentPane;
private FeasibleSolution solution;
int scaleFactor = 40;
int spacing = 5;
/**
* Create the frame.
*/
public FormSolutionViewer(FeasibleSolution solution, int x, int y, int dpi) {
this.solution = solution;
this.scaleFactor = (int) Math.round(dpi / 2.4);
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
setBounds(x, y, 800, 600);
setTitle("Initialized Solution of " + solution.getInstance().toString());
this.setBackground(new Color(250, 250, 250));
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(spacing, spacing, spacing, spacing));
FlowLayout layout = new FlowLayout(FlowLayout.LEADING, 5, 5);
contentPane.setLayout(layout);
this.setContentPane(contentPane);
/* Place the boxes */
int boxNo = 0;
int rowCount = 0;
for (Box box : solution.getBoxes()) {
boxNo++;
BoxPanel boxPanel = new BoxPanel(box, scaleFactor);
contentPane.add(boxPanel);
contentPane.setSize(this.getWidth(), 500);
boxPanel.setVisible(true);
}
}
}
答案 0 :(得分:1)
this.setBackground(Color.white);
...
this.setToolTipText("Box contains " + this.box.getRectangles().size() + " rectangles");
...
this.setBorder(BorderFactory.createLineBorder(Color.black));
不要在绘画方法中设置组件的属性。当组件的属性发生更改时,Swing会在组件上调用revalidate()/ repaint()以反映组件的新状态。
绘制方法的目的是将组件绘制为当前状态,而不是更改其状态。