[英]How do I properly implement a mouselistener to my Jcomponent?
I have a project where I need to create a GUI in Java that creates a circle on mouse-click and and continues to make trailing circles as the mouse is dragged through the frame.我有一个项目,我需要在 Java 中创建一个 GUI,在鼠标单击时创建一个圆圈,并在鼠标拖过框架时继续制作尾随圆圈。 I've been given reference to multiple threads on here but none have seemed to help me do what I need to do.我在这里得到了多个线程的参考,但似乎没有一个可以帮助我做我需要做的事情。 So far I've got a static circle added to my JFrame, but I want to make the multiple circles show on a JPanel in that frame.到目前为止,我已经在 JFrame 中添加了一个 static 圆圈,但我想让多个圆圈显示在该框架中的 JPanel 上。 I'm stuck after trying many different angles.在尝试了许多不同的角度后,我被卡住了。 As of now I just need to be able to click once and create a circle.到目前为止,我只需要能够单击一次并创建一个圆圈。
public class Theremin extends JFrame implements ActionListener, MouseListener{
private JPanel windowArea;
private int x, y;
private static final long serialVersionUID = 1L;
public Theremin() {
}
public static void main(String[] args) {
Theremin Frame = new Theremin();
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
panel.setLayout(null);
Frame.add(panel);
Frame.pack();
Frame.setLocationRelativeTo(null);
Frame.setVisible(true);
}
private static class MyPanel extends JPanel {
public void paint(Graphics g) {
Graphics2D gObj = (Graphics2D)g;
Shape disk = new Ellipse2D.Double(10, 10, 100, 100);
gObj.setColor(new Color(255, 0, 0, 120));
gObj.fill(disk);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(700, 600);
}
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
} }
Here's a GUI that I put together.这是我放在一起的 GUI。
Each mouse click creates a circle.每次鼠标单击都会创建一个圆圈。
When I create a Swing GUI, or any Java application, I use the model / view / controller (MVC) pattern. When I create a Swing GUI, or any Java application, I use the model / view / controller (MVC) pattern. This pattern allows me to separate my concerns and focus on one part of the application at a time.这种模式使我能够分离我的关注点并一次专注于应用程序的一个部分。
For a Swing GUI, the MVC pattern means:对于 Swing GUI,MVC 模式意味着:
The model consists of two classes, Circles
and Circle
. model 包含两个类, Circles
和Circle
。 The Circle
class defines a circle with a Point
center, int
radius, and a Color
color. Circle
class 定义了一个具有Point
中心、 int
半径和Color
颜色的圆。 Because Circle
is a class, I can define as many instances (circles) as I want.因为Circle
是 class,所以我可以定义任意数量的实例(圆)。
The Circles
class holds a List
of Circle
instances. Circles
class 包含一个Circle
实例List
。
The view consists of a JFrame
and a drawing JPanel
.该视图由JFrame
和绘图JPanel
组成。 The paintComponent
method of the drawing JPanel
paints circles.绘图JPanel
的paintComponent
方法绘制圆圈。 Period.时期。 We create the circles in the controller class.我们在 controller class 中创建圆圈。
The controller class CirclesListener
creates the circles and repaints the drawing JPanel
. controller class CirclesListener
创建圆圈并重新绘制绘图JPanel
。 All of the circles are redrawn each and every time the drawing JPanel
is repainted.每次重新绘制绘图JPanel
时,都会重新绘制所有圆圈。
An instance of the JFrame
class and the application model class is passed to the controller CirclesListener
class. An instance of the JFrame
class and the application model class is passed to the controller CirclesListener
class. This allows the class to create a new circle and repaint the drawing JPanel
.这允许 class 创建一个新圆圈并重新绘制绘图JPanel
。
Here's the complete runnable code.这是完整的可运行代码。
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MouseClickCircleGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new MouseClickCircleGUI());
}
private Circles circles;
private DrawingPanel drawingPanel;
public MouseClickCircleGUI() {
this.circles = new Circles();
}
@Override
public void run() {
JFrame frame = new JFrame("Circles");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawingPanel = new DrawingPanel(this, circles);
frame.add(drawingPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public void repaint() {
drawingPanel.repaint();
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private final Circles circles;
public DrawingPanel(MouseClickCircleGUI frame, Circles circles) {
this.circles = circles;
setBackground(Color.WHITE);
setPreferredSize(new Dimension(500, 500));
addMouseListener(new CirclesListener(frame, circles));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(3f));
for (Circle circle : circles.getCircles()) {
Point p = circle.getCenter();
int radius = circle.getRadius();
g2.setColor(circle.getColor());
g2.drawOval(p.x - radius, p.y - radius,
2 * radius, 2 * radius);
}
}
}
public class CirclesListener extends MouseAdapter {
private final Circles circles;
private final MouseClickCircleGUI frame;
public CirclesListener(MouseClickCircleGUI frame, Circles circles) {
this.frame = frame;
this.circles = circles;
}
@Override
public void mouseReleased(MouseEvent event) {
circles.addCircle(new Circle(event.getPoint(), 30, Color.BLACK));
frame.repaint();
}
}
public class Circles {
private final List<Circle> circles;
public Circles() {
this.circles = new ArrayList<>();
}
public void addCircle(Circle circle) {
this.circles.add(circle);
}
public List<Circle> getCircles() {
return circles;
}
}
public class Circle {
private final int radius;
private final Color color;
private final Point center;
public Circle(Point center, int radius, Color color) {
this.center = center;
this.radius = radius;
this.color = color;
}
public int getRadius() {
return radius;
}
public Point getCenter() {
return center;
}
public Color getColor() {
return color;
}
}
}
The idea here is to:这里的想法是:
Here is how I have done it, this is a sample code.这是我的做法,这是一个示例代码。
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Theremin frame = new Theremin();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
panel.initListeners();
panel.setLayout(null);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
panel.releaseListener();
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
}
}
class MyPanel extends JPanel implements MouseListener, MouseMotionListener {
private Graphics graphics;
private List<CircleData> shapeList = new ArrayList<>();
private Graphics2D gObj;
public MyPanel() {
}
@Override
public void paint(Graphics g) {
this.graphics = g;
gObj = (Graphics2D) g;
System.out.println("called paint with times: " + times++);
for (CircleData circleData : shapeList) {
Rectangle rectangle = circleData.rectangle;
Color color = circleData.color;
Shape disk = new Ellipse2D.Double(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
gObj.setColor(color);
gObj.fill(disk);
}
}
Color randomColor() {
int red = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
return new Color(red, green, blue);
}
static int times = 0;
@Override
public Dimension getPreferredSize() {
return new Dimension(700, 600);
}
public void initListeners() {
System.out.println("added default listeners");
addMouseListener(this);
addMouseMotionListener(this);
}
public void releaseListener() {
System.out.println("removed default listeners");
removeMouseListener(this);
removeMouseMotionListener(this);
}
@Override
public void mouseClicked(MouseEvent e) {
float x = e.getX();
float y = e.getY();
String cordinates = String.format("(%f, %f)", x, y);
System.out.println("Mouse Clicked @ " + cordinates);
shapeList.add(new CircleData(new Rectangle((int) x, (int) y, 50, 50), randomColor()));
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
float x = e.getX();
float y = e.getY();
String cordinates = String.format("(%f, %f)", x, y);
System.out.println("Mouse Dragged @ " + cordinates);
System.out.println("Mouse Dragged @ " + shapeList.size());
shapeList.add(new CircleData(new Rectangle((int) x, (int) y, 50, 50), randomColor()));
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
}
}
class CircleData {
Rectangle rectangle;
Color color;
public CircleData(Rectangle rectangle, Color color) {
this.rectangle = rectangle;
this.color = color;
}
}
class Theremin extends JFrame {
private static final long serialVersionUID = 1L;
public Theremin() {
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.