焦点所有者临时更改为空 [英] Focus owner temporary changes to null

查看:133
本文介绍了焦点所有者临时更改为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Swing开发很陌生,希望我的问题不是愚蠢的。



我遇到了以下问题。我正在使用 KeyboardFocusManager 跟踪焦点,监听属性 permanentFocusOwner 更改。但是,当焦点从一个控件更改为另一个控件时,我得到 permanentFocusOwner 属性的中间变更为 null



当焦点位于其中一个面板或其子面板内时,我当前的UI逻辑正在对控件进行一些更改。然而,获取中间 null 打破了这个逻辑。



我在Google搜索了关于这个问题的信息,有什么相关的。

现在的问题是,这种行为是否是由设计,以及是否有一些方法来解决中间的空值。

下面是重现上述行为的最小应用程序:

  import java.awt。*; 
import java.beans。*;
import javax.swing。*;
$ b $ public class FocusNullTest extends JFrame {

public static void main(String [] args){
EventQueue.invokeLater(new Runnable(){
(); $ b $ self.setVisible(true);
}
});

$ b $ public FocusNullTest(){
setSize(150,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
容器contentPane = getContentPane();
contentPane.setLayout(new BoxLayout(contentPane,BoxLayout.X_AXIS));

contentPane.add(new JButton(1));
contentPane.add(new JButton(2));

KeyboardFocusManager focusManager =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(
permanentFocusOwner,
new PropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent e){
System.out (permanentFocusOwner改为:
+ e.getOldValue());
System.out.println(permanentFocusOwner改为:
+ e.getNewValue());
}
});






$ p $日志输出是:
$ b


(程序启动,焦点自动设置为按钮1)


permanentFocusOwner已更改: b $ b permanentFocusOwner更改为:javax.swing.JButton [,0,18,41x26,(已跳过)]

(点击按钮2)

permanentFocusOwner从以下版本更改:javax.swing.JButton [,0,18,41x26,(已跳过)]

permanentFocusOwner已更改为null

permanentFocusOwner已从:null更改为
permanentFocusOwner更改为:javax.swing.JButton [,41,18,41x26,(已跳过)]







(可选部分,代码意图)

我的目标是让东西看起来像列表视图,这些条目在聚焦时展开和显示更多的信息(当它们失去时则折回)。展开视图包含一些额外的按钮。

JList 似乎不是合适的控件,因为(1 )它不允许点击按钮,(2)其条目具有恒定的高度,而我希望条目在焦点上动态扩展。 JTable 与其编辑模式似乎也不是一个合适的解决方案,至少因为不断的条目大小



因此,我将plain JPanel 与垂直框布局作为容器一起使用,并订阅模型更改并手动更新视觉效果。问题是,当我点击一个按钮,包含列表项失去焦点。如果焦点暂时不会变为 null ,我可以检测到焦点仍然在列表项中。



  firePropertyChange(someProperty,oldValue,null)
firePropertyChange(someProperty,null,newValue)
code>

根据newVaue做些什么,等待第二个

I'm pretty new to Swing development, hope my question is not a stupid one.

I've got a following problem. I am tracking the focus using KeyboardFocusManager, listening for property permanentFocusOwner changes. However when the focus changes from one control to another, I get intermediate change of permanentFocusOwner property to null.

My current UI logic is making some changes to the controls when the focus is inside one of the panels or its child panels. However getting intermediate null breaks this logic.

I searched in Google for information about this problem, didn't find anything relevant.

The question is, whether this behaviour is by design, and if there is some way to workaround intermediate nulls.

Here is the minimal application reproducing the said behaviour:

import java.awt.*;
import java.beans.*;
import javax.swing.*;

public class FocusNullTest extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                FocusNullTest self = new FocusNullTest();
                self.setVisible(true);
            }
        });
    }

    public FocusNullTest() {
        setSize(150, 100);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container contentPane = getContentPane(); 
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS));

        contentPane.add(new JButton("1"));
        contentPane.add(new JButton("2"));

        KeyboardFocusManager focusManager =
            KeyboardFocusManager.getCurrentKeyboardFocusManager();
        focusManager.addPropertyChangeListener(
                "permanentFocusOwner",
                new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent e) {
                        System.out.println("permanentFocusOwner changed from: "
                                           + e.getOldValue());
                        System.out.println("permanentFocusOwner changed to  : "
                                           + e.getNewValue());
                    }
                });
    }
}

The log output is:

(program start, focus sets to button 1 automatically)
permanentFocusOwner changed from: null
permanentFocusOwner changed to : javax.swing.JButton[,0,18,41x26, (skipped)]
(clicked on button 2)
permanentFocusOwner changed from: javax.swing.JButton[,0,18,41x26, (skipped)]
permanentFocusOwner changed to : null
permanentFocusOwner changed from: null
permanentFocusOwner changed to : javax.swing.JButton[,41,18,41x26, (skipped)]


(optional part, on the code intention)
My goal is to make something looking like a list view, where the entries expand and display more information when they get focus (and collapse back when they lose it). The expanded view contains some additional buttons.

JList doesn't seem to be the appropriate control, because (1) it doesn't allow clicks on the buttons, and (2) its entries have constant height, whereas I want the entries to expand dynamically on focus. JTable with its edit mode seems to be not an appropriate solution as well, at least because of constant entry size.

So I am using plain JPanel with a vertical box layout as a container, and subscribe to model changes and update the visuals manually. The problem is that when I click on a button, the containing list item loses focus. I could detect that the focus still stays within the list item if the focus wouldn't change to null temporarily.

解决方案

KeyboardFocusManager is firing two events for most properties (as of beans spec, it shouldn't - never found out the reason, just guessing that the asynchrous nature of focus somehow might be the reason)

   firePropertyChange(someProperty, oldValue, null)
   firePropertyChange(someProperty, null, newValue)

for doing stuff depending on newVaue, wait for the second

这篇关于焦点所有者临时更改为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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