当前位置: 首页 > 知识库问答 >
问题:

如果MouseListener事件方法已经在运行,如何激发它

高嘉熙
2023-03-14

在我的代码中,我有:

带有普通JPanel的JFrame,其中包含一些JComponent对象。这些JComponents有:-一个JTextFields列表。-一个侦听器,当鼠标插入时高亮显示边框,当鼠标退出时隐藏边框。如果鼠标在jceeExit方法的边框上嵌套,那么当鼠标在jceeExit方法的边框上嵌套时,也会触发jceeExit:

问题是:

代码:

代码是为了解决上述问题而编写的。以下是Jcomponent类(MyContainer)和包含Main的类(MyClass):

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class MyClass {

    public static void main(String[] args)  {       
        SwingUtilities.invokeLater(new Runnable() {
            public void run(){   
                int i=0;
                //mainWindow
                    JFrame mainWindow = new JFrame("MyFrame");
                    mainWindow.setLayout(new BorderLayout());
                    mainWindow.setMinimumSize(new Dimension(300,300));

                    JPanel viewPort = new JPanel();
                    viewPort.setLayout(new FlowLayout(FlowLayout.LEFT));

                    MyContainer one = new MyContainer();
                    MyContainer two = new MyContainer();
                    MyContainer three = new MyContainer();

                    viewPort.add(one);
                    viewPort.add(two);
                    viewPort.add(three);
                    mainWindow.add(viewPort,BorderLayout.CENTER);
                    mainWindow.setVisible(true);
            }
        });
    }

}





import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JTextField;

    @SuppressWarnings("serial")
    public  class MyContainer extends JComponent {
            JTextField text1 ;
            JTextField text2 ;
            JTextField text3 ;

            public MyContainer(){
                super.setLayout(new FlowLayout(FlowLayout.LEFT));
                super.setPreferredSize(new Dimension(200,50));
                super.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
                super.setBackground(Color.green);

                text1 = new JTextField("LABEL_1");
                text1.setPreferredSize(new Dimension(60,30));
                text1.setEditable(false);
                this.add(text1);

                text2 = new JTextField("LABEL_2");
                text2.setPreferredSize(new Dimension(60,30));
                text2.setEditable(false);
                this.add(text2);

                text3 = new JTextField("LABEL_3");
                text3.setPreferredSize(new Dimension(60,30));
                text3.setEditable(false);
                this.add(text3);

                addListener();
            }

            private void addListener() {
                this.addMouseListener(new MouseListener() {
                    @Override
                    public void mouseEntered(MouseEvent e) {
                        MyContainer.this.setBorder(BorderFactory.createLineBorder(Color.BLUE));
                    }

                    @Override
                    public void mouseExited(MouseEvent e) {
                        Rectangle r = e.getComponent().getBounds();
                        Point p = e.getPoint();
                        if( p.x < 0 || p.y < 0 || p.x >= r.width || p.y >= r.height)
                            MyContainer.this.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
                    }

                    @Override public void mouseClicked(MouseEvent e) { /*NOTHING*/ }
                    @Override public void mouseReleased(MouseEvent e) { /*NOTHING*/ }
                    @Override public void mousePressed(MouseEvent e) { /*NOTHING*/ }
                });         
            }
        }

共有2个答案

吴嘉禧
2023-03-14

我建议不要使用静态方法,尽管我不确定按照你的方式做会有什么实际影响。我建议

public void mouseEntered(MouseEvent e) {
    ((MyContainer) e.getSource()).setBorder(...)
}

// and so forth

此外,问题可能与您的mouseExited方法有关。而不是使用。getBounds()我建议使用instanceof

if(e.getSource() instanceof MyContainer) {
    // do the stuff
} else {
    // do nothing
}

或者:

if(!(e.getSource() instanceof JTextField)) {
    // do the stuff
} else {
    // do nothing
}

其他语句甚至是不必要的;我只是为了完整性而包含它。

鲜于阳
2023-03-14

这里是一个可能的实现使用MyContainer.this.dispatch事件(SwingUtilities.convert鼠标事件(JTextField, e, MyContainer.this));

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class MyClass2 {
  public static void main(String[] args)  {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        int i = 0;
        //mainWindow
        JFrame mainWindow = new JFrame("MyFrame");
        mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        mainWindow.setMinimumSize(new Dimension(300, 300));

        JPanel viewPort = new JPanel();
        viewPort.setLayout(new FlowLayout(FlowLayout.LEFT));

        MyContainer one = new MyContainer();
        MyContainer two = new MyContainer(true);
        viewPort.add(makeTitledPanel(one, "move it fast: NG?"));
        viewPort.add(makeTitledPanel(two, "move it fast: OK?"));
        mainWindow.add(viewPort, BorderLayout.CENTER);
        mainWindow.setVisible(true);
      }
    });
  }
  private static JComponent makeTitledPanel(JComponent c, String title) {
    JPanel p = new JPanel(new BorderLayout());
    p.setBorder(BorderFactory.createTitledBorder(title));
    p.add(c);
    return p;
  }
}

