在此帖子的底部显示了基于接受的答案的已编辑的正确代码。

我找到了一种方法(written by Andremoniy),可以捕获双击和三次单击而无需触发单击和双击。对于我的目的,它工作得很好。

我对其进行了修改,以便可以通过实现调整点击间隔。那也很好。

我的修改包括将其设置为abstract class,定义了实现必须定义的5个abstract方法(单次,两次,三次和“多次”点击以及点击间隔调整的方法)。

这是修改后的版本(println语句具有指导意义):

public abstract class Click123 extends JPanel
{
  public abstract void singleClick();
  public abstract void doubleClick();
  public abstract void tripleClick();
  public abstract void manyClick();
  public abstract int  getFreq();

  public Click123()
  {
    addMouseListener
    (
      new MouseAdapter()
      {
        Thread cp = null;

        public void mouseClicked(MouseEvent e)
        {
          if (cp != null && cp.isAlive())
            cp.interrupt();

          if (e.getClickCount() == 1)
          {
            cp =  new Thread(new ClickProcessor(new Callable<Void>() {
              @Override public Void call() throws Exception {
                singleClick();
                return null;
              }
            }));
            cp.start();
          }
          else if (e.getClickCount() == 2)
          {
            cp = new Thread(new ClickProcessor(new Callable<Void>() {
              @Override public Void call() throws Exception {
                doubleClick();
                return null;
              }
            }));
            cp.start();
          }
          else if (e.getClickCount() == 3)
          {
            cp =  new Thread(new ClickProcessor(new Callable<Void>()
            {
              @Override public Void call() throws Exception {
                tripleClick();
                return null;
              }
              })
            );
            cp.start();
          }
          else manyClick();
        } // mouseClicked
      }  // new MouseAdapter
    ); // add mouseListener
  } // Click123

  class ClickProcessor implements Runnable
  {
    Callable<Void> eventProcessor;

    ClickProcessor(Callable<Void> eventProcessor)
    {
        this.eventProcessor = eventProcessor;
    }

    @Override public void run()
    {
      try
      {
          Thread.sleep(getFreq());
          eventProcessor.call();
      } catch (InterruptedException e) { System.out.println(e);}
        catch (Exception e)            { System.out.println(e);}
    }  // run
  }  // class ClickProcessor
} // class Click123


这是实施程序:

public class NewMain1 {
  static int INITIAL_CLICK_FREQUENCY = ((Integer)Toolkit.getDefaultToolkit()
      .getDesktopProperty("awt.multiClickInterval"));

  public static int CLICK_FREQUENCY;

  static       JSpinner spinner   = new JSpinner();
  static final JLabel   ch        = new JLabel("Click here to test");

  public static void main(String[] args) {

    CLICK_FREQUENCY = INITIAL_CLICK_FREQUENCY;
    spinner = new JSpinner();
    spinner.setModel(new SpinnerNumberModel(CLICK_FREQUENCY, 200, 900, 50));
    spinner.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent e) {
        CLICK_FREQUENCY = (int) spinner.getValue();
      }
    });

    Click123 frame = new Click123(){
      public void singleClick(){
        JOptionPane.showMessageDialog(null,"Single click at " + CLICK_FREQUENCY);
      }
      public void doubleClick(){
        JOptionPane.showMessageDialog(null,"Double click at " + CLICK_FREQUENCY);
      }
      public void tripleClick(){
        JOptionPane.showMessageDialog(null,"Triple click at " + CLICK_FREQUENCY);
      }
      public void manyClick(){
        JOptionPane.showMessageDialog(null,"Many clicks at " + CLICK_FREQUENCY);
      }
      public int getFreq(){
        return CLICK_FREQUENCY;
      }
    };
    frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    frame.setLayout(new FlowLayout());
    frame.setSize(500, 300);
              ch.setBorder(new EtchedBorder());
    frame.add(ch);
    frame.add(spinner);
    frame.setVisible(true);
  } // main
}


如最初所写,Click123 extends JFrame。我对其进行了修改(通过将顶行更改为extends JTextField)以处理类型为JTextField的网格。然后,我添加了一个按钮来动态更改点击间隔。所以现在我有了三个相同的代码(扩展类型除外)。

我的问题是:如何修改Click123,以便可以不进行更改地使任何组件都知道单击,双击和三次单击?

编辑-必要更改的摘要(对于我自己的应用程序,abstract方法需要传递MouseEvent才能确定触发点击的组件):

类定义:

 public abstract class Click123<T extends Component>
 {
   public abstract void singleClick(MouseEvent e); // same for 3 others
    ...

    public Click123(T target)
    {
      target.addMouseListener
      (
        new MouseAdapter() ...
     } ...
  }


添加final作为修饰符以便通过MouseEvent

    public void mouseClicked(final MouseEvent e)


通过MouseEvent

    singleClick(e); // same for doubleClick and tripleClick and manyClick


接收MouseEvent以确定哪个组件触发了点击:

  public void doubleClick(MouseEvent e)


实现方式:

frame = new JPanel();
new Click123(frame) {

最佳答案

泛型是解决方案的一部分。只需执行以下操作:


使您的班级Click123<T extends Component>
使您的构造函数public Click123(T targetedComponent) {
呼叫targetedComponent.addMouseListener而不是addMouseListener
创建一个JFrameJPanel或其他任何东西,然后将其作为构造函数参数传递给您的new Click123。然后在使用JFrame的地方使用Click123

07-26 05:17