简体   繁体   English

在 JPanel 中在图像上绘制形状

[英]Drawing shapes in JPanel over an image

I need to draw shapes (circle or free line) over an image that is shown in a JLabel of a JPanel.我需要在 JPanel 的 JLabel 中显示的图像上绘制形状(圆形或自由线)。

I based my code on the questions How to draw thin line with no gap while dragging the cursor?我的代码基于以下问题: 如何在拖动光标时绘制没有间隙的细线? and Draw a circle using 2 mouse clicks .使用 2 次鼠标点击绘制一个圆圈

The code is bellow.代码如下。 The problem is that when I start drawing the image disappears and only reappears after I stop.问题是,当我开始绘制图像时,图像消失了,只有在我停止后才会重新出现。 If I comment the line super.paintComponent(g);如果我评论这行super.paintComponent(g); that doesnt happen but when I draw the circle it maintains a path of the previous positions.这不会发生,但是当我绘制圆圈时,它会保持先前位置的路径。

public static void main(String args[]) {
try {
    URL url = new URL("http://www.senhoritatours.com/wp-content/uploads/2014/05/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);

} }

/* Layer 0: * Load background picture */ /* 第 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);

} }

/* Layer 1: * Annotation: Draw on top of background picture anything! /* 第 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();

  }
});
}

Either任何一个

  1. Display the image in the same paintComponent method that you're doing your drawing in, via Graphics#drawImage(...) .通过Graphics#drawImage(...)在您正在绘图的同一个paintComponent 方法中显示图像。 You would call this immediately after the super.paintComponent(g) call.您可以在super.paintComponent(g)调用之后立即调用它。
  2. Or do your drawing in the paintComponent(...) method of your JLabel, the one displaying the image.或者在 JLabel 的paintComponent(...)方法中进行绘图,即显示图像的方法。

For example:例如:

在此处输入图片说明

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();
         }
      });
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM