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

あなたはスレッドを使用しており、再描画は間違っていて不要です。コードのその部分を取り除き、代わりに 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();
  }

最初の Point が 2 番目の Point に対してどこにあるかに関係なく、Math ライブラリ メソッドを使用して計算を行うことに注意してください。

于 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 に答える