在java中绘制线条

此代码存在许多问题

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. 当滚动条上下移动时,我想沿着图像移动线,我该怎么做?

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

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

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


例:

 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) {} } 

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

截图

 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. 不要扩展任何东西(尤其不是JFrame )。
  2. 保持对已加载的原始BufferedImage的引用。
  3. 当鼠标事件发生时(在标签上,如其他人所述),将线条绘制到图像副本,然后将其用于标签。
  4. 将标签放在一个没有约束的GridBagLayout面板中,因此它居中。
  5. 将面板拖放到滚动窗格中,然后将其添加到父组件的某个约束(例如BorderLayout.CENTER )。

请注意,您还可以将行对象添加到可扩展集合(如ArrayListDefaultListModel ,然后将它们显示在JList以显示图像滚动窗格的WEST 。 这样可以更轻松地管理(并可能删除)线组。

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