繁体   English   中英

Java Swing:焦点问题

[英]Java Swing: Focus issue

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

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

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

因为,会发生什么:

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

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

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

提前致谢。

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


编辑 :对于我正在使用FocusAdost的focusLost

FocusAdapter focusAdapter = new FocusAdapter()
{

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

对于按钮,一个简单的ActionListener与actionPerformed`。

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

嗯...无法重现:在下面的片段中,丢失的内容总是在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);

另一方面,焦点是一个难以依赖的属性,排序可能是系统依赖的(我的是胜利视野)。 检查代码段在您的代码上的行为方式。

  • 如果您看到与我相同的序列,则问题出在其他地方
  • 如果你在丢失之前得到了保存,请尝试将save动作包装到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()); } }); } }; 

通常,将保存代码包装到SwingUtilities.invokeLater()应该可以解决问题。 正如您已经提到的,这不起作用? 尝试这个:

private boolean editFocus = false;
FocusAdapter focusAdapter = new FocusAdapter()
{
   @Override
   public void focusGained(FocusEvent e){
        editFocus = true;
   }
   @Override
   public void focusLost(FocusEvent e){
       compProperties.setProperty(i, getColor());
       record(); // For undo-redo mechanism
       editFocus = false;
       if (saveRequested){
           save();               
       }
   }
};

并为您的按钮:

private boolean saveRequested = false;

btnSave.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
         if (editFocus){
             saveRequested = true;
             return;
         } else {
             save();
         }
    }
});

然后你的保存方法:

private void save(){
    // do your saving work
    saveRequested = false;
}

这仅适用于在按钮操作后调用focusLost时。 如果突然顺序正确,则此代码将调用save()两次。

但同样,在原始方法中包装save()代码应该有效,因为保存代码将在处理完所有事件后执行。 这是在处理按钮单击和focusLost事件之后。 因为你的focusLost代码立即执行(它没有包装在invokeLater()中),所以应该始终在保存代码之前执行focusLost代码。 这并不意味着事件顺序是正确的! 但是与事件关联的代码将按正确的顺序执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM