JTree события кажутся неупорядоченными - PullRequest
3 голосов
/ 27 апреля 2010

Мне кажется, что события выбора дерева должны происходить после событий фокуса, но, похоже, это не так.Предположим, у вас есть 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);
 }
}

Ответы [ 3 ]

2 голосов
/ 28 апреля 2010

Пусть ваш слушатель текстового поля вызовет setSelectionPath(), чтобы выбрать TreePath для узла, соответствующего тексту.Методы DefaultMutableTreeNode могут использоваться для обхода дерева.Я бы использовал ActionListener в текстовом поле, но FocusListener должно работать - просто не полагайтесь на порядок, в котором приходят события TreeSelectionListener.

Вот пример получения узла " pizza " по умолчанию JTree:

JTree tree = new JTree();
TreeNode node = (TreeNode) tree.getModel().getRoot();
node = node.getChildAt(2).getChildAt(1);
TreePath pizza = new TreePath(((DefaultMutableTreeNode) node).getPath());
1 голос
/ 21 июня 2012

Хорошие новости: я попытался отложить логику выбора дерева до конца 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);
            }
       });
    }
});

Это решение решило мою проблему с привязкой данных. Надеюсь, это имеет смысл и для тебя.

0 голосов
/ 20 июня 2012

Плохие новости: та же проблема возникает при выборе другого узла дерева. Правильно выбрать тот же узел дерева, который редактирует ваше текстовое поле.

Хорошая новость: я обнаружил, что эта проблема действительно старая. Увидеть http://java.net/jira/browse/BINDING-67

...