首先,我作为网站程序员来到Java。在JavaScript中,您只需调用addEventListener函数即可添加mousemove,mouseover或click事件。根据我对Java的有限经验,您不能只从任何对象实现MouseListener接口。
基本上,到目前为止我所拥有的是一个JPanel,它绘制了一些具有x / y / width / height值的形状(带有绘制方法的CustomShape对象)。我想在形状对象中添加一些类型的鼠标监听器,这样我就可以触发形状的移动/滚动/点击事件。只是将CustomLhaner接口实现到CustomShape对象不起作用(我认为这是显而易见的原因)。我已经了解了如何设计自定义事件监听器,但似乎不可能制作自定义鼠标监听器。
我最终使用鼠标监听器添加到JPanel,然后循环遍历所有形状对象。如果形状对象附加了“侦听器”,并且鼠标坐标已验证鼠标事件已发生,则会触发该方法。最初,它很好,但随着应用程序越来越发达,它开始变得非常混乱。另外,在没有复制大量代码的情况下,我永远无法将形状对象/接口复制到另一个应用程序。
简单说明:(实际代码非常大)
Interface CustomShape{
int width, height, x, y;
void paint(Graphics g);
}
public class StarShape implements CustomShape{
int width, height, x, y;
public StarShape(){
width = 100;
height = 100;
x = 50;
y = 50;
}
void paint(Graphics g){
g.setColor(Color.black);
g.draw(new Rectangle(x,y,width,height));
}
}
public class Main extends JPanel{
StarShape check = new StarShape();
public Main(){ }
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
check.paint(g);
}
}
所以,我想知道是否有一种干净的方式为'手绘'形状实现某种类型的鼠标监听器。
答案 0 :(得分:5)
为了能够接收事件,您的“Shape”对象应该扩展java.awt.Component(或javax.swing.JComponent)。然后你可以将它们作为一个孩子添加到JPanel,它们将接收事件,你可以直接向它们添加监听器。
您的工作方式是,您必须在JPanel中手动跟踪形状的位置。您将鼠标侦听器添加到面板本身,并根据您获得的事件的x / y坐标,在形状上调用一些方法来处理事件。这几乎是重新实现基础AWT / Swing类将为您做的事情。
答案 1 :(得分:2)
我做你想做的事情的方法。编译,运行,阅读: - )
(注意:您可以将下面的每一行代码复制到一个文件Example01.java
中。编译并运行它。)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example01 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame jf = new JFrame();
MainPanel mainPanel = new MainPanel();
jf.add(mainPanel);
jf.setSize(640, 480);
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
});
}
}
class MainPanel extends JPanel {
StarShape check1 = new StarShape();
StarShape check2 = new StarShape();
public MainPanel() {
check1.setName("check1");
check2.setName("check2");
check1.addMouseListener(new MyMouseListener(check1));
check2.addMouseListener(new MyMouseListener(check2));
this.add(check1);
this.add(check2);
}
}
class StarShape extends JComponent {
public StarShape() {
this.setPreferredSize(new Dimension(100, 100));
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(Color.black);
Graphics2D g2d = (Graphics2D) g;
int x = 0;
int y = 0;
int width = this.getWidth() - 1;
int height = this.getHeight() - 1;
g2d.draw(new Rectangle(x, y, width, height));
}
}
class MyMouseListener implements MouseListener {
private final JComponent component;
public MyMouseListener(JComponent component) {
this.component = component;
}
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked: " + component.getName());
}
public void mouseEntered(MouseEvent e) {
System.out.println("mouseEntered: " + component.getName());
Dimension preferredSize = component.getPreferredSize();
preferredSize.height += 20;
preferredSize.width += 20;
component.setPreferredSize(preferredSize);
component.invalidate();
SwingUtilities.getWindowAncestor(component).validate();
}
public void mouseExited(MouseEvent e) {
System.out.println("mouseExited: " + component.getName());
Dimension preferredSize = component.getPreferredSize();
preferredSize.height -= 20;
preferredSize.width -= 20;
component.setPreferredSize(preferredSize);
component.invalidate();
SwingUtilities.getWindowAncestor(component).validate();
}
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed: " + component.getName());
}
public void mouseReleased(MouseEvent e) {
System.out.println("mouseReleased: " + component.getName());
}
}
答案 2 :(得分:1)
你可以做的是形状扩展JPanel
。
public abstract class CustomShape extends JPanel {
public CustomShape(){
setOpaque(false);
}
public abstract void paintShape(Graphics g);
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintShape(g);
}
}
然后,您可以直接在形状上添加侦听器。
然后,您需要创建父JPanel
,并将其LayoutManager
设置为null
。然后,您需要在父级上手动设置Shape的位置。
阅读有关手动布置组件here的更多信息。而且,如果您不喜欢这种方法,请查看我对this问题的回答。它谈到用鼠标在屏幕周围移动彩色矩形。