绘画时关于Java绘图程序的多个问题 [英] Multiple problems regarding Java paint program while painting

查看:102
本文介绍了绘画时关于Java绘图程序的多个问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java绘图程序,我有两个问题与它有关。这两个问题都相对简单,只关注如何处理鼠标输入以及图像如何使用颜色。这是应用程序的照片:

I have a Java paint program, and I've got two problems to do with it. Both problems are relatively simple, and just regard how the mouse input is handled and how the image uses colors. Here's a photo of the app:

所以这是我的第一个问题:

So here's my first problem:

正如您所看到的,从应用程序的外观来看,涂料区域有一点点喷涂。每个点都是鼠标点击。用户按住鼠标按钮时程序无法识别,因此您必须单独单击。

As you can see, by the look of the app, there's a spray of dots on the paint area. Each of those dots is a mouseclick. The program does not recognize when a user is holding down the mouse button, so you have to click individually.

这显然适得其反,用户不友好且不可接受。现在,我如何解决这个问题,我不确定。我尝试使用永久而(true)循环,但这不起作用。我如何制作它,以便每次按下鼠标而不必每次都点击它,它会喷出点?

This is obviously counterproductive, user-unfriendly and unacceptable. Now, how I fix this, I'm not sure. I've tried using a permanent while (true) loop, but that does not work. How do I make it so that instead of having to click every time, each time the mouse is held down it sprays out dots?

第二个问题是颜色是点。如您所见,在底部有颜色按钮。这些功能,但有一个问题:每当我改变颜色时,屏幕上当前的所有点都会改变颜色。颜色由名为 currentColor 的变量运行,该变量由底部面板上所有颜色按钮控制的actionListeners运行。如何确保已经放置在屏幕上的颜色不再受影响?

The second problem is the color of the dots. As you can see, at the bottom, there are color buttons. These function, but there is a problem: Whenever I change the color, all the dots currently on the screen change color. The color is run by a variable called currentColor which is run by the actionListeners controlled by all the color buttons on the bottom panel. How do I make sure that colors already placed on the screen are not affected anymore?

我相信可以修复这两个问题的所有代码都在于我的自定义 JPanel ,用于绘制程序。我将在下面发布整个课程,如果您有任何其他问题,请告诉我。

I believe that all the code that can be fixed for these two problems lies in my custom JPanel which is used for the program to paint on. I'll post the entire class below, and if you have any other questions, please let me know.

int xCord, yCord;

public class PaintPanel extends JPanel implements MouseListener {
    // default serial whatever...
    private static final long serialVersionUID = -6514297510194472060L;

    public PaintPanel() {
        addMouseListener(this);
    }

    ArrayList<Point> points = new ArrayList<Point>();

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Point point : points) {
            g.setColor(currentColor);
            g.fillOval(point.x, point.y, 12, 12);

        }
        repaint();
    }

    @Override
    public void mouseClicked(MouseEvent m) {
    }

    @Override
    public void mouseEntered(MouseEvent m) {
    }

    @Override
    public void mouseExited(MouseEvent m) {
    }

    @Override
    public void mousePressed(MouseEvent m) {

        if (paintPanel.contains(m.getPoint())) {
                points.add(m.getPoint());
                xCord = m.getX();
                yCord = m.getY();
                System.out.println("x: " + xCord + " y: " + yCord);
        }

    }

    @Override
    public void mouseReleased(MouseEvent m) {
    }

}


推荐答案

Swing中的绘画具有破坏性。

Painting in Swing is destructive.

也就是说,当Swing请求在组件上发生重绘时,组件应该清除以前绘制的内容并自行更新。

That is to say, when Swing requests that a repaint occur on a component, the component is expected to clear what ever was previously paint and update itself.

您的颜色问题是您只能指定一种颜色。

The problem with your color issue is that you only ever have a single color specified.

一种可能的解决方案是绘制到后备缓冲区(如 BufferedImage )而不是依赖 paintComponent

A possible solution would be to paint to backing buffer (like BufferedImage) instead of relying on paintComponent.

每次调用 paintComponent 时重新绘制所有点,你只需要绘制 BufferedImage

Instead of repainting all the dots each time paintComponent is called, you would simply paint the BufferedImage instead.

至于你的鼠标问题,你需要实现一个 MouseMotionListener ,这将允许您检测鼠标拖过表面的时间,绘制点迹线

As to your issue with the mouse, you need to implement a MouseMotionListener, this will allow you to detect when the mouse is dragged across the surface, painting a trail of dots

使用非常基本的示例进行更新

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SimplePaint04 {

    public static void main(String[] args) {
        new SimplePaint04();
    }

    public SimplePaint04() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private PaintPane paintPane;

        public TestPane() {
            setLayout(new BorderLayout());
            add((paintPane = new PaintPane()));
            add(new ColorsPane(paintPane), BorderLayout.SOUTH);
        }
    }

    public class ColorsPane extends JPanel {

        public ColorsPane(PaintPane paintPane) {
            add(new JButton(new ColorAction(paintPane, "Red", Color.RED)));
            add(new JButton(new ColorAction(paintPane, "Green", Color.GREEN)));
            add(new JButton(new ColorAction(paintPane, "Blue", Color.BLUE)));
        }

        public class ColorAction extends AbstractAction {

            private PaintPane paintPane;
            private Color color;

            private ColorAction(PaintPane paintPane, String name, Color color) {
                putValue(NAME, name);
                this.paintPane = paintPane;
                this.color = color;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                paintPane.setForeground(color);
            }

        }

    }

    public class PaintPane extends JPanel {

        private BufferedImage background;

        public PaintPane() {
            setBackground(Color.WHITE);
            setForeground(Color.BLACK);
            MouseAdapter handler = new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    drawDot(e.getPoint());
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    drawDot(e.getPoint());
                }

            };
            addMouseListener(handler);
            addMouseMotionListener(handler);
        }

        protected void drawDot(Point p) {
            if (background == null) {
                updateBuffer();;
            }

            if (background != null) {
                Graphics2D g2d = background.createGraphics();
                g2d.setColor(getForeground());
                g2d.fillOval(p.x - 5, p.y - 5, 10, 10);
                g2d.dispose();
            }
            repaint();
        }

        @Override
        public void invalidate() {
            super.invalidate();
            updateBuffer();
        }

        protected void updateBuffer() {

            if (getWidth() > 0 && getHeight() > 0) {
                BufferedImage newBuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics2D g2d = newBuffer.createGraphics();
                g2d.setColor(Color.WHITE);
                g2d.fillRect(0, 0, getWidth(), getHeight());
                if (background != null) {
                    g2d.drawImage(background, 0, 0, this);
                }
                g2d.dispose();
                background = newBuffer;
            }

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (background == null) {
                updateBuffer();
            }
            g2d.drawImage(background, 0, 0, this);
            g2d.dispose();
        }
    }
}

这篇关于绘画时关于Java绘图程序的多个问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