在重叠的面板上绘制形状,一个面板绘制固定的,另一个绘制移动的

Draw Shapes on overlapping Panels, One panel Draw Stationary and another Draw Movable

我正在创建 Swing 应用程序。它是一种带有移动对象应用程序的路线图。我将我的形状组件分成两个 JPanels。一个是静态组件JPanel,第二个是动态组件JPanel,都添加到mainPanel中。两个面板都是重叠的,对于动态组件面板,不透明是 false 以使其透明。当我为动态组件面板重绘时,它也会触发静态组件面板的重绘。如果动态组件面板的形状发生变化并且不应擦除静态组件面板形状,我不想每次都重新绘制静态组件面板。

目前我的逻辑如下。这是伪代码。 请帮助我如何在静态组件顶部绘制可移动组件并在启动时绘制一次静态组件。

public class layeredpanel extends JFrame
{

    private JPanel contentPane;


    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    layeredpanel frame = new layeredpanel();
                    frame.setVisible(true);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public layeredpanel()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.CENTER);

        panel.setLayout( new OverlayLayout(panel) );


        final JPanel layer_1 = new layer1();

        layer_1.setOpaque(false);
        panel.add(layer_1);


        JPanel layer_2 = new layer2();      
        panel.add(layer_2);


        Thread thread = new Thread(new Runnable()
        {

            @Override
            public void run()
            {
                while(true)
                {try
                {
                    Thread.sleep(500);
                } catch (InterruptedException e)
                {

                    e.printStackTrace();
                }

                layer_1.repaint();
            }
            }
        });

        thread.start();



    }

    class layer1 extends JPanel
    {


        @Override
        public void paintComponent(Graphics g)
        {
            // TODO Auto-generated method stub
            super.paintComponent(g);
            System.out.println("Paint1");
            g.setColor(Color.blue);
            g.drawRect(30, 20, 40, 40);
        }

    }

    class layer2 extends JPanel
    {
        @Override
        public void paintComponent(Graphics g)
        {
            System.out.println("Paint2");
        // TODO Auto-generated method stub
        super.paintComponent(g);

        g.setColor(Color.green);
        g.fillRect(30, 20, 20, 20);}

    }
}

输出:Paint2

Paint1
Paint2
Paint1
Paint2
Paint1
Paint2
Paint1
Paint2
Paint1
Paint2
Paint1
Paint2
Paint1

这就是 Swing 绘画的工作方式。当你有一个透明面板时,父面板也必须被绘制以确保没有绘制伪影。

为了提高父面板的绘制效率,您可以:

  1. 首先在 BufferedImage 上绘制(当您创建 class 时),然后重新绘制 BufferedImage。
  2. 重绘顶部面板时,您可以repaint(....)指定要重绘的矩形区域。然后只有父面板的那部分也被重新绘制。

此外,不要使用带有 Thread.sleep() 的线程来制作动画。如果你想要动画,那么使用 Swing Timer 来安排重绘。