Java Swing:焦点问题

Mar*_*aux 6 java swing focus

我正在为我的游戏制作关卡编辑器.我有一个属性面板,我可以在其中修改所选对象的属性.我还有一个Save按钮来编写级别xml.

当编辑器组件失去焦点或被Enter按下时,将提交字段编辑(*).这很有效,但唯一的问题是,当我有这一系列动作时:

  1. 编辑一个字段
  2. 按保存按钮

因为,会发生什么:

  1. 我编辑该字段
  2. 我按下保存按钮
  3. 级别已保存
  4. 该领域失去了焦点
  5. 编辑已提交

如您所见,这是错误的顺序.当然我希望该字段失去焦点,这会导致提交然后保存级别.

是否有技巧,黑客或解决方法使字段首先失去焦点,然后执行保存按钮的动作侦听器?

提前致谢.

(*submit =字段的编辑也在对象属性中进行)


编辑:对于我正在使用FocusAdapter的字段focusLost:

FocusAdapter focusAdapter = new FocusAdapter()
{

    @Override
    public void focusLost(FocusEvent e)
    {
        compProperties.setProperty(i, getColor());
        record(); // For undo-redo mechanism
    }
};
Run Code Online (Sandbox Code Playgroud)

而对于按钮,一个简单ActionListener的actionPerformed`.

btnSave.addActionListener(new java.awt.event.ActionListener() {
     public void actionPerformed(java.awt.event.ActionEvent evt) {
         // Save the level
     }
});
Run Code Online (Sandbox Code Playgroud)

kle*_*tra 3

嗯...无法重现:在下面的代码片段中,总是在 actionPerfomed 之前通知丢失,与我是否单击按钮或使用助记符无关:

    final JTextField field = new JTextField("some text to change");
    FocusAdapter focus = new FocusAdapter() {

        @Override
        public void focusLost(FocusEvent e) {
            LOG.info("lost: " + field.getText());
        }

    };
    field.addFocusListener(focus);

    Action save = new AbstractAction("save") {

        @Override
        public void actionPerformed(ActionEvent e) {
            LOG.info("save: " + field.getText());
        }
    };
    save.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_S);
    JButton button = new JButton(save);
    JComponent box = Box.createHorizontalBox();
    box.add(field);
    box.add(button);
Run Code Online (Sandbox Code Playgroud)

另一方面,焦点是一个难以依赖的属性,顺序可能取决于系统(我的是 win vista)。检查该代码片段在您的代码片段上的表现如何。

  • 如果您看到与我相同的序列,则问题出在其他地方
  • 如果您在丢失之前获得了保存,请尝试将保存操作包装到invokeLater中(这会将其放在EventQueue的末尾,因此它会在所有待处理事件之后执行)

    Action save = new AbstractAction("save") {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    LOG.info("save: " + field.getText());
                }
            });
        }
    };
    
    Run Code Online (Sandbox Code Playgroud)