在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) { } }
- MouseEvents没有获得精确的坐标,这意味着无论何时我绘制一条线,它都不在其位置上。 这背后的原因是什么?
- 当滚动条上下移动时,我想沿着图像移动线,我该怎么做?
- 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); }
- 不要扩展任何东西(尤其不是
JFrame
)。 - 保持对已加载的原始
BufferedImage
的引用。 - 当鼠标事件发生时(在标签上,如其他人所述),将线条绘制到图像的副本,然后将其用于标签。
- 将标签放在一个没有约束的
GridBagLayout
面板中,因此它居中。 - 将面板拖放到滚动窗格中,然后将其添加到父组件的某个约束(例如
BorderLayout.CENTER
)。
请注意,您还可以将行对象添加到可扩展集合(如ArrayList
或DefaultListModel
,然后将它们显示在JList
以显示图像滚动窗格的WEST
。 这样可以更轻松地管理(并可能删除)线组。
- 来源可能是JLabel边界的内容。
- 你有可见的矩形。 将可见的rect x和y添加到基本坐标。