Graphics .drawRect is filled

I make a rectangle selector with the mouse, and I have a regular drawRect rectangle surrounding it. When the width or height becomes negative, the rectangle fills. Is there any way to fix this?

Here is my code:

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

Is there something I'm doing wrong?

+4
source share
2 answers

You use Thread, and redrawing is wrong and unnecessary. Please get rid of this part of your code and instead just call the redraw in MouseListener. Use Math.abs(...) , Math.min(...) and Math.max(...) to help you draw rectangles with higher quality. For instance,

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

If key code is here:

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

Note the use of the Math library methods to perform your calculations no matter where the first point refers to the second point.

+3
source

Thank you all for your answers, but I decided it was easier to just make the border with the lines this way:

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

Source: https://habr.com/ru/post/1499976/


All Articles