4

我正在使用鼠标制作一个矩形选择器,并且我drawRect周围有一个普通的矩形。当宽度或高度变为负数时,矩形被填充。有没有什么办法解决这一问题?

这是我的代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class Pie extends JPanel{
  public boolean running = true;
  public Rectangle mouseRect;
  public Rectangle rectBounds;
  public int x1,y1,x2,y2;
  public boolean showRect = false;

 public Pie(){
     setFocusable(true);
     MAdapter mama = new MAdapter();
     setDoubleBuffered(true);
     this.addMouseListener(new MAdapter());
     this.addMouseMotionListener(mama);
     setBackground(Color.black);
     Thread update = new Thread(){
         public void run(){
             while(running){
                 repaint();
                 try{Thread.sleep(2);}catch(InterruptedException e){}
             }
         }
     };
     update.start();
 }

 public void paintComponent(Graphics g){
     super.paintComponent(g);           
     //if(y2 < y1) y2 = y1;                  
     if(showRect){
         g.setColor(new Color(0,250,0,50));
         g.fillRect(x1,y1,x2 - x1,y2 - y1);
         g.setColor(new Color(0,255,0));            
         g.drawRect(x1 - 1,y1 - 1,x2 - x1 + 1,y2 - y1 + 1);
     }
 }

 class MAdapter extends MouseAdapter{
     public void mousePressed(MouseEvent e){
            showRect = true;
            x1 = e.getX();
            y1 = e.getY();
            x2 = e.getX();
            y2 = e.getY();
        }
     public void mouseDragged(MouseEvent e){
        x2 = e.getX();
        y2 = e.getY();
        rectBounds = new Rectangle(x1,y1,x2 - x1, y2 - y1);
     }
        public void mouseReleased(MouseEvent e){
            showRect = false;
            rectBounds = new Rectangle(x1,y1,x2 - x1, y2 - y1);
            x1 = 0;
            y1 = 0;
            x2 = 0;
            y2 = 0;
        }
 }

 public static void main(String[] args){
     JFrame f = new JFrame("Aber");
     f.setSize(500,500);
     f.setResizable(true);
     f.setVisible(true);
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     f.setLocationRelativeTo(null);
     f.add(new Pie());
   }
 }

有什么我做错了吗?

4

2 回答 2

3

您使用 Thread 并且重绘是错误且不必要的。请删除您的代码的那部分,而只需在 MouseListener 中调用 repaint。使用Math.abs(...),Math.min(...)Math.max(...)来帮助您绘制表现更好的矩形。例如,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;

import javax.swing.*;

public class Pie2 extends JPanel {
   private static final int PREF_W = 500;
   private static final int PREF_H = 500;
   private static final Color BACKGROUND = Color.black;
   private static final Color RECT_COLOR = Color.green;
   private static final Color RECT_FILL_COLOR = new Color(0,250,0,50);
   private Rectangle2D rect = null;

   public Pie2() {
      setBackground(BACKGROUND);
      MyMouseAdapater mouseAdapater = new MyMouseAdapater();
      addMouseListener(mouseAdapater);
      addMouseMotionListener(mouseAdapater);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public void setRect(Rectangle2D rect) {
      this.rect = rect;
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (rect != null) {
         Graphics2D g2 = (Graphics2D) g;
         g2.setColor(RECT_FILL_COLOR);
         g2.fill(rect);
         g2.setColor(RECT_COLOR);
         g2.draw(rect);
      }
   }

   private class MyMouseAdapater extends MouseAdapter {
      private Point p1;

      @Override
      public void mousePressed(MouseEvent e) {
         if (e.getButton() != MouseEvent.BUTTON1) {
            return;
         }
         p1 = e.getPoint();
         drawRect(p1);
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (p1 == null) {
            return;
         }
         drawRect(e.getPoint());
      }

      private void drawRect(Point p2) {
         int x = Math.min(p1.x, p2.x);
         int y = Math.min(p1.y, p2.y);
         int w = Math.abs(p1.x - p2.x);
         int h = Math.abs(p1.y - p2.y);         

         Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
         Pie2.this.setRect(rect);
         Pie2.this.repaint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (e.getButton() != MouseEvent.BUTTON1) {
            return;
         }
         drawRect(e.getPoint());

      }
   }

   private static void createAndShowGui() {
      Pie2 mainPanel = new Pie2();

      JFrame frame = new JFrame("Pie2");
      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();
         }
      });
   }
}

关键代码在这里:

  private void drawRect(Point p2) {
     int x = Math.min(p1.x, p2.x);
     int y = Math.min(p1.y, p2.y);
     int w = Math.abs(p1.x - p2.x);
     int h = Math.abs(p1.y - p2.y);         

     Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
     Pie2.this.setRect(rect);
     Pie2.this.repaint();
  }

请注意使用数学库方法进行计算,无论第一个点相对于第二个点在哪里。

于 2013-09-01T00:17:52.270 回答
0

每个人都感谢您的回答,但我决定以这种方式用线条制作边框更容易:

public void paintComponent(Graphics g){
     super.paintComponent(g);                        
     if(showRect){
         g.setColor(new Color(0,250,0,50));
         g.fillRect(x1,y1,x2 - x1,y2 - y1);
         g.setColor(new Color(0,255,0));            
         g.drawLine(x1, y1, x2, y1);
         g.drawLine(x1, y2, x2, y2);
         g.drawLine(x1, y1, x1, y2);
         g.drawLine(x2, y1, x2, y2);

     }

 }
于 2013-09-01T00:37:29.203 回答