Mock MSPaint程序在Java

问题描述

我的问题:graphics2D对象为ArrayList中的每个点重新着色。如何更改颜色,而不会更改以前的颜色?我的猜测是要更改for循环在PaintApp中的交互方式,但是我不确定该怎么做。感谢您的帮助!

我的代码

PaintApp.java

package paint;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class PaintApp extends JPanel {

    private List<List<Point>> points;
    private JFrame frame = new JFrame("Sketch MSPaint");
    private JMenuBar bar = new JMenuBar();
    private JMenu file = new JMenu("File");
    private JMenu colors = new JMenu("Colors");
    private JMenuItem quit = new JMenuItem("Quit");

    private JMenuItem red = new JMenuItem("Red");
    private JMenuItem blue = new JMenuItem("Blue");
    private JMenuItem green = new JMenuItem("Green");
    private JMenuItem orange = new JMenuItem("Orange");
    private JMenuItem pink = new JMenuItem("Pink");
    private JMenuItem cyan = new JMenuItem("Cyan");

    private JMenuItem clear = new JMenuItem("Clear");
    private boolean clearBoard = false,blackColor,redColor,blueColor,greenColor,orangeColor,pinkColor,cyanColor;

    
    
    public PaintApp(Dimension d) {
        this.setSize(d);
        this.setPreferredSize(d);

        points = new ArrayList<>();
        MouseAdapter ma = new MouseAdapter() {

            private List<Point> currentPath;

            @Override
            public void mousepressed(MouseEvent e) {
                currentPath = new ArrayList<>();
                currentPath.add(e.getPoint());

                points.add(currentPath);
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                Point dragPoint = e.getPoint();
                currentPath.add(dragPoint);
                repaint();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                currentPath = null;
            }

        };

        addMouseListener(ma);
        addMouseMotionListener(ma);
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.clearRect(0,frame.getWidth(),frame.getHeight());

        for (List<Point> path : points) {
            Point from = null;
            for (Point p : path) {
                if (from != null) {
                    if (redColor) {
                        g2d.setColor(Color.red);
                    } else if (blueColor) {
                        g2d.setColor(Color.blue);
                    } else if (greenColor) {
                        g2d.setColor(Color.green);
                    } else if (orangeColor) {
                        g2d.setColor(Color.orange);
                    } else if (pinkColor) {
                        g2d.setColor(Color.pink);
                    } else if (cyanColor) {
                        g2d.setColor(Color.cyan);
                    } else {
                        g2d.setColor(Color.black);
                    }
                    g2d.drawLine(from.x,from.y,p.x,p.y);
                }
                from = p;
            }
        }
        g2d.dispose();
    }

    public void initBar() {
        bar.add(file);
        file.add(clear);
        clear.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                points = new ArrayList<>();
                repaint();
            }

        });
        file.add(quit);
        quit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                System.exit(0);

            }

        });

        bar.add(colors);
        colors.add(red);
        red.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                redColor = true;
                blueColor = false;
                greenColor = false;
                orangeColor = false;
                pinkColor = false;
                cyanColor = false;
                repaint();
            }

        });

        colors.add(orange);
        orange.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                redColor = false;
                blueColor = false;
                greenColor = false;
                orangeColor = true;
                pinkColor = false;
                cyanColor = false;
                repaint();

            }

        });

        colors.add(blue);
        blue.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                redColor = false;
                blueColor = true;
                greenColor = false;
                orangeColor = false;
                pinkColor = false;
                cyanColor = false;
                repaint();
            }

        });

        colors.add(green);
        quit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                redColor = false;
                blueColor = false;
                greenColor = true;
                orangeColor = false;
                pinkColor = false;
                cyanColor = false;
                repaint();

            }

        });

        colors.add(pink);
        quit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                redColor = false;
                blueColor = false;
                greenColor = false;
                orangeColor = false;
                pinkColor = true;
                cyanColor = false;
                repaint();

            }

        });

        colors.add(cyan);
        quit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                redColor = false;
                blueColor = false;
                greenColor = false;
                orangeColor = false;
                pinkColor = false;
                cyanColor = true;
                repaint();

            }

        });

        frame.setJMenuBar(bar);

    }

    public void show() {
        frame.add(this);
        initBar();
        frame.setResizable(false);
        frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Main.java

package paint;

import java.awt.Dimension;

public class Main {
    public static void main(String[] args) {
        
        PaintApp app = new PaintApp(new Dimension(700,700));
        
        app.show();
        
    }
}

解决方法

如果您不想为此功能提供“撤消”功能,那么我看到的最简单的解决方案是绘制到BufferedImage,然后在SELECT a.id FROM tableA a WHERE a.id_list IN (select b.this_id from tableB b) and a.id IN (select b.this_id from tableB b); 覆盖(而不是{{1 }} – 从不 paintComponent)。这样,以前绘制的线条将一直保留,直到用新实例替换BufferedImage为止。

否则,如果您绝对不能走这条路,则创建一个新的自定义类,该类包含一个paint或其他Shape类型的对象和一个Color,在用户绘制时创建这些对象,并将其存储到此类对象的列表,然后在您的(再次paint替代中对其进行绘制。通过这种方式,您可以将每条线(或其他Shape)与一种颜色相关联,并且这种关联将继续存在。

如上所述,我也建议不要覆盖Line2D,而应该覆盖paintComponent,因为paint可以自动双缓冲,如果您决定制作动画,并且您也不想这样做不必担心会混淆组件的子组件和边框的绘制,而当您覆盖paintComponent时,可能会冒险这么做。当然,通常在其覆盖的第一行中调用paint方法。