在图像上绘制JPanel中的形状

我需要在JPanel的JLabel中显示的图像上绘制形状(圆形或自由线)。

我的代码基于如何在拖动光标时绘制没有间隙的细线? 并使用2次鼠标单击绘制一个圆圈 。

代码如下。 问题是,当我开始绘制时,图像消失,只有在我停止后才会重新出现。 如果我评论行super.paintComponent(g); 但这并不会发生,但是当我绘制圆圈时,它会保留以前位置的路径。

public static void main(String args[]) { try { URL url = new URL("http://sofzh.miximages.com/java/Porto-.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); 

}

/ *第0层:*加载背景图片* /

 public static void loadBackground() { JLabel lbImg = new JLabel(); lbImg.setBounds(0, 0, new ImageIcon(backgroundImage).getIconWidth(), new ImageIcon(backgroundImage).getIconHeight()); lbImg.setIcon(new ImageIcon(backgroundImage)); mp = new JPanel(new BorderLayout()); btnCircle.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { if(btnCircle.isEnabled()) { btnCircle.setEnabled(false); btnLine.setEnabled(true); } } }); btnLine.setEnabled(true); btnCircle.setEnabled(false); btnLine.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { if(btnLine.isEnabled()) { btnLine.setEnabled(false); btnCircle.setEnabled(true); } } }); mp.add(btnCircle); mp.add(btnLine); mp.add(lbImg); mp.add(p); 

}

/ *第1层:*注释:在背景图片上绘制任何东西! * /

  public static void loadAnnotation() { p = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(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) { if (!btnLine.isEnabled()) { g.drawLine(_start.x, _start.y, _end.x , _end.y); } } if (!btnCircle.isEnabled()) { g.drawOval(x, y, width, height); } } public Dimension getPreferredSize() { return new Dimension(1024, 600); } }; p.setLayout(new OverlayLayout(p)); p.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent me) { } @Override public void mousePressed(MouseEvent me) { last = me.getPoint(); dragging = isInsideEllipse(last); if (!dragging) { x = last.x; y = last.y; width = 0; height = 0; } p.repaint(); } @Override public void mouseReleased(MouseEvent me) { //_state = State.IDLE; last = null; dragging = false; _state = State.IDLE; p.repaint(); } @Override public void mouseEntered(MouseEvent me) { } @Override public void mouseExited(MouseEvent me) { } }); p.addMouseMotionListener(new MouseMotionListener() { @Override public void mouseDragged(MouseEvent me) { if(!btnLine.isEnabled()) { _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; } else { int dx = me.getX() - last.x; int dy = me.getY() - last.y; if (dragging) { x += dx; y += dy; } else { width += dx; height += dy; } last = me.getPoint(); p.repaint(); } } @Override public void mouseMoved(MouseEvent me) { //System.out.println("move"); _start = me.getPoint(); } }); } 

  1. 通过Graphics#drawImage(...)在您正在绘制的同一paintComponent方法中显示图像。 你可以在super.paintComponent(g)调用之后立即调用它。
  2. 或者在JLabel的paintComponent(...)方法中绘制图形,即显示图像的方法。

例如:

在此处输入图像描述

 import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.*; @SuppressWarnings("serial") public class DrawingPanel extends JPanel { private final static String PATH = "https://upload.wikimedia.org/wikipedia/commons/" + "thumb/7/7c/Thomas_Hicks_-_Leopold_Grozelier_-_Presidential_Candidate_" + "Abraham_Lincoln_1860_-_cropped_to_lithographic_plate.jpg/" + "463px-Thomas_Hicks_-_Leopold_Grozelier_-_Presidential_Candidate_" + "Abraham_Lincoln_1860_-_cropped_to_lithographic_plate.jpg"; private static final Color DRAWING_COLOR = new Color(255, 100, 200); private static final Color FINAL_DRAWING_COLOR = Color.red; private BufferedImage backgroundImg; private Point startPt = null; private Point endPt = null; private Point currentPt = null; private int prefW; private int prefH; public DrawingPanel() throws IOException { URL imgUrl = new URL(PATH); BufferedImage bImg = ImageIO.read(imgUrl); prefW = bImg.getWidth(); prefH = bImg.getHeight(); backgroundImg = new BufferedImage(prefW, prefH, BufferedImage.TYPE_INT_ARGB); Graphics g = backgroundImg.getGraphics(); g.drawImage(bImg, 0, 0, this); g.dispose(); MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); addMouseMotionListener(myMouseAdapter); addMouseListener(myMouseAdapter); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (backgroundImg != null) { g.drawImage(backgroundImg, 0, 0, this); } if (startPt != null && currentPt != null) { g.setColor(DRAWING_COLOR); int x = Math.min(startPt.x, currentPt.x); int y = Math.min(startPt.y, currentPt.y); int width = Math.abs(startPt.x - currentPt.x); int height = Math.abs(startPt.y - currentPt.y); g.drawRect(x, y, width, height); } } @Override public Dimension getPreferredSize() { return new Dimension(prefW, prefH); } public void drawToBackground() { Graphics g = backgroundImg.getGraphics(); g.setColor(FINAL_DRAWING_COLOR); int x = Math.min(startPt.x, endPt.x); int y = Math.min(startPt.y, endPt.y); int width = Math.abs(startPt.x - endPt.x); int height = Math.abs(startPt.y - endPt.y); g.drawRect(x, y, width, height); g.dispose(); startPt = null; repaint(); } private class MyMouseAdapter extends MouseAdapter { @Override public void mouseDragged(MouseEvent mEvt) { currentPt = mEvt.getPoint(); DrawingPanel.this.repaint(); } @Override public void mouseReleased(MouseEvent mEvt) { endPt = mEvt.getPoint(); currentPt = null; drawToBackground(); } @Override public void mousePressed(MouseEvent mEvt) { startPt = mEvt.getPoint(); } } private static void createAndShowGui() { DrawingPanel mainPanel = null; try { mainPanel = new DrawingPanel(); } catch (IOException e) { e.printStackTrace(); System.exit(-1); } JFrame frame = new JFrame("Drawing Panel"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } }