Java中的自定义绘制-在JPanel上绘制UI元素

Java中的自定义绘制-在JPanel上绘制UI元素,java,swing,user-interface,paint,Java,Swing,User Interface,Paint,我正在创建一个绘图板程序,基本上是MS Paint的简化版本。它在大多数情况下都可以工作,但当我在黑板上绘制时,当前选定的UI元素会显示在绘图区域中 我尝试了paintComponent,当我调用super.paintComponent(g)时它工作了(就像一个人那样),但是在我绘制下一个对象之前它清除了绘图区域。我重写了update,并在其中放入了println语句,它永远不会被调用 顶部的按钮是红色的,因为我将底部JPanel的背景设置为红色,以查看这些按钮的背景。因此,很明显,它们是底部J

我正在创建一个绘图板程序,基本上是MS Paint的简化版本。它在大多数情况下都可以工作,但当我在黑板上绘制时,当前选定的UI元素会显示在绘图区域中

我尝试了paintComponent,当我调用super.paintComponent(g)时它工作了(就像一个人那样),但是在我绘制下一个对象之前它清除了绘图区域。我重写了update,并在其中放入了println语句,它永远不会被调用

顶部的按钮是红色的,因为我将底部JPanel的背景设置为红色,以查看这些按钮的背景。因此,很明显,它们是底部JPanel的一部分。我正在为布局使用边框布局

这是我的代码(删除了一些不相关的部分):


如果当前选定的UI元素显示在绘图区域上,这可能只有一个原因:图形对象有问题,可能对其调用转换,并且在完成转换时没有重置转换。(有关正确使用翻译的示例,请参见链接)

调用
paintComponent
时,应使用
BufferedImage
保存绘图区域,然后使用
drawImage
将其复制到屏幕上。您不希望覆盖绘制以不清除屏幕,因为在调用绘制之间,缓冲区可能会变得无效并充满其他数据。请编辑您的问题,以包括一个显示调用
pack()
@yiding“一旦有了图像,您应该使用缓冲区图像来保存绘图区域”的选项,您也可以将其显示在标签中。谢谢!我在这个项目上休息了很长时间,但最终还是打算回去。如果我弄明白了,我会告诉你的。我会调查的…谢谢!
public class JSPaint extends JFrame implements Serializable
{    
    private static final long serialVersionUID = -8787645153679803322L;
    private JFrame mainFrame;
    private JPanel bp;
    private JButton ...
    private DrawingArea da;

    public JSPaint()
    {
        setTitle("JS Paint");
        setSize(1024, 768);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Drawing area
        da = new DrawingArea();

        setLayout(new BorderLayout());

        // add the buttons to the panel
        buttonPanel();

        // Add the drawing area 
        add(bp, BorderLayout.SOUTH);
        bp.setBackground(Color.RED);
        add(da, BorderLayout.CENTER);
        da.setBackground(Color.BLUE);

        setVisible(true);        
    }

    // I put it here too just in case
    @Override
    public void update(Graphics g)
    {
        System.out.println("update in JSPaint called.");
        paint(g);
    }

   /*
    * Creates the panel for the buttons, creates the buttons and places them on
    * the panel
    */
    public void buttonPanel()
    {
        // Create the panel for the buttons to be placed in
        bp = new JPanel();

        saveButton = new JButton("Save");
        loadButton = new JButton("Load");
        //more buttons

        bp.add(saveButton);
        bp.add(loadButton);
        //more buttons

        // ActionListeners

        colorButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                System.out.println("color");
                da.color();
            }
        });            
    }

    public class DrawingArea extends JPanel
    {        
        private static final long serialVersionUID = -8299084743195098560L;
        boolean dragged = false;

        @Override
        public void update(Graphics g)
        {
            System.out.println("Update in DrawingArea called");
            paint(g);
        }

       /*
        * Draws the selected shape onto the screen and saves it into a Stack.
        *
        */
        public void draw()
        {
            this.addMouseMotionListener(new MouseMotionListener()
            {                
                public void mouseDragged(MouseEvent me)
                {
                    dragged = true;
                }

                public void mouseMoved(MouseEvent me) {}
            });

            //more listeners...
            });
        }

       /*
        * Draws the selected String onto the screen when the mouse is held down.
        *
        */
        public void brush()
        {
            this.addMouseMotionListener(new MouseMotionListener()
            {                
                public void mouseDragged(MouseEvent me)
                {
                    // If we are in drawing mode, draw the String. Create a new 
                    // Figure Object and push it onto the Stack
                    if(activeButton == "brush")
                    {
                        startPoint = me.getPoint();

                        Figure fig = new Figure("String", startPoint, null, currentColor);
//                        figures.push(calculate(fig));
                        toPaint.push(calculate(fig));
                        repaint();
                    }
                }

                public void mouseMoved(MouseEvent me) {}
            });           
        }

        // more of the same...

        public void paint(Graphics g)
        {                        
            toSave.addAll(toPaint);

            while(!toPaint.isEmpty())
            {
                Figure f = toPaint.pop();
                String t = f.type;

                if(f.color != null)
                {
                    g.setColor(f.color);
                }

                switch(t)
                {
                    case "Rectangle": g.drawRect(f.x1, f.y1, f.width, f.height);
                        break;
                    case "Oval": g.drawOval(f.x1, f.y1, f.width, f.height);
                        break;         
                    case "Line": g.drawLine(f.x1, f.y1, f.x2, f.y2);
                        break;
                    case "Clear": 
                        g.fillRect(0, 0, da.getWidth(), da.getHeight());
                        clearStack(toSave);
                        break;
                    case "String": g.drawString(f.toPrint, f.x1, f.y1);
                        break;
                }
            }
        }
    }

    private class Figure implements Serializable
    {
        private static final long serialVersionUID = 4690475365105752994L;
        String type, toPrint;
        Color color;
        Point start;
        Point end;
        int x1, y1, x2, y2, width, height;

        public Figure(String figureType, 
            Point startPoint, Point endPoint, Color figureColor)
        {
            type = figureType;
            color = figureColor;
            start = startPoint;
            end = endPoint;
        }

        // Rect, Oval
        public Figure(String figureType, int figureX, int figureY, 
            int figureWidth, int figureHeight, Color figureColor)
        {
            type = figureType;
            x1 = figureX;
            y1 = figureY;
            width = figureWidth;
            height = figureHeight;
            color = figureColor;
        }

        // more shapes
    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new JSPaint();
            }
        });
    }
}