【发布时间】:2018-07-01 10:02:42
【问题描述】:
我有一个初学 Swing/AWT 问题要问你。
我正在对扩展 JPanel 的 BoxPanel 对象进行自定义绘制。
我有这些BoxPanels 中的n,然后使用FlowLayout 在称为FormSolutionViewer 的JFrame 中绘制。
现在我遇到的问题是,在创建 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);
}
}
}
【问题讨论】:
-
什么“无限循环”在哪里?您的代码仅显示两个非无限 for 循环。这个未显示的无限循环是否尊重 Swing 线程规则?
-
抱歉,我的措辞可能不太好。没有无限循环,我的意思是框架会不断重新绘制。对于小问题,每秒数百次。这是否使它更清晰?
-
为什么 JFrame 会不断重绘?是什么代码推动了这一点——再次我在上面的代码中没有看到这一点。你在哪里创建 JFrame?请创建并发布有效的minimal reproducible example。
标签: java swing user-interface awt paint