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

时间:2016-09-28 05:31:18

标签: java swing repaint awt-eventqueue custom-painting

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

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

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

1 个答案:

答案 0 :(得分:1)

这是Swing绘画的工作方式。当您有透明面板时,还必须绘制父面板以确保没有绘制工件。

为了使父面板的绘画更有效,您可以:

  1. 首先在BufferedImage上绘图(当你创建你的类时),然后重新绘制BufferedImage。
  2. 当您对顶部面板进行重新绘制时,可以执行repaint(....)指定要重新绘制的矩形区域。然后,只有父面板的那一部分也被重新绘制。
  3. 另外,不要使用Thread with Thread.sleep()来做动画。如果你想要动画,那么使用Swing Timer来安排重新绘制。