【问题标题】:Graphics.drawRect being filledGraphics.drawRect 被填充
【发布时间】:2013-09-04 10:17:24
【问题描述】:

我正在使用鼠标制作一个矩形选择器,它周围有一个普通的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());
   }
 }

我做错了什么吗?

【问题讨论】:

  • 很好的问题,有一个 SSCCE,但不是一个很好的答案。如果你想改变你的程序,让它现在允许用户绘制多个矩形,并允许用户选择甚至删除绘制的矩形,该怎么办?为此目的使用 Rectangle 或 Rectangle2D 对象会更容易做到这一点,相信我。
  • 我不知道是否有一个硬性规定规定宽度/高度必须 >= 0,但正如您所发现的,当涉及到绘画时,它会使不同

标签: java swing graphics rectangles


【解决方案1】:

您使用线程并重新绘制是错误且不必要的。请删除您的代码的那部分,而只需在 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();
  }

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

【讨论】:

    【解决方案2】:

    感谢大家的回答,但我决定用这种方式制作边框更容易:

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

    【讨论】:

      猜你喜欢
      • 2023-02-05
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 2014-06-18
      相关资源
      最近更新 更多