Java 三个事件似乎顺序错误

Java 三个事件似乎顺序错误,java,swing,events,jtree,Java,Swing,Events,Jtree,在我看来,树选择事件应该发生在焦点事件之后,但事实似乎并非如此。假设您有一个JTree和一个JTextField,其中JTextField由树中选择的内容填充。当用户更改文本字段时,在焦点丢失时,您将从文本字段更新树。但是,在文本字段上的焦点丢失之前,将更改树选择。这是不正确的,对吗?有什么想法吗?以下是一些示例代码: import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.even

在我看来,树选择事件应该发生在焦点事件之后,但事实似乎并非如此。假设您有一个JTree和一个JTextField,其中JTextField由树中选择的内容填充。当用户更改文本字段时,在焦点丢失时,您将从文本字段更新树。但是,在文本字段上的焦点丢失之前,将更改树选择。这是不正确的,对吗?有什么想法吗?以下是一些示例代码:

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

public class Focus extends JFrame
{
 public static void main(String[] args)
 {
  Focus f = new Focus();
  f.setLocationRelativeTo(null);
  f.setVisible(true);
 }

 public Focus()
 {
  Container cp = getContentPane();
  cp.setLayout(new BorderLayout());

  final JTextArea ta = new JTextArea(5, 10);
  cp.add(new JScrollPane(ta), BorderLayout.SOUTH);

  JSplitPane sp = new JSplitPane();
  cp.add(sp, BorderLayout.CENTER);

  JTree t = new JTree();
  t.addTreeSelectionListener(new TreeSelectionListener()
  {
   public void valueChanged(TreeSelectionEvent tse)
   {
    ta.append("Tree Selection changed\n");
   }
  });
  t.addFocusListener(new FocusListener()
  {
   public void focusGained(FocusEvent fe)
   {
    ta.append("Tree focus gained\n");
   }
   public void focusLost(FocusEvent fe)
   {
    ta.append("Tree focus lost\n");
   }
  });

  sp.setLeftComponent(new JScrollPane(t));
  JTextField f = new JTextField(10);
  sp.setRightComponent(f);

  pack();

  f.addFocusListener(new FocusListener()
  {
   public void focusGained(FocusEvent fe)
   {
    ta.append("Text field focus gained\n");
   }
    public void focusLost(FocusEvent fe)
{
    ta.append("Text field focus lost\n");
   }
  });
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
}

让文本字段侦听器调用,为与文本匹配的节点选择树路径。可以使用的方法遍历树。我会在文本字段上使用ActionListener,但是FocusListener应该工作,只是不依赖TreeSelectionListener事件到达的顺序

下面是在默认JTree中获取pizza节点的示例:


坏消息:我在选择另一个树节点时遇到了同样的问题。选择文本字段正在编辑的同一个树节点就可以了

好消息:我发现这个问题真的很老了。看见
更好的消息:我试图将树选择逻辑推迟到EDT的末尾,这将在文本字段的焦点离开后执行

JTree t = new JTree();
t.addTreeSelectionListener(new TreeSelectionListener()
{
   public void valueChanged(TreeSelectionEvent tse)
   {
       ta.append("Tree Selection changed\n");
       SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                logicInEDT...(tse);
            }
       });
    }
});

这个解决方案解决了我的数据绑定问题。希望这对您也有意义。

您永远不应该根据事件的顺序编写代码。您应该在事件分派线程上构建GUI:我同意您的观点:如果在树选择事件之前触发焦点事件,则更符合逻辑。因此,我不应该假设windowClosing事件将在windowClosed事件之前发生?有趣…已经有一段时间了,但我无法抗拒:我不应该假设windowClosing事件将先于windowClosing事件-多么愚蠢的评论,除非假设您没有阅读文档-不,你误解了,也许我没有解释。无论用户在文本字段中键入什么,在失去焦点时,都应更改当前选定的树节点。IIUC,setSelectionPath在从focusLost调用时正好执行此操作:它将选择更改为指定的树路径。如果您试图编辑一个节点,那么使用t.setEditabletrue可能会更容易;这将允许原位编辑。文本字段可能会显示“fooo”,但树中没有fooo。事实上,它甚至可能不是正在更改的节点标签-它可能只是所选节点的用户对象中的一个字段。在遍历树时检查每个用户对象似乎很容易。我通常在失败时返回null;当传递到setSelectionPath时,null清除选择。正如您所说的根本原因是TreeSelectionEvent在焦点丢失/获得事件之前触发。我用JTable和JList进行了测试,它们都很好,我的意思是,选择事件是在文本字段的焦点丢失后触发的。如果您使用的是一些数据绑定框架,我必须说,对于文本字段的承诺,使用MODIFY而不是focus_OUT可能是好的。不管怎样,我现在必须采取这个解决方案。对不起,我帮不了你了,到目前为止我只找到了这些。
JTree t = new JTree();
t.addTreeSelectionListener(new TreeSelectionListener()
{
   public void valueChanged(TreeSelectionEvent tse)
   {
       ta.append("Tree Selection changed\n");
       SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                logicInEDT...(tse);
            }
       });
    }
});