2013-05-20 1 views
1

У меня есть JTree, где каждый узел дерева представляет некоторые пользовательские данные. Данные доступны для редактирования и хранятся в файле/db. Существует множество JTextField, которые позволяют редактировать/обновлять пользовательские данные для узла. Сохранение события данных запускается, когда JTextField теряет фокус. Это отлично работает, если вы не изменили выбор узла в JTree. Поскольку valueChanged из события JTree возникает перед focusLost JTextField.Событие JTree valueChanged вызывается перед focusLost другого компонента при щелчке по узлу

Вот SSCCE: http://pastebin.com/wH1Veqdc

public class JTreeFocusTest extends JFrame{ 
     private static final long serialVersionUID = 1L; 
     public JTreeFocusTest() { 
       super("JTree Focus Test"); 
       JPanel panel = new JPanel(true); 
       panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 
       MyTree tree = new MyTree(); 
       panel.add(tree); 
       panel.add(Box.createVerticalStrut(20)); 
       panel.add(new MyTextField(tree)); 
       panel.add(Box.createVerticalStrut(20)); 
       panel.add(new JTextField(30)); 
       getContentPane().add(panel); 
       setVisible(true); 
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       pack(); 
     } 

     public static void main(String[] args){ 
       new JTreeFocusTest(); 
     } 
} 

class MyTree extends JTree{ 
     private static final long serialVersionUID = 1L; 
     public MyTree() { 
       DefaultMutableTreeNode root = new DefaultMutableTreeNode(new MyNode("Root", "Root")); 
       DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(new MyNode("Child 1", "DOC122122")); 
       root.add(child1); 
       DefaultMutableTreeNode child2 = new DefaultMutableTreeNode(new MyNode("Child 2", "DOC134342")); 
       root.add(child2); 
       DefaultTreeModel model = new DefaultTreeModel(root, true); 
       setModel(model); 
       getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 
       setSelectionPath(getPathForRow(0)); 
     } 
} 

class MyTextField extends JTextField implements FocusListener, TreeSelectionListener{ 
     private static final long serialVersionUID = 1L; 
     private MyTree tree; 
     public MyTextField(MyTree tree) { 
       this.tree = tree; 
       setText("Some"); 
       addFocusListener(this); 
       this.tree.addTreeSelectionListener(this); 
       Dimension dim = new Dimension(200, 20); 
       setPreferredSize(dim); 
       setMaximumSize(dim); 
       setMinimumSize(dim); 
     } 
     @Override 
     public void focusGained(FocusEvent e) {System.out.println("TextField gained focus");} 
     @Override 
     public void focusLost(FocusEvent e) { 
       getSelectedNodeUserObj().setValue(getText()); 
     } 
     @Override 
     public void valueChanged(TreeSelectionEvent e) { 
       setText(getSelectedNodeUserObj().getValue()); 
     } 
     private MyNode getSelectedNodeUserObj(){ 
       return ((MyNode)((DefaultMutableTreeNode)this.tree.getSelectionPath().getLastPathComponent()).getUserObject()); 
     } 
} 

class MyNode{ 
     private String label = ""; 
     private String value = ""; 

     public MyNode(String label, String value) { 
       this.label = label; 
       this.value = value; 
     } 
     public void setValue(String value){ 
       this.value = value; 
     } 
     public String getValue(){ 
       return value; 
     } 
     public String toString(){ 
       return label; 
     }  
} 

В этом примере я просто одно поле, но в реальном приложении у меня есть несколько полей, которые представляют данные пользователя. Также JTextField - это просто пример, поле ввода может быть JComboBox или JSpinner.

Как сохранить данные пользователя? Я был бы признателен за любую помощь/указатель.

Спасибо!

+0

Отправьте код здесь, а не на pastebin. – camickr

+0

Его долго вставлять сюда. Я думал, что это будет неудобно, потому что иногда это затрудняет чтение. – Mo3z

ответ

2

Поскольку valueChanged из события JTree возникает перед focusLost из JTextField.

  • это логический порядок, не изменить, один JComponents focusGained, то после того, как владелец фокуса focusLost в фокусе в окне

  • Focus вполне асинхронный, для JTextComponent может быть отсрочено события стрельба из добавленного Listeners/InputMask/Formatter, может быть решена путем задержки в invokeLater, забыли об этом, а не о вашей проблеме

  • (I am ...) удалить TreeSelectionListener от JTextField, перейти (логический) JTree,

  • System.out.println(getText()); добавить, что 1-й строки кода в public void valueChanged(TreeSelectionEvent e) { см Что случилось :-), есть место для хранения (использование Runnable#Thread, SwingWorker перенаправить независимо в Workers Thread)

  • затем остается вопрос, что происходит, если значение изменено в JTextField, и пользователь нажимает на тот же узел, тогда значение остается неизменным или JComponent обновляется с исходным значением, но это касается бизнес-логик, а не о том, как кодировать , мои предположения

+0

1. Порядок событий -> JTree.valueChanged> JTextField.focusLost> JTree.focusGained. Как может valueChange для JTree не получить фокус? Возможно, я не буду следовать. 2. TreeSelectionListener на самом деле находится в JTree в приложении. Просто чтобы собрать SSCCE, я поместил его в JTextField. 3. Не могли бы вы объяснить это больше? Я получаю текст, который мне нужен, но я теряю выделение, то есть узел. 4. Если я разрешу проблему, в которой focusLost JTextField всегда запускается перед чем-либо в JTree, это решит проблему. – Mo3z

+0

не focusLost может быть инициализирован из focusGained, то выбор JTrees вызвал focusGained, пожалуйста, не изменяйте порядок событий, cand be fragille, breakable, (потому что) Я уверен, что можно создать код для двух JComponents, которые меняют Focus в Window, теория находится в моем посте, где Focus программно добавляется к JComponents, добавленному к утилите.Список, не задумываясь, потому что не уверен, что произошло в этом случае, который добавлен DocumentListener (Filter), inputmask, formatter, вызвал длинный цикл для JComboBox & JSpinner и JTextField (где используется JTextComponent как редактор) – mKorbel

+0

Получил это спасибо !! – Mo3z

Смежные вопросы