class MyContainer extends JComponent {
  JTextField text1 ;
  JTextField text2 ;
  JTextField text3 ;
  private final boolean flag;
  public MyContainer() {
    this(false);
  }
  public MyContainer(boolean flag) {
    super();
    this.flag = flag;

    super.setLayout(new FlowLayout(FlowLayout.LEFT));
    super.setPreferredSize(new Dimension(200, 50));
    super.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    super.setBackground(Color.green);

    text1 = new JTextField("LABEL_1");
    text2 = new JTextField("LABEL_2");
    text3 = new JTextField("LABEL_3");

    MouseListener l = new MouseEventConverter();
    for (JTextField f : Arrays.asList(text1, text2, text3)) {
      f.setPreferredSize(new Dimension(60, 30));
      f.setEditable(false);
      if (flag) {
        f.addMouseListener(l);
      }
      this.add(f);
    }
    this.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent e) {
        MyContainer.this.setBorder(BorderFactory.createLineBorder(Color.BLUE));
      }
      @Override
      public void mouseExited(MouseEvent e) {
        Rectangle r = e.getComponent().getBounds();
        Point p = e.getPoint();
        if (p.x < 0 || p.y < 0 || p.x >= r.width || p.y >= r.height) {
          MyContainer.this.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
        }
      }
    });
  }
}

class MouseEventConverter extends MouseAdapter {
  @Override public void mouseEntered(MouseEvent e) {
    dispatchMouseEvent(e);
  }
  @Override public void mouseExited(MouseEvent e) {
    dispatchMouseEvent(e);
  }
  private void dispatchMouseEvent(MouseEvent e) {
    Component c = e.getComponent();
    Component p = SwingUtilities.getUnwrappedParent(c);
    p.dispatchEvent(SwingUtilities.convertMouseEvent(c, e, p));
  }
}
 类似资料:
  • 我在一个KeyListener中为一个非常简单的游戏编程控件。伊芙得到了下面的问题。 我做了类似的事情(只是一个简单的示例,而不是我实现的代码): 如果我同时按下两个键(左,上),你就可以移动charachter对角线。问题是监听器与最后一个按下的KeyEvent一起工作,所以如果我先按左再向上,但没有释放左再向上,对象就不会移动(仍然按左)。 我怎么处理?是否可以在我的keylistener的k

  • 问题内容: 我有以下5个文件: gui.py functions.py 线程处理程序 variables.py 和start.py 执行start.py之后,我收到消息:“ QCoreApplication:exec:事件循环已在运行 ” 我发现,这与计时器有关 从 start.py 和功能 在 functions.py中 有人可以向我解释问题是什么吗?我不知道代码有什么问题… 问题答案: 我认为

  • 问题内容: 我正在使用Selenium WebDriver语法。我知道,在基于Selenium服务器的语法中,您可以执行以下操作来触发javascript事件: 如何在使用WebDriver(例如FirefoxDriver)创建的应用程序中执行相同操作? 问题答案: 不幸的是,Selenium WebDriver设计人员明确决定不在 Selenium 2中包含此功能。 明智的决定是不将此功能包含在

  • 问题内容: 我正在使用Selenium WebDriver语法。我知道,在基于Selenium服务器的语法中,您可以执行以下操作来触发javascript事件: 如何在使用WebDriver(例如FirefoxDriver)创建的应用程序中执行相同操作? 问题答案: 不幸的是,Selenium WebDriver设计人员明确决定不在 Selenium 2中包含此功能。 明智的决定是不将此功能包含在

  • 在用java编写Minecraft插件时,您可以创建一个事件监听器方法,并将其命名为任意名称,但您必须传入事件监听者的类,例如: 我只是想知道,如果Bukkit API中的任何类都不知道该方法的名称,那么该方法是如何在“幕后”执行的?我希望我能很好地解释自己。谢谢

  • 我在库中的页面上有一个可自定义的表单元素。我希望看到在与javascript交互时触发了哪些javascript事件,因为我试图找出要使用的事件处理程序。 我如何使用ChromeWebDeveloper做到这一点?