我怎么知道,如果一个项目自动完成饰的JComboBox是鼠标单击? [英] How do I know if an item of an auto-complete decorated JComboBox is mouse clicked?

查看:312
本文介绍了我怎么知道,如果一个项目自动完成饰的JComboBox是鼠标单击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 SwingX AutoCompleteDecorator 的JComboBox 。自动完成功能精美的作品...

但我有麻烦找出的最后用户选择的瞬间;要坚持很少我的数据。

让我试着解释:该组合框触发一个comboBoxChanged - 的ActionEvent 为每一位选择。我有当用户键入的字符忽略这些事件和组合框是自动匹配和选择项目。如果用户点击回车键的comboBoxEdited - 的ActionEvent 产生,我可以保存选择的值。伟大; - )

如果鼠标用来打开的JComboBox -PopUp并选择一个项目,唯一的射击事件是一个comboBoxChanged - 的ActionEvent (比如当自动匹配,或选择具有光标键的项目)。在鼠标点击的事件是某种消费!?这就是为什么我无法识别的最后的鼠标选项。

我怎么能算出这个?我失败的尝试侦听的mouseClicked-事件在这个SSCCE都记录:

 进口java.awt.Component中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口java.awt.event.MouseEvent中;
进口java.awt.event.MouseListener;
进口javax.swing.JComboBox中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.JTextField中;
进口javax.swing.SwingUtilities中;
进口javax.swing.UIManager中;
进口org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
公共类SearchForThePopUpMouseClick继承JPanel
{
  私人的JComboBox<串GT;组合框;  公共SearchForThePopUpMouseClick()
  {
    组合框=新的JComboBox<串GT(新的String [] {安娜,马克,玛丽亚,貂,彼得});
    增加(组合框);
    添加(新的JTextField(文本框点击));    AutoCompleteDecorator.decorate(组合框);
    comboBox.addActionListener(新的ActionListener()
    {
      @覆盖
      公共无效的actionPerformed(ActionEvent的五)
      {
        的System.out.println(操作事件与'+ e.getActionCommand()++ e.getID()+');
      };
    });
    ((成分)comboBox.getUI()。getAccessibleChild(组合框,0))。addMouseListener将(新的MouseListener()
    {
      @覆盖
      公共无效的mouseReleased(的MouseEvent E)
      {
        的System.out.println(E);
      }
      @覆盖
      公共无效鼠标pressed(的MouseEvent E)
      {
        的System.out.println(E);
      }
      @覆盖
      公共无效的mouseExited(的MouseEvent E)
      {
        的System.out.println(E);
      }
      @覆盖
      公共无效的mouseEntered(的MouseEvent E)
      {
        的System.out.println(E);
      }
      @覆盖
      公共无效的mouseClicked(的MouseEvent E)
      {
        的System.out.println(E);
      }
    });
  }
  公共静态无效的主要(字串[] args)抛出异常
  {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    SwingUtilities.invokeLater(Runnable的新()
    {
      @覆盖
      公共无效的run()
      {
        SearchForThePopUpMouseClick autoCompletePanel =新SearchForThePopUpMouseClick();
        JFrame的帧=新的JFrame(SwingX自动完成实例);
        frame.add(autoCompletePanel);
        frame.pack();
        frame.setLocationRelativeTo(NULL);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(真);
      }
    });
  }}


解决方案

组合框没有的最后的选择的概念:所有的选择都有平等的语义权重依赖于它们的触发(鼠标,键盘导航,编程,选择在核心的第一个字母),并触发一个ActionEvent。同样的行为平原和装饰的组合框。

这正是需要在大多数情况下是什么:反应选择总是好像是的最后的(不管这可能意味着)

如果你的情况,你的真的希望把通过的MouseEvent为比由别的什么触发了最终引发了选择(再次:这是典型的不可以建议换一个良好的用户体验,所以是非常,在你的评价非常小心),你可以检查由ActionEvent的返回的修饰符:

  IF((e.getModifiers()及!InputEvent.BUTTON1_MASK)= 0){
    //鼠标触发
}

修改

看到用例(感谢他们提供!)中的意见,意识到我谨防在错误的树部分咆哮:-)

在这种情况下,鼠标器与键盘手势具有确实不同的语义


  • 键盘:输入在编辑器中,以及在弹出的浏览表示工艺打造的最终选择,有一个特殊的键(Enter)表示提交

  • 鼠标:单击,在弹出的既是选择和提交

