【问题标题】:How to draw thin line with no gap while dragging the cursor?拖动光标时如何绘制没有间隙的细线?
【发布时间】:2012-05-10 10:25:33
【问题描述】:

我有以下这个类,它刷新第 0 层中的 jpeg 文件,第 1 层用于绘制/绘画/素描与粉碎事物相关的任何内容。但是在我的绘图中,当我想做一条细线时,它会断裂。因为鼠标光标移动需要更慢。

如何解决鼠标快速移动,线保持连接?

Annotation.java

package test;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Annotation {

  // Image
  private static Image backgroundImage;
  private static BufferedImage _bufImage = null;
  
  // Enum 
  public  static enum Shape { RECTANGLE, OVAL, LINE }
  private static enum State { IDLE, DRAGGING }       
  
  private static final Shape INIIIAL_SHAPE = Shape.RECTANGLE;
  private static final Color INITIAL_COLOR = Color.RED;  
  private static Shape _shape = INIIIAL_SHAPE;
  private static Color _color = INITIAL_COLOR;
  
  private static State _state = State.IDLE;
  private static Point _start = null; 
  private static Point _end   = null;
  
  // JPanel
  private static JPanel p;
  private static JPanel mp;
   
  /* Run: */
  public static void main(String args[]) {   
    c();
  }

  /* GUI */
  public static void c() {      
    try {
      backgroundImage = ImageIO.read(new File("/var/tmp/test.jpeg"));
    } catch (IOException e) {
      e.printStackTrace();
    }
    
    myTimer();
    loadAnnotation();
    loadBackground();
    
    JFrame f; 
    f = new JFrame();    
    f.setLayout(new BorderLayout());
    f.add(mp);
    f.pack();
    f.setVisible(true);    
  }

  /* 5 seconds to load picture */
  public static void myTimer() {   
    javax.swing.Timer t = new javax.swing.Timer(5000, new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        try {
          backgroundImage = ImageIO.read(new File("/var/tmp/test.jpeg"));    
          mp.repaint();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    });
    t.start();
  }
  
  /* Layer 0: 
   * Load background picture */
  public static void loadBackground() {    
    mp = new JPanel() {
      public void paintComponent(Graphics g) {       
        super.paintComponent(g);
        g.drawImage(backgroundImage, 0, 0, 1024, 600, null);            
      }
      public Dimension getPreferredSize() {
        return new Dimension(1024, 600);
      }
    };    
    mp.add(p);        
  }

  /* Layer 1: 
   * Annotation: Draw on top of background picture anything! */
  public static void loadAnnotation() {
        
    p = new JPanel() {
      public void paintComponent(Graphics g) {       
        Graphics2D g2 = (Graphics2D)g;
        g2.setColor(Color.RED);
        if (_bufImage == null) {        
            int w = this.getWidth();
            int h = this.getHeight();
            _bufImage  = new BufferedImage(1024,600, BufferedImage.TRANSLUCENT);
            Graphics2D gc = _bufImage.createGraphics();
        }
        
        g2.drawImage(_bufImage, null, 0, 0);        
        if (_state == State.DRAGGING) {
          g2.drawLine(_start.x, _start.y, _end.x  , _end.y);
        }        
      }

      public Dimension getPreferredSize() {
        return new Dimension(1024, 600);
      }      
    };
    
    p.setLayout(new FlowLayout());
    p.addMouseListener(new MouseListener() {
      @Override
      public void mouseClicked(MouseEvent me) {
      }

      @Override
      public void mousePressed(MouseEvent me) {
      }

      @Override
      public void mouseReleased(MouseEvent me) {
        //_state = State.IDLE;
        _state = State.IDLE;
      }

      @Override
      public void mouseEntered(MouseEvent me) {
      }

      @Override
      public void mouseExited(MouseEvent me) {
      }
    });
    
    p.addMouseMotionListener(new MouseMotionListener() {
      
      @Override
      public void mouseDragged(MouseEvent me) {
        System.out.println("drag");        
        _state = State.DRAGGING; 
        _start = me.getPoint();
        _end   = _start;
        if (_state == State.DRAGGING) {
            Graphics2D g2 = _bufImage.createGraphics();
            g2.setColor(Color.red);
            g2.setStroke(new BasicStroke(90));   
            g2.fillOval(_start.x, _start.y, 10, 10);            
            p.repaint();                        
        }         
      }
      
      @Override
      public void mouseMoved(MouseEvent me) {
        System.out.println("move");
      }
    });
    
    JButton pm = new JButton("+");
    pm.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent ae) {
      }
    });    
    p.add(pm);       
    p.setOpaque(true);    
  }
  
}

【问题讨论】:

    标签: java image swing graphics2d


    【解决方案1】:

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class Annotation {
    
      // Image
      private static Image backgroundImage;
      private static BufferedImage _bufImage = null;
    
      // Enum
      public  static enum Shape { RECTANGLE, OVAL, LINE }
      private static enum State { IDLE, DRAGGING }
    
      private static final Shape INIIIAL_SHAPE = Shape.RECTANGLE;
      private static final Color INITIAL_COLOR = Color.RED;
      private static Shape _shape = INIIIAL_SHAPE;
      private static Color _color = INITIAL_COLOR;
    
      private static State _state = State.IDLE;
      private static Point _start = null;
      private static Point _end   = null;
    
      // JPanel
      private static JPanel p;
      private static JPanel mp;
    
      /* Run: */
      public static void main(String args[]) {
        c();
      }
    
      /* GUI */
      public static void c() {
        try {
            URL url = new URL("http://pscode.org/media/stromlo2.jpg");
          backgroundImage = ImageIO.read(url);
        } catch (Exception e) {
          e.printStackTrace();
        }
    
        loadAnnotation();
        loadBackground();
    
        JFrame f;
        f = new JFrame();
        f.setLayout(new BorderLayout());
        f.add(mp);
        f.pack();
        f.setVisible(true);
      }
    
      /* Layer 0:
       * Load background picture */
      public static void loadBackground() {
        mp = new JPanel() {
          public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), null);
          }
          public Dimension getPreferredSize() {
            return new Dimension(backgroundImage.getWidth(this), backgroundImage.getHeight(this));
          }
        };
        mp.add(p);
      }
    
      /* Layer 1:
       * Annotation: Draw on top of background picture anything! */
      public static void loadAnnotation() {
    
        p = new JPanel() {
          public void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D)g;
            g2.setColor(Color.RED);
            if (_bufImage == null) {
                int w = this.getWidth();
                int h = this.getHeight();
                _bufImage  = new BufferedImage(1024,600, BufferedImage.TRANSLUCENT);
                Graphics2D gc = _bufImage.createGraphics();
            }
    
            g2.drawImage(_bufImage, null, 0, 0);
            if (_state == State.DRAGGING) {
              g2.drawLine(_start.x, _start.y, _end.x  , _end.y);
            }
          }
    
          public Dimension getPreferredSize() {
            return new Dimension(1024, 600);
          }
        };
    
        p.setLayout(new FlowLayout());
        p.addMouseListener(new MouseListener() {
          @Override
          public void mouseClicked(MouseEvent me) {
          }
    
          @Override
          public void mousePressed(MouseEvent me) {
          }
    
          @Override
          public void mouseReleased(MouseEvent me) {
            //_state = State.IDLE;
            _state = State.IDLE;
          }
    
          @Override
          public void mouseEntered(MouseEvent me) {
          }
    
          @Override
          public void mouseExited(MouseEvent me) {
          }
        });
    
        p.addMouseMotionListener(new MouseMotionListener() {
    
          @Override
          public void mouseDragged(MouseEvent me) {
            _state = State.DRAGGING;
            _end   = me.getPoint();
            if (_state == State.DRAGGING) {
                Graphics2D g2 = _bufImage.createGraphics();
                g2.setColor(Color.red);
                g2.setStroke(new BasicStroke(2));
                g2.drawLine(_start.x, _start.y, _end.x, _end.y);
                p.repaint();
            }
            _start = _end;
          }
    
          @Override
          public void mouseMoved(MouseEvent me) {
            //System.out.println("move");
            _start = me.getPoint();
          }
        });
    
        JButton pm = new JButton("+");
        pm.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent ae) {
          }
        });
        p.add(pm);
        p.setOpaque(true);
      }
    
    }
    

    【讨论】:

    • 不客气。如果您像我一样发布 SSCCE(图像的热链接),那会早几分钟。 ;) 但是 +1 用于发布可编译的代码。 :)
    【解决方案2】:

    我通过在点之间绘制矩形解决了这个问题,使用描边大小(基本描边)作为高度。这听起来像是一个令人讨厌的解决方案,但实际上它做得很好

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多