在图像上绘制JPanel中的形状

时间:2015-02-12 16:05:28

标签: java image swing jframe paintcomponent

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

我的代码基于问题How to draw thin line with no gap while dragging the cursor?Draw a circle using 2 mouse clicks

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

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

}

/ *第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 个答案:

答案 0 :(得分:5)

要么

  1. 通过Graphics#drawImage(...)在您正在进行绘制的同一paintComponent方法中显示图像。您可以在super.paintComponent(g)电话后立即拨打电话。
  2. 或者使用JLabel的paintComponent(...)方法进行绘制,即显示图像的方法。

  3. 例如:

    enter image description here

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