JComboBox的不支持该用例最佳地,击发太多。这就是问题甚至摆在内部,f.i.使用组合框为CellEditor的时候。这部分是由一个神奇clientProperty固定的:

 公共DefaultCellEditor(JComboBox的最终组合框){
    editorComponent =组合框;
    comboBox.putClientProperty(JComboBox.isTableCellEditor,Boolean.TRUE);

检测该财产的BasicComboBoxUI(实际上是BasicComboPopup)导航按键只在弹出的列表中选择,defering的listSelection的同步到comboSelection,直到通过输入承诺。它是局部因为先行。(又名:打字和选择由第一个字母)仍然在组合选择(和从而承诺)立即

简短摘要:已经有一个摆动内部使用情况,从而导致已经可用的swingx内部的自动完成编辑表中的解决方案 - 一个名为ComboBoxCellEditor类。可单机使用也:

  AutoCompleteDecorator.decorate(withEditor);
ComboBoxCellEditor编辑器=新ComboBoxCellEditor(withEditor);
CellEditorListener组成监听器=新CellEditorListener组成(){    @覆盖
    公共无效editingStopped(的ChangeEvent发送){
        //做承诺的东西
    }    @覆盖
    公共无效editingCanceled(的ChangeEvent发送){
    }
};
editor.addCellEditorListener(监听);
contentPane.add(withEditor,BorderLayout.SOUTH);

I'm using the SwingX AutoCompleteDecorator for a JComboBox. The autocomplete feature works beautifully...

But I have trouble to identify the moment of the final user selection; to persist my data seldom.

Let me try to explain: The combobox fires an "comboBoxChanged"-ActionEvent for every selection. I have to ignore these events while the user is typing characters and the combobox is auto-matching and selecting items. If the user hits the return-key an "comboBoxEdited"-ActionEvent is generated and I can save the selected value. Great ;-)

If the mouse is used to open the JComboBox-PopUp and to select an item, the only fired event is a "comboBoxChanged"-ActionEvent (like when auto-matching or selecting an item with the cursor-keys). The mouse-clicked-Event is consumed somehow!? That's why I can't identify the final mouse selection.

How can I figure this out? My failed attempts to listen for the mouseClicked-Event are documented in this SSCCE:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;


public class SearchForThePopUpMouseClick extends JPanel
{
  private JComboBox<String> comboBox;

  public SearchForThePopUpMouseClick()
  {
    comboBox = new JComboBox<String>(new String[] { "Anna", "Marc", "Maria", "Marten", "Peter" });
    add(comboBox);
    add(new JTextField("textfield to click"));

    AutoCompleteDecorator.decorate(comboBox);


    comboBox.addActionListener(new ActionListener()
    {
      @Override
      public void actionPerformed(ActionEvent e)
      {
        System.out.println("Action Event with '" + e.getActionCommand() + " " + e.getID() + "'");
      };
    });


    ((Component) comboBox.getUI().getAccessibleChild(comboBox, 0)).addMouseListener(new MouseListener()
    {
      @Override
      public void mouseReleased(MouseEvent e)
      {
        System.out.println(e);
      }
      @Override
      public void mousePressed(MouseEvent e)
      {
        System.out.println(e);
      } 
      @Override
      public void mouseExited(MouseEvent e)
      {
        System.out.println(e);
      }
      @Override
      public void mouseEntered(MouseEvent e)
      {
        System.out.println(e);
      }
      @Override
      public void mouseClicked(MouseEvent e)
      {
        System.out.println(e);
      }
    });
  }


  public static void main(String[] args) throws Exception
  {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    SwingUtilities.invokeLater(new Runnable()
    {
      @Override
      public void run()
      {
        SearchForThePopUpMouseClick autoCompletePanel = new SearchForThePopUpMouseClick();
        JFrame frame = new JFrame("SwingX Autocomplete Example");
        frame.add(autoCompletePanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }

}

解决方案

A comboBox has no notion of final selection: all selections have equal semantic weight independent on their trigger (mouse, keyboard navigation, programmatically, selection by first letter in core) and fire an actionEvent. Same behaviour for plain and decorated comboBox.

That's exactly what you need in most contexts: react to a selection always as if it were final (whatever that might mean)

If in your case you really want to regard a selection triggered by a mouseEvent as more final than those triggered by anything else (again: that's typically not recommended for a good user experience, so be very, very careful in your evaluation) you can check the modifiers returned by the actionEvent:

if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
    // triggered by mouse
}

Edit

Seeing the use cases (thanks for providing them!) in the comments, realized that my beware partly barked at the wrong tree :-)

In this context, the mouse- vs. keyboard gesture have indeed different semantics

  • keyboard: typing in the editor as well as navigating in the popup denote the process to build the final selection, with a special key (enter) denoting a commit
  • mouse: clicking in the popup is both selecting and commit

JComboBox doesn't support that use-case optimally, firing too much. That's problem even swing-internally, f.i. when using a comboBox as CellEditor. That's partly fixed by a magic clientProperty:

public DefaultCellEditor(final JComboBox comboBox) {
    editorComponent = comboBox;
    comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);

Detecting that property, the BasicComboBoxUI (actually the BasicComboPopup) keyStrokes navigation selects in the list of the popup only, defering the synch of the listSelection to the comboSelection until committed via enter. It's partial because the look-ahead (aka: typing and selecting by first letter) still selects (and thereby committing) immediately in the combo.

Short summary: there already is a swing-internal use-case, which leads to an already available swingx-internal solution for autoComplete editing in tables - a class named ComboBoxCellEditor. Can be used stand-alone also:

AutoCompleteDecorator.decorate( withEditor );
ComboBoxCellEditor editor = new ComboBoxCellEditor(withEditor);
CellEditorListener listener = new CellEditorListener() {

    @Override
    public void editingStopped(ChangeEvent e) {
        // do commit stuff
    }

    @Override
    public void editingCanceled(ChangeEvent e) {
    }
};
editor.addCellEditorListener(listener);
contentPane.add(withEditor, BorderLayout.SOUTH);

这篇关于我怎么知道,如果一个项目自动完成饰的JComboBox是鼠标单击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