Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
412 views
in Technique[技术] by (71.8m points)

java - Drawing a rectangle over an existing Graphics page

I have a Java application which draws a drawing. I want to give the user the possibility to mark an area with the mouse (in order to, for example, zoom into it). For that I use the MouseMotionListener class, and when the mouse is (clicked and then) moved, I save the location of the currently selected (it isn't final since the user haven't released the mouse) rectangle, and use the repaint() function. I wish to display that rectangle over the original drawing, making it similar to the Selection tool in MSPaint.

The problem is that when I call the repaint() function, the method paintComponent (Graphics page) is invoked, in which I use the method super.paintComponent(page) which erases my drawing. However, if I don't use that method when I know the user is selecting a rectangle, I get that all the selected rectangles are "packed" one above the other, and this is an undesirable result - I wish to display the currently selected rectangle only.

I thought I should be able to save a copy of the Graphics page of the drawing and somehow restore it every time the user moves the mouse, but I could not find any documentation for helpful methods.

Thank you very much,

Ron.

Edit: Here are the relevant pieces of my code:

public class DrawingPanel extends JPanel
{
public FractalPanel()
   {
      addMouseListener (new MyListener());
      addMouseMotionListener (new MyListener());

      setBackground (Color.black);
      setPreferredSize (new Dimension(200,200));
      setFocusable(true);
   }

public void paintComponent (Graphics page)
   {
        super.paintComponent(page);
        //that's where the drawing takes place: page.setColor(Color.red), page.drawOval(..) etc
   }
   private class MyListener implements MouseListener, MouseMotionListener
   {
   ...
      public void mouseDragged (MouseEvent event) 
      {
          //saving the location of the rectangle
          isHoldingRectangle = true;
          repaint();
       }
   }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm betting that you are getting your Graphics object via a getGraphics() call on a component, and are disatisfied since this obtains a Graphics object which does not persist. It is for this reason that you shouldn't do this but instead just do your drawing inside of the JPanel's paintComponent. If you do this all will be happy.

As an aside -- we'll be able to help you better if you tell us more of the pertinent details of your problem such as how you're getting your Graphics object and how you're trying to draw with it, key issues here. Otherwise we're limited to taking wild guesses about what you're trying to do.

e.g.,

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class MandelDraw extends JPanel {
private static final String IMAGE_ADDR = "http://upload.wikimedia.org/" +
        "wikipedia/commons/thumb/b/b3/Mandel_zoom_07_satellite.jpg/" +
        "800px-Mandel_zoom_07_satellite.jpg";
private static final Color DRAWING_RECT_COLOR = new Color(200, 200, 255);
private static final Color DRAWN_RECT_COLOR = Color.blue;

   private BufferedImage image;
   private Rectangle rect = null;
   private boolean drawing = false;

   public MandelDraw() {
      try {
         image = ImageIO.read(new URL(IMAGE_ADDR));
         MyMouseAdapter mouseAdapter = new MyMouseAdapter();
         addMouseListener(mouseAdapter);
         addMouseMotionListener(mouseAdapter);
      } catch (MalformedURLException e) {
         e.printStackTrace();
         System.exit(-1);
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      if (image != null) {
         return new Dimension(image.getWidth(), image.getHeight());
      }
      return super.getPreferredSize();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D)g;
      if (image != null) {
         g.drawImage(image, 0, 0, null);
      }
      if (rect == null) {
         return;
      } else if (drawing) {
         g2.setColor(DRAWING_RECT_COLOR);
         g2.draw(rect);
      } else {
         g2.setColor(DRAWN_RECT_COLOR);
         g2.draw(rect);
      }
   }

   private class MyMouseAdapter extends MouseAdapter {
      private Point mousePress = null; 
      @Override
      public void mousePressed(MouseEvent e) {
         mousePress = e.getPoint();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         drawing = true;
         int x = Math.min(mousePress.x, e.getPoint().x);
         int y = Math.min(mousePress.y, e.getPoint().y);
         int width = Math.abs(mousePress.x - e.getPoint().x);
         int height = Math.abs(mousePress.y - e.getPoint().y);

         rect = new Rectangle(x, y, width, height);
         repaint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         drawing = false;
         repaint();
      }

   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("MandelDraw");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new MandelDraw());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...