如何使用鼠标拖动事件在Java小程序上绘制一个矩形并使其保持不变

我的程序可以绘制矩形。 我有两个问题我无法解决。 绘制矩形后,它不会停留。 我唯一的代码清除canvas下的canvas,重绘仅在鼠标拖动时调用。 为什么当鼠标释放或鼠标移动时我的canvas清晰。 第二件事不是问题,而是我无法弄清楚的事情,当我的矩形的高度或宽度为负时,矩形填充为黑色。

package pracpapp2; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MouseTracker4July extends JFrame implements MouseListener, MouseMotionListener { private static final long serialVersionUID = 1L; private JLabel mousePosition; int x, y; int x1, x2, y1, y2; int w, h; private JLabel recStart; private JLabel recStop; private JLabel cords; // set up GUI and register mouse event handlers public MouseTracker4July() { super( "Rectangle Drawer" ); mousePosition = new JLabel(); mousePosition.setHorizontalAlignment(SwingConstants.CENTER); getContentPane().add( mousePosition, BorderLayout.CENTER ); JLabel text1 = new JLabel(); text1.setText( "At the center the mouse pointer's coordinates will be displayed." ); getContentPane().add( text1, BorderLayout.SOUTH ); recStart = new JLabel(); getContentPane().add(recStart, BorderLayout.WEST); recStop = new JLabel(); getContentPane().add(recStop, BorderLayout.EAST); cords = new JLabel(); getContentPane().add(cords, BorderLayout.NORTH); addMouseListener( this ); // listens for own mouse and addMouseMotionListener( this ); // mouse-motion events setSize( 800, 600 ); setVisible( true ); } // MouseListener event handlers // handle event when mouse released immediately after press public void mouseClicked( MouseEvent event ) { mousePosition.setText( "Clicked at [" + event.getX() + ", " + event.getY() + "]" ); } // handle event when mouse pressed public void mousePressed( MouseEvent event ) { mousePosition.setText( "Pressed at [" +(x1 = event.getX()) + ", " + (y1 = event.getY()) + "]" ); recStart.setText( "Start: [" + x1 + ", " + y1 + "]" ); } // handle event when mouse released after dragging public void mouseReleased( MouseEvent event ) { mousePosition.setText( "Released at [" +(x2 = event.getX()) + ", " + (y2 = event.getY()) + "]" ); recStop.setText( "End: [" + x2 + ", " + y2 + "]" ); } // handle event when mouse enters area public void mouseEntered( MouseEvent event ) { mousePosition.setText( "Mouse entered at [" + event.getX() + ", " + event.getY() + "]" ); } // handle event when mouse exits area public void mouseExited( MouseEvent event ) { mousePosition.setText( "Mouse outside window" ); } // MouseMotionListener event handlers // handle event when user drags mouse with button pressed public void mouseDragged( MouseEvent event ) { mousePosition.setText( "Dragged at [" + (x = event.getX()) + ", " + (y = event.getY()) + "]" ); // call repaint which calls paint repaint(); } // handle event when user moves mouse public void mouseMoved( MouseEvent event ) { mousePosition.setText( "Moved at [" + event.getX() + ", " + event.getY() + "]" ); } public void paint(Graphics g) { super.paint(g); // clear the frame surface g.drawString("Start Rec Here", x1, y1); g.drawString("End Rec Here", x, y); w = x1 - x; h = y1 - y; w = w * -1; h = h * -1; g.drawRect(x1, y1, w, h); cords.setText( "w = " + w + ", h = " + h); } public static void main( String args[] ) { MouseTracker4July application = new MouseTracker4July(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } } // end class MouseTracker 

好的,重新阅读你的问题之后,似乎你可以少关心多个矩形:)

