Рисование прямоугольника над существующей графической страницей - PullRequest
2 голосов
/ 19 октября 2011

У меня есть приложение Java, которое рисует рисунок.Я хочу дать пользователю возможность пометить область мышью (например, чтобы увеличить ее).Для этого я использую класс MouseMotionListener, и когда мышь (щелкают и затем) перемещают, я сохраняю местоположение выбранного в данный момент (это не окончательно, поскольку пользователь не отпустил мышь) прямоугольника и использую repaint() функция.Я хочу отобразить этот прямоугольник поверх исходного чертежа, делая его похожим на инструмент «Выделение» в MSPaint.

Проблема в том, что когда я вызываю функцию repaint(), вызывается метод paintComponent (Graphics page), в которомЯ использую метод super.paintComponent(page), который стирает мой рисунок.Однако, если я не использую этот метод, когда я знаю, что пользователь выбирает прямоугольник, я получаю, что все выбранные прямоугольники «упакованы» один над другим, и это нежелательный результат - я хочу отобразить текущий выбранныйтолько прямоугольник.

Я подумал, что смогу сохранить копию графической страницы чертежа и каким-то образом восстановить ее каждый раз, когда пользователь перемещает мышь, но я не смог найти документацию для полезных методов.

Большое спасибо,

Рон.

Редактировать: Вот соответствующие части моего кода:

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

Ответы [ 2 ]

4 голосов
/ 19 октября 2011

Могу поспорить, что вы получаете объект Graphics с помощью вызова getGraphics() для компонента и недовольны, так как при этом получается объект Graphics, который не сохраняется.Именно по этой причине вам не следует делать это, а просто рисовать внутри JPC-компонента paintComponent.Если вы сделаете это, все будут счастливы.

В качестве отступления - мы сможем помочь вам лучше, если вы расскажете нам более подробную информацию о вашей проблеме, например о том, как вы получаете графикуобъект и то, как вы пытаетесь нарисовать его, ключевые вопросы здесь.В противном случае мы ограничены дикими догадками о том, что вы пытаетесь сделать.

например,

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();
         }
      });
   }
}
1 голос
/ 19 октября 2011

Вам нужно перекрашивать при каждом движении мыши:

    public void mouseDragged(MouseEvent e){
        int x = e.getX();
        int y = e.getY();
        //Update the rectangle holder object with that point coordinates
        repaint();
    }

Возможно, у вас будет объект-прямоугольник-держатель для хранения начальной и конечной точек прямоугольника.Инициалы устанавливаются по щелчку мыши, финальные изменяются при перетаскивании мышью и отпускании мыши.

В методе paint очистите графику и нарисуйте прямоугольник с координатами в держателе.Это основная идея.

ОБНОВЛЕНИЕ: Как нарисовать новую фигуру поверх существующего изображения: я думаю о двух вариантах:

  1. Если вы рисуете только фигуры(например, линии, прямоугольники и другие элементы Java2D) вы можете иметь коллекцию, содержащую эти координаты фигур, и нарисовать их все на каждом paint.Плюсы: хорошо, когда есть несколько форм, позволяет отменить.Минусы: когда количество фигур увеличивается, метод paint будет занимать все больше и больше времени за каждый проход.
  2. Иметь «фоновое изображение».При каждом вызове paint сначала нарисуйте изображение, а затем активную форму сверху.когда активная фигура становится постоянной (onMouseReleased), она сохраняется в фоновом изображении.Плюсы: эффективно, постоянное время.Минусы: рисование большого фонового изображения при каждом движении мыши может быть «дорогим».
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...