模拟的MSPaint程序在Java中绘制之前的笔画,而不仅限于当前的笔画。

huangapple go评论81阅读模式
英文:

Mock MSPaint program paints previous strokes instead of only the current stroke in java

问题

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, 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);
        green.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);
        pink.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);
        cyan.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);
    }
}
import java.awt.Dimension;

public class Main {
    public static void main(String[] args) {

        PaintApp app = new PaintApp(new Dimension(700, 700));

        app.show();

    }
}
英文:

My Problem: The graphics2D object recolors EVERY point in the ArrayList. How would I make it so when I change the color, it doesn't change previous colors? My guess would be to change how the for loops interate in PaintApp, but I'm not sure what I should make it. Thanks for any help!

My Code:

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(&quot;serial&quot;)
public class PaintApp extends JPanel {
private List&lt;List&lt;Point&gt;&gt; points;
private JFrame frame = new JFrame(&quot;Sketch MSPaint&quot;);
private JMenuBar bar = new JMenuBar();
private JMenu file = new JMenu(&quot;File&quot;);
private JMenu colors = new JMenu(&quot;Colors&quot;);
private JMenuItem quit = new JMenuItem(&quot;Quit&quot;);
private JMenuItem red = new JMenuItem(&quot;Red&quot;);
private JMenuItem blue = new JMenuItem(&quot;Blue&quot;);
private JMenuItem green = new JMenuItem(&quot;Green&quot;);
private JMenuItem orange = new JMenuItem(&quot;Orange&quot;);
private JMenuItem pink = new JMenuItem(&quot;Pink&quot;);
private JMenuItem cyan = new JMenuItem(&quot;Cyan&quot;);
private JMenuItem clear = new JMenuItem(&quot;Clear&quot;);
private boolean clearBoard = false, blackColor, redColor, blueColor, greenColor, orangeColor, pinkColor, cyanColor;
public PaintApp(Dimension d) {
this.setSize(d);
this.setPreferredSize(d);
points = new ArrayList&lt;&gt;();
MouseAdapter ma = new MouseAdapter() {
private List&lt;Point&gt; currentPath;
@Override
public void mousePressed(MouseEvent e) {
currentPath = new ArrayList&lt;&gt;();
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, 0, frame.getWidth(), frame.getHeight());
for (List&lt;Point&gt; 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&lt;&gt;();
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();
}
}

答案1

得分: 1

最简单的解决方案是,如果您不想为此添加“撤消”功能,可以将图案绘制到 BufferedImage 中,然后在 paintComponent 重写中显示相同的 BufferedImage(不是 paint —— 绝对不是 paint)。这样,先前绘制的线条将保留,直到您用新实例替换 BufferedImage。

或者,如果您绝对不能选择这种方法,那么可以创建一个新的自定义类,其中包含一个 Line2D 或其他形状类型的对象和一个颜色,在用户绘制时创建这些对象,将它们存储到对象列表中,然后在您的(同样是)paintComponent 重写中使用它们进行绘制。这样,您可以将每条线(或其他形状)与颜色关联起来,关联将保持不变。

如上所述,我还建议不要覆盖 paint,而是覆盖 paintComponent,因为后者允许自动双缓冲,以便在决定执行动画时使用,并且您不会在覆盖 paint 时有可能影响组件子组件和边框的绘制,而覆盖 paint 时会有这种风险。当然,在您的重写中调用 super.paintComponent(g) 方法,通常在其第一行调用。

英文:

The easiest solution that I see, if you don't want to give this an "undo" feature, is to draw to a BufferedImage and then display that same BufferedImage within a paintComponent override (not paint -- never paint). This way, the previously drawn lines will persist until you replace the BufferedImage with a new instance.

Else, if you absolutely cannot go this route, then create a new custom class, one that holds a Line2D or other Shape type object and a Color, create these objects when the user draws, store them to a List of such objects, and then paint with them in your (again) paintComponent override. This way you associate each line (or other Shape) with a Color, and the association will persist.

As noted above, I also recommend not overriding paint but rather paintComponent since the latter allows for automatic double buffering should you decide to do animation, and also you don't risk messing with the painting of your component's child components and border, which you risk doing when you override paint. Of course, call the super.paintComponent(g) method in your override, often on its first line.

huangapple
  • 本文由 发表于 2020年10月14日 09:47:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64345479.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定