这是一个一次只有一个解决方案(接近你必须开始的):

 import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingConstants; public class MouseTracker4July extends JFrame implements MouseListener, MouseMotionListener { private static final long serialVersionUID = 1L; private final JLabel mousePosition; int x1, x2, y1, y2; int x, y, w, h; private final JLabel recStart; private final JLabel recStop; private final JLabel cords; // set up GUI and register mouse event handlers boolean isNewRect = true; public MouseTracker4July() { super( "Rectangle Drawer" ); this.mousePosition = new JLabel(); this.mousePosition.setHorizontalAlignment( SwingConstants.CENTER ); getContentPane().add( this.mousePosition, BorderLayout.CENTER ); JLabel text1 = new JLabel(); text1.setText( "At the center the mouse pointer's coordinates will be displayed." ); getContentPane().add( text1, BorderLayout.SOUTH ); this.recStart = new JLabel(); getContentPane().add( this.recStart, BorderLayout.WEST ); this.recStop = new JLabel(); getContentPane().add( this.recStop, BorderLayout.EAST ); this.cords = new JLabel(); getContentPane().add( this.cords, BorderLayout.NORTH ); addMouseListener( this ); // listens for own mouse and addMouseMotionListener( this ); // mouse-motion events setSize( 800, 600 ); setVisible( true ); } // MouseListener event handlers // handle event when mouse released immediately after press public void mouseClicked( final MouseEvent event ) { this.mousePosition.setText( "Clicked at [" + event.getX() + ", " + event.getY() + "]" ); repaint(); } // handle event when mouse pressed public void mousePressed( final MouseEvent event ) { this.mousePosition.setText( "Pressed at [" + ( this.x1 = event.getX() ) + ", " + ( this.y1 = event.getY() ) + "]" ); this.recStart.setText( "Start: [" + this.x1 + ", " + this.y1 + "]" ); this.isNewRect = true; repaint(); } // handle event when mouse released after dragging public void mouseReleased( final MouseEvent event ) { this.mousePosition.setText( "Released at [" + ( this.x2 = event.getX() ) + ", " + ( this.y2 = event.getY() ) + "]" ); this.recStop.setText( "End: [" + this.x2 + ", " + this.y2 + "]" ); repaint(); } // handle event when mouse enters area public void mouseEntered( final MouseEvent event ) { this.mousePosition.setText( "Mouse entered at [" + event.getX() + ", " + event.getY() + "]" ); repaint(); } // handle event when mouse exits area public void mouseExited( final MouseEvent event ) { this.mousePosition.setText( "Mouse outside window" ); repaint(); } // MouseMotionListener event handlers // handle event when user drags mouse with button pressed public void mouseDragged( final MouseEvent event ) { this.mousePosition.setText( "Dragged at [" + ( this.x2 = event.getX() ) + ", " + ( this.y2 = event.getY() ) + "]" ); // call repaint which calls paint repaint(); this.isNewRect = false; repaint(); } // handle event when user moves mouse public void mouseMoved( final MouseEvent event ) { this.mousePosition.setText( "Moved at [" + event.getX() + ", " + event.getY() + "]" ); repaint(); } @Override public void paint( final Graphics g ) { super.paint( g ); // clear the frame surface g.drawString( "Start Rec Here", this.x1, this.y1 ); g.drawString( "End Rec Here", this.x2, this.y2 ); int width = this.x1 - this.x2; int height = this.y1 - this.y2; this.w = Math.abs( width ); this.h = Math.abs( height ); this.x = width < 0 ? this.x1 : this.x2; this.y = height < 0 ? this.y1 : this.y2; if ( !this.isNewRect ) { g.drawRect( this.x, this.y, this.w, this.h ); } this.cords.setText( "w = " + this.w + ", h = " + this.h ); } public static void main( final String args[] ) { MouseTracker4July application = new MouseTracker4July(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } } // end class MouseTracker 

您需要将绘制的项目存储在某些数据结构中,并确保在重新绘制时将结构中的每个项目绘制到canvas上。

此外,您需要为每个鼠标事件添加重绘。

像这样:(这假设你想要保留所有矩形) – 你可以通过消除arraylist并用一个rect实例替换单个rect。

 import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingConstants; public class MouseTracker4July extends JFrame implements MouseListener, MouseMotionListener { private static final long serialVersionUID = 1L; private final JLabel mousePosition; int x1, x2, y1, y2; int w, h; private final JLabel recStart; private final JLabel recStop; private final JLabel cords; // set up GUI and register mouse event handlers private final ArrayList< Rectangle > rectangles = new ArrayList< Rectangle >(); private boolean isNewRect = true; public MouseTracker4July() { super( "Rectangle Drawer" ); this.mousePosition = new JLabel(); this.mousePosition.setHorizontalAlignment( SwingConstants.CENTER ); getContentPane().add( this.mousePosition, BorderLayout.CENTER ); JLabel text1 = new JLabel(); text1.setText( "At the center the mouse pointer's coordinates will be displayed." ); getContentPane().add( text1, BorderLayout.SOUTH ); this.recStart = new JLabel(); getContentPane().add( this.recStart, BorderLayout.WEST ); this.recStop = new JLabel(); getContentPane().add( this.recStop, BorderLayout.EAST ); this.cords = new JLabel(); getContentPane().add( this.cords, BorderLayout.NORTH ); addMouseListener( this ); // listens for own mouse and addMouseMotionListener( this ); // mouse-motion events setSize( 800, 600 ); setVisible( true ); } // MouseListener event handlers // handle event when mouse released immediately after press public void mouseClicked( final MouseEvent event ) { this.mousePosition.setText( "Clicked at [" + event.getX() + ", " + event.getY() + "]" ); repaint(); } // handle event when mouse pressed public void mousePressed( final MouseEvent event ) { this.mousePosition.setText( "Pressed at [" + ( this.x1 = event.getX() ) + ", " + ( this.y1 = event.getY() ) + "]" ); this.recStart.setText( "Start: [" + this.x1 + ", " + this.y1 + "]" ); repaint(); } // handle event when mouse released after dragging public void mouseReleased( final MouseEvent event ) { this.mousePosition.setText( "Released at [" + ( this.x2 = event.getX() ) + ", " + ( this.y2 = event.getY() ) + "]" ); this.recStop.setText( "End: [" + this.x2 + ", " + this.y2 + "]" ); Rectangle rectangle = getRectangleFromPoints(); this.rectangles.add( rectangle ); this.w = this.h = this.x1 = this.y1 = this.x2 = this.y2 = 0; this.isNewRect = true; repaint(); } private Rectangle getRectangleFromPoints() { int width = this.x1 - this.x2; int height = this.y1 - this.y2; Rectangle rectangle = new Rectangle( width < 0 ? this.x1 : this.x2, height < 0 ? this.y1 : this.y2, Math.abs( width ), Math.abs( height ) ); return rectangle; } // handle event when mouse enters area public void mouseEntered( final MouseEvent event ) { this.mousePosition.setText( "Mouse entered at [" + event.getX() + ", " + event.getY() + "]" ); repaint(); } // handle event when mouse exits area public void mouseExited( final MouseEvent event ) { this.mousePosition.setText( "Mouse outside window" ); repaint(); } // MouseMotionListener event handlers // handle event when user drags mouse with button pressed public void mouseDragged( final MouseEvent event ) { this.mousePosition.setText( "Dragged at [" + ( this.x2 = event.getX() ) + ", " + ( this.y2 = event.getY() ) + "]" ); // call repaint which calls paint repaint(); this.isNewRect = false; repaint(); } // handle event when user moves mouse public void mouseMoved( final MouseEvent event ) { this.mousePosition.setText( "Moved at [" + event.getX() + ", " + event.getY() + "]" ); repaint(); } @Override public void paint( final Graphics g ) { super.paint( g ); // clear the frame surface g.drawString( "Start Rec Here", this.x1, this.y1 ); g.drawString( "End Rec Here", this.x2, this.y2 ); Rectangle newRectangle = getRectangleFromPoints(); if ( !this.isNewRect ) { g.drawRect( newRectangle.x, newRectangle.y, newRectangle.width, newRectangle.height ); } for( Rectangle rectangle : this.rectangles ) { g.drawRect( rectangle.x, rectangle.y, rectangle.width, rectangle.height ); } this.cords.setText( "w = " + this.w + ", h = " + this.h ); } public static void main( final String args[] ) { MouseTracker4July application = new MouseTracker4July(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } } // end class MouseTracker 

阅读这两种自定义绘画方法 。 上面描述了一种方法,第二种方法显示了如何使用BufferedImage。 两种方法使用的示例允许您向框架添加多个矩形。

如果您不关心某些显示信息,只需删除鼠标侦听器中的每个“mousePosition.setText(…)”,就会导致不必要的repaint()调用。

然后,添加两个字段:“int rx,ry;”,添加/修改以下几种方法:

  public void mouseDragged(MouseEvent event) { // mousePosition.setText("Dragged at [" + (x = event.getX()) + ", " // + (y = event.getY()) + "]"); // call repaint which calls paint x = event.getX(); y = event.getY(); compRectPos(); repaint(); } private void compRectPos() { rx = x1; ry = y1; w = x - x1; h = y - y1; if ( w < 0) rx += w; if (h < 0) ry += h; w = Math.abs(w); h = Math.abs(h); } public void paint(Graphics g) { super.paint(g); // clear the frame surface g.drawString("Start Rec Here", x1, y1); g.drawString("End Rec Here", x, y); g.drawRect(rx, ry, w, h); cords.setText("w = " + w + ", h = " + h); } 

我发现的唯一问题是,首次绘制时矩形不会出现。