【问题标题】:Prevent FocusEvents when Component is not focused当组件未获得焦点时防止 FocusEvents
【发布时间】:2011-08-29 13:41:44
【问题描述】:

我有以下示例代码:

import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class SampleFocus extends JFrame {

  public SampleFocus(String titel) {
    setTitle(titel);
    JTextField txtField1 = new JTextField("default-click");
    JTextField txtField2 = new JTextField("alternative-Text");
    JTextField txtField3 = new JTextField("own diaolog textfield");

    JTextArea dummyLabel = new JTextArea(10, 20);
    dummyLabel.setText("empty textarea, which is focusable");

    setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
    add(txtField1);
    add(dummyLabel);
    add(txtField2);

    JDialog altDialog = new JDialog(this);
    altDialog.add(txtField3);
    altDialog.setVisible(true);
    altDialog.pack();

    FocusAdapter myFocusListner = new FocusAdapter() {

      @Override
      public void focusGained(FocusEvent e) {
        if (e.getComponent() instanceof JTextField) {
          System.out.println("gained for TextField: "
                             + ((JTextField) e.getComponent()).getText());
        } else {
          System.out.println("gained for component: " + e.getComponent());
        }
      }
    };

    txtField1.addFocusListener(myFocusListner);
    txtField2.addFocusListener(myFocusListner);
    txtField3.addFocusListener(myFocusListner);

    // dummyLabel.addFocusListener(myFocusListner);
  }

  public static void main(String[] args) {
    JFrame frame = new SampleFocus("FocusListener  - sample");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

  }
}

当我从框架切换到对话框时,我得到了正确的事件。当我切换回 Frame 时,我也得到了正确的 FocusEvents。我的问题是,当我切换回来时,我也会获得我不感兴趣的组件的 FocusEvents。

例如

选择'默认点击' ==> 对话框/文本字段 ==> 框架/'空文本区域'

结果:尽管组件没有焦点,但我得到了“默认点击”的 FocusGained-Event。

期望的结果:要么

  • 组件“默认点击”未获得 FocusEvent 或

  • 判断组件是否真的正确接收到事件(例如,我也可以点击它)

我找到的解决方法:

附加到 JTextArea 以及 FocusListener。问题是,这意味着,我需要在我的所有组件上附加一个 Listener。这几乎是不可能的。有什么想法吗?

任何想法如何得到结果?

谢谢LeO

【问题讨论】:

    标签: java swing focus


    【解决方案1】:

    它按预期工作。 您选择“默认单击”。它获得焦点。 您选择对话框。框架和“默认点击”失去焦点。 您选择文本区域。现在,事情变得有趣了。对话框失去焦点。框架获得焦点。 “默认点击”也获得焦点,因为他在 Frame 处于活动状态时拥有它。然后“默认点击”失去焦点,textarea 获得焦点(因为你点击了文本区域)。

    尝试结合 focusGained 和 focusLost 事件。

    或者告诉我更多你想要完成什么,也许我可以提供帮助。

    【讨论】:

    • 失而复得——也许吧。但我的主要问题是,我想要例如显示当前对应的标签。最后聚焦的 JTextField(显示属性)。因此,一旦获得,我就可以将其设置为“默认点击”=>“自己的对话文本字段”。但我不想再次将其设置为“默认点击”,因为这不再是任何焦点。标签应保留“自己的对话框文本字段”的属性。在我的理解中,由于时间问题,失去焦点+获得焦点并不一定结合在一起。所以,依赖于特定事件顺序的代码不是我想要的。
    • 焦点事件的顺序具有一定的顺序 - 一个组件失去焦点,然后另一个组件获得焦点。当您激活(单击它,从另一个窗口等的 alt+tab 等)窗口(框架、对话框)时,它的一个组件总是获得焦点。如果窗口不是新的并且之前有焦点,焦点将返回给之前拥有它的组件。
    • 标签应该保留'own dialog textfield' umm的属性,但是其中的对话框和文本字段也没有焦点......
    • 我在一个 Frame 中有一个组件,它显示我自己的组件(=例如 JTextField)中的任何类型的属性(=例如 JTextArea)。从用户的角度来看,我希望,一旦我选择了自己的组件 (=JTextField) 并单击属性区域 (=JTextArea),我仍然希望获得最后选择的自写组件 (=JTextField) 的属性) 而不是任何先前选择的其他任何地方随机聚焦的组件的属性 [?]。
    • 好吧,我不想讨论得太详细。我对设计有自己的想法,并询问是否有人有解决方法的想法。
    【解决方案2】:

    我找到解决方法的方法是检查 focusGained 方法,如果当前组件在自己的 JDialog 中,并且之前的组件是 JFrame 中的 JTextField。如果是这样,那么我会记住获得的焦点组件,将焦点更改为另一个组件,当我收到 focusLost 时,我会请求将其返回到之前记住的组件。

    某种 hack,但它有效....如果有更好的想法,我很感兴趣...

    【讨论】:

      猜你喜欢
      • 2013-11-26
      • 2011-09-18
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多