简体   繁体   English

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

[英]Custom painting in Java - drawing UI elements onto the JPanel

I am creating a drawing board program, basically a simplified version of MS Paint. 我正在创建一个绘图板程序,基本上是MS Paint的简化版本。 It is working for the most part but when I draw on the board, the currently selected UI element shows up on the drawing area. 它在大多数情况下工作,但是当我在板上绘图时,当前选择的UI元素显示在绘图区域上。

I tried paintComponent, which worked when I called super.paintComponent(g) (as one does) but it cleared the drawing area before I drew the next object. 我尝试了paintComponent,当我调用super.paintComponent(g)(就像一个人那样)时它工作但是在我绘制下一个对象之前它清除了绘图区域。 I overrode update and put a println statement in there and it is never being called. 我覆盖了更新并在其中放入了println语句,它永远不会被调用。

The buttons at the top are red because I set the background to the bottom JPanel to red to see what the background of these buttons would be. 顶部的按钮是红色的,因为我将背景设置为底部JPanel为红色,以查看这些按钮的背景是什么。 So clearly they are part of the bottom JPanel. 很明显,它们是底层JPanel的一部分。 I am using a BorderLayout for the layout. 我正在使用BorderLayout进行布局。

在此输入图像描述

Here is my code (with some irrelevant bits removed): 这是我的代码(删除了一些不相关的位):

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

If the currently selected UI element shows up on the drawing area, this can have only one reason: you are doing something wrong with the Graphics objects, possibly calling a translate on them, and not resetting the tranlation when you are done. 如果当前选定的UI元素显示在绘图区域上,则只能有一个原因:您正在对Graphics对象执行错误操作,可能会对它们进行转换,并且在完成后不会重置转换。 (See this link for an example of translate used correctly). (有关正确使用翻译的示例,请参阅链接)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM