3

我有一个有两层的窗口:一个静态背景和一个包含移动对象的前景。我的想法是只绘制一次背景(因为它不会改变),所以我让改变面板透明并将其添加到静态背景之上。这是此的代码:

public static void main(String[] args) {
    JPanel changingPanel = new JPanel() {

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillRect(100, 100, 100, 100);
        }
    };
    changingPanel.setOpaque(false);

    JPanel staticPanel = new JPanel();
    staticPanel.setBackground(Color.BLUE);
    staticPanel.setLayout(new BorderLayout());
    staticPanel.add(changingPanel);

    JFrame frame = new JFrame();
    frame.add(staticPanel);
    frame.setSize(800, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

这段代码为我提供了我想要的正确图像,但每次我 repaint时changingPanelstaticPanel也会重新绘制(这显然违背了只绘制一次静态面板的整个想法)。有人可以告诉我有什么问题吗?

仅供参考,我正在使用 javax.swing.Timer 每秒 24 次重新计算和重新绘制更改面板。

4

3 回答 3

7

当您在另一个上方重绘一个透明组件时,您仍然会“弄脏”较低的组件,导致它被重绘。如果你不重新绘制下层,你会在它上面得到一个图像的涂抹效果。

这里唯一可用的优化是不重新生成在较低级别使用的图像。每次上面的图层发生变化时,仍然需要将栅格绘制到图形缓冲区。

于 2010-04-23T05:05:10.850 回答
3

这正是绘画的工作方式。Swing 必须搜索第一个具有非透明背景的组件。然后它绘制该组件和子组件以确保所有绘制都正确完成。

即使您有一个移动的组件,SWing 仍然需要“清除”组件的最后一个位置,这意味着它必须至少重新绘制背景面板的该区域,然后才能重新绘制移动的组件。

为了使绘画更有效率,子面板应该是不透明的。我不知道你为什么更改默认设置。

于 2010-04-23T05:04:43.337 回答
2

一个非常简单的方法是使用jxlayer。实现AbstractLayerUI并将其添加到您的组件上。请参阅此处开始。

于 2010-04-23T05:24:24.780 回答