.drawLine()问题和缓冲图像

时间:2012-08-09 15:34:42

标签: java swing jpanel bufferedimage mouse-listeners

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

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


        }

3 个答案:

答案 0 :(得分:5)

  • 为了证明我的评论是正确的,我正在添加这个答案,虽然是轻微的 从评论的变化是在这里,这是使用 mousePressed(...)代替mouseClicked(...)
  • 还有一个补充,因为你需要Graphics2D对象 BufferedImage所以不要总是使用getGraphics() createGraphics()返回Graphics2D对象,因此你 我真的不必担心Cast中的东西。

    请看下面的示例:

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

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

答案 1 :(得分:2)

30个像素是一条非常宽的线,我可以想象,在没有抗锯齿的情况下绘制时,它会看起来非常锯齿状;这可能就是你所看到的。你可能想尝试像

这样的东西
graph.setRenderingHint(
    RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);

另一方面,也许你已经已经获得了抗锯齿功能,而你想要将其关闭;然后

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

其中一个可以保证改变图像的外观;希望它更符合你的喜好。

答案 2 :(得分:2)

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

即使您慢慢拖动,也不会始终通知您每个像素的移动,而是系统等待“空闲”状态(或阈值)通知您,使其“显示”为平滑移动。

我能够通过稍微修改你的代码把它放在一起

Hello ;)

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

            }

        }
    };

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

希望这是在球场