2

我有一个绘画程序,我已经完成了所有按钮和滑块,但是我对实际绘画本身有问题。当我将光标拖过屏幕而不是一条完整的线时,我几乎得到了一条我不想要的虚线。这是MouseListenerinJPanel和的代码BufferedImage

      public void mouseDragged(MouseEvent e) {
          Graphics g=buffered.getGraphics();
          g.setColor(mycol);
              Graphics2D graph=(Graphics2D)g;
          BasicStroke stroke=new BasicStroke(30);
          graph.setStroke(stroke);
              //  g.fillRect(xcor, ycor, 20, 20);
          /  /varx=e.getX();
            ycor=e.getY();
             xcor=e.getX();
            int bad=xcor;
            int good=ycor;
            graph.drawLine(xcor, ycor, bad, good);
           // buffered.setRGB(xcor, ycor, mycol.getRGB());
            repaint();
            // g.drawLine(xcor, ycor, x, x)
             repaint();


        }
4

3 回答 3

6
  • 只是为了证明我的评论是正确的,我添加了这个答案,尽管这里的评论略有变化,即使用 of mousePressed(...)而不是mouseClicked(...).
  • 另外一个补充是,由于您想要 so 的Graphics2D对象BufferedImage而不是使用返回对象的getGraphics()always use ,因此您不必担心其中的 Cast 事物。createGraphics()Graphics2D

    请看下面的例子:

=======================

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.net.URL;
import javax.swing.*;
import javax.imageio.ImageIO;

public class PaintingExample {

    private BufferedImage bImage;
    private ImageIcon image;
    private JLabel imageLabel;
    private int xClicked = 0;
    private int yClicked = 0;
    private int xDragged = 0;
    private int yDragged = 0;

    private MouseAdapter mouseListener = new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent me) {
            xClicked = me.getX();
            yClicked = me.getY();
        }

        @Override
        public void mouseDragged(MouseEvent me) {
            xDragged = me.getX();
            yDragged = me.getY();

            Graphics2D g2 = bImage.createGraphics();
            g2.setColor(Color.WHITE);
            BasicStroke stroke=new BasicStroke(30);
            g2.setStroke(stroke);
            g2.drawLine(xClicked, yClicked, xDragged, yDragged);
            g2.dispose();
            imageLabel.setIcon(new ImageIcon(bImage));
        }
    };

    public PaintingExample() {
        try {
            bImage = ImageIO.read(new URL(
                    "http://i.imgur.com/fHiBMwI.jpg"));
            image = new ImageIcon(bImage);          
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void displayGUI() {
        JFrame frame = new JFrame("Painting on Image");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imageLabel = new JLabel(image);
        imageLabel.addMouseListener(mouseListener);
        imageLabel.addMouseMotionListener(mouseListener);

        contentPane.add(imageLabel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new PaintingExample().displayGUI();
            }
        });
    }
}
于 2012-08-09T18:59:58.030 回答
3

如果我正确理解您的问题,那么您将遇到的主要问题是拖动鼠标时您将收到的更新数量。

即使您缓慢拖动,您也不会总是收到每个像素移动的通知,而是系统等待“空闲”状态(或阈值)通知您,因此它“看起来”是一个平滑的移动。

我可以通过稍微修改你的代码来把它放在一起

你好 ;)

private MouseAdapter mouseListener =
    new MouseAdapter() {
        private boolean paint = false;
        @Override
        public void mousePressed(MouseEvent me) {

            xClicked = me.getX();
            yClicked = me.getY();
            xDragged = xClicked;
            yDragged = yClicked;

            paint = true;

        }

        @Override
        public void mouseReleased(MouseEvent e) {

            xClicked = -1;
            xClicked = -1;
            xDragged = -1;
            yDragged = -1;

            paint = false;

        }

        @Override
        public void mouseMoved(MouseEvent me) {
        }

        @Override
        public void mouseDragged(MouseEvent me) {

            if (paint) {

                xClicked = xDragged;
                yClicked = yDragged;

                xDragged = me.getX();
                yDragged = me.getY();

                xDragged = me.getX();
                yDragged = me.getY();

                Graphics2D g2 = bImage.createGraphics();
                g2.setColor(Color.WHITE);
                g2.drawLine(xClicked, yClicked, xDragged, yDragged);
                g2.dispose();
                imageLabel.setIcon(new ImageIcon(bImage));

                me.getComponent().invalidate();
                me.getComponent().repaint();

            }

        }
    };

基本上,这个想法是从最后一个“已知位置”到当前位置画一条线。

希望这是在球场

于 2012-08-09T22:57:45.957 回答
2

30 像素是一条很宽的线,我可以想象在没有抗锯齿的情况下绘制时,它会看起来锯齿;这可能就是您所看到的。您可能想尝试类似的东西

graph.setRenderingHint(
    RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);

另一方面,也许你已经开始抗锯齿了,你想把它关掉;然后

graph.setRenderingHint(
    RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_OFF);

其中之一保证会改变图像的外观;希望它会更符合您的喜好。

于 2012-08-09T15:44:51.843 回答