java - Java 中的自定义绘画 - 将 UI 元素绘制到 JPanel 上

标签 java swing user-interface paint

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

我尝试了paintComponent,它在我调用 super.paintComponent(g) 时起作用(就像一个人所做的那样),但它在我绘制下一个对象之前清除了绘图区域。我覆盖了 update 并在其中放置了一条 println 语句,但它从未被调用。

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

enter image description here

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

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();
            }
        });
    }
}

最佳答案

如果当前选定的 UI 元素显示在绘图区域上,这可能只有一个原因:您对 Graphics 对象执行了错误操作,可能对它们调用了翻译,并且在完成后没有重置翻译。 (有关正确使用翻译的示例,请参阅 this 链接)。

关于java - Java 中的自定义绘画 - 将 UI 元素绘制到 JPanel 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13985178/

相关文章:

java - 有没有办法截取当前运行的 Java 桌面应用程序的屏幕截图并将其作为视频传输?

python - 为什么 PyGTK ListStore 添加具有相同值的新记录?

java - 等到elementToBeClickable不是其他元素会收到点击异常的解决方案

java - 我从 SOAP 服务返回什么以及如何返回?

java - 批量更新 JComponents。需要更好的(线程)设计的建议

java - 如何取消焦点 JTextField

java - 计时器无法正确触发

java - 通过 ftp 发送数据库 - 获取不同的文件

c# - 设计更好的 GUI?

jquery - Kendo网格detailInit访问父网格