在java中绘制线条

时间:2012-02-15 09:41:21

标签: java image swing graphics line

此代码存在许多问题

public class LineEx extends JFrame implements MouseMotionListener,MouseListener{
    int x1,y1,x2,y2;
    public LineEx(){
        JLabel image=new JLabel("");
        JFileChooser chooser=new JFileChooser();

        chooser.setCurrentDirectory(new File("."));
        int r=chooser.showOpenDialog(new JFrame());
        File file=chooser.getSelectedFile();
        if(r==JFileChooser.APPROVE_OPTION){
            try {
                BufferedImage bf;
                bf = ImageIO.read(file);
                ImageIcon icon=new ImageIcon(bf);
                image.setIcon(icon);
                image.setHorizontalAlignment(JLabel.CENTER);

            } catch (IOException ex) {
                Logger.getLogger(LineEx.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        JScrollPane jsp=new JScrollPane(image);
        getContentPane().add(jsp);
        image.addMouseListener(this);
        image.addMouseMotionListener(this);
        this.pack();
    }
    public static void main(String ar[]){
        LineEx line=new LineEx();
        line.setVisible(true);
        line.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void mouseClicked(MouseEvent e) {

    }

    public void mousePressed(MouseEvent e) {
        x1=e.getX();
        y1=e.getY();
    }

    public void mouseReleased(MouseEvent e) {
        JOptionPane.showMessageDialog(rootPane, "X1="+x1+"  Y1="+y1);
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }
    @Override
    public void paint(Graphics g){
        super.paintComponents(g);
        Graphics2D gd=(Graphics2D)g;
        gd.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Line2D line=new Line2D.Double(x1,y1,x2,y2);
        gd.draw(line);
    }

    public void mouseDragged(MouseEvent e) {
        x2=e.getX();
        y2=e.getY();
        repaint();
    }

    public void mouseMoved(MouseEvent e) {
    }
}
  1. MouseEvents没有得到精确的坐标,这意味着每当我绘制一条线时,它就不在其位置上。这背后的原因是什么?
  2. 当滚动条上下移动时,我想沿着图像移动线,我该怎么做?

3 个答案:

答案 0 :(得分:6)

  
      
  • MouseEvents没有得到精确的坐标,这意味着每当我绘制一条线时,它就不在其位置上。这背后的原因是什么?
  •   
  • 当滚动条上下移动时,我想沿着图像移动线,我该怎么做?
  •   

您从JLabel获取正确的坐标,但在JFrame上绘制。框架坐标从左上角开始,“包括”窗口标题/边框。

覆盖paintComponent上的JLabel方法,您将获得正确的插图和坐标。


示例:

class ImageComponent extends JComponent 
        implements MouseListener, MouseMotionListener {
    private final BufferedImage img;
    private Point p1, p2;

    public ImageComponent(URL url) throws IOException {
        img = ImageIO.read(url);
        setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
        addMouseListener(this);
        addMouseMotionListener(this);
    }
    @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), this);
        if (p1 != null && p2 != null)
            g.drawLine(p1.x, p1.y, p2.x, p2.y);
    }
    @Override public void mousePressed(MouseEvent e) {
        p1 = e.getPoint();
    }
    @Override public void mouseDragged(MouseEvent e) {
        mouseReleased(e);
    }
    @Override public void mouseReleased(MouseEvent e) {
        p2 = e.getPoint();
        repaint();
    }
    @Override public void mouseMoved(MouseEvent e) {}
    @Override public void mouseClicked(MouseEvent e) {}
    @Override public void mouseEntered(MouseEvent e) {}
    @Override public void mouseExited(MouseEvent e) {}
}

测试代码(生成此屏幕截图):

screenshot

public static void main(String[] args) throws Exception {

    final URL lenna =
        new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png");

    final ImageComponent image = new ImageComponent(lenna);

    JFrame frame = new JFrame("Test");
    frame.add(new JScrollPane(image));

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 300);
    frame.setVisible(true);
}

答案 1 :(得分:3)

  1. 不要扩展任何内容(尤其不是JFrame)。
  2. 保留对已加载的原始BufferedImage的引用。
  3. 当鼠标事件发生时(在标签上,如其他人所述),将线条绘制到图像的副本,然后将其用作标签。
  4. 将标签放在GridBagLayout没有约束的面板中,使其居中。
  5. 将面板拖放到滚动窗格中,然后将其添加到父组件的某个约束(例如BorderLayout.CENTER)。
  6. 请注意,您还可以将线对象添加到可展开的集合,例如ArrayListDefaultListModel,然后将其显示在JList的{​​{1}}中。图像滚动窗格。这样可以更轻松地管理(并可能删除)一组行。

答案 2 :(得分:2)

  1. 来源可能是JLabel边界的内容。
  2. 你有可见的矩形。将可见的矩形x和y添加到基本坐标。