java - 为什么我的组件一遍又一遍地重新绘制而没有发生任何变化?

标签 java swing user-interface awt paint

我有一个 Swing/AWT 初学者问题要问您。

我正在对扩展 JPanelBoxPanel 对象进行自定义绘制。 我有 n 这些 BoxPanels,然后使用 FlowLayout< 在名为 FormSolutionViewerJFrame 中进行绘制。 现在我遇到的问题是,在创建 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);
        }
    }
}

最佳答案

this.setBackground(Color.white);
...
this.setToolTipText("Box contains " + this.box.getRectangles().size() + " rectangles");
...
this.setBorder(BorderFactory.createLineBorder(Color.black));

不要在绘画方法中设置组件的属性。当组件的属性更改时,Swing 会调用组件上的 revalidate()/repaint() 以反射(reflect)组件的新状态。

绘制方法的要点是在当前状态下绘制组件,而不是更改其状态。

关于java - 为什么我的组件一遍又一遍地重新绘制而没有发生任何变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48387246/

相关文章:

c++ - 有没有一种方法可以测量桌面应用程序 UI 响应时间?

ios - 如何在我的应用程序中禁用 iOS 7 界面更改

java - 如何使用 Rest assured 验证数组中元素的正确值

java - com.apple.eawt - 我到底应该安装什么

java - 配置 Play !显示完整堆栈跟踪的框架

Java动态var分配给变量

java - 为什么 JCombobox 不是 AbstractButton 的子类?

java - Swing Java 中带有多框架应用程序的任务栏图标

java - 如何在 JPanel 中为长 JComponent 添加滚动条?如何使 JComponent 居中?

user-interface - 自动完成与下拉菜单。什么时候使用?