gpt4 book ai didi

java - 单击节点时,在另一个组件的 focusLost 之前调用 JTree valueChanged 事件

转载 作者:行者123 更新时间:2023-11-30 04:22:40 25 4
gpt4 key购买 nike

我有一个 JTree,其中树的每个节点代表一些用户数据。数据是可编辑的并存储在文件/数据库中。有一堆 JTextField 可让您编辑/更新节点的用户数据。当 JTextField 失去焦点时,会触发保存数据事件。除非您更改 JTree 中节点的选择,否则这工作正常。因为JTree事件的valueChanged发生在JTextField的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。

如何保存该用户数据?我将不胜感激任何帮助/指示。

谢谢!

最佳答案

Because valueChanged of JTree event occurs before focusLost of JTextField.

  • 这是逻辑顺序,请勿更改它,一个 JComponents focusGained,然后是窗口焦点中的焦点所有者 focusLost

  • Focus 非常异步,因为 JTextComponent 可以延迟从添加的 Listeners/InputMask/Formatter 触发的事件,可以解决通过延迟invokeLater,忘记了这一点,而不是你的问题

  • (我...)从 JTextField 中删除 TreeSelectionListener,移至(逻辑)JTree

  • 添加 System.out.println(getText());,作为 public void valueChanged(TreeSelectionEvent e) { 的第一行代码,看看发生了什么:-),有地方可以存储(使用 Runnable#ThreadSwingWorker 将任何内容重定向到 Workers Thread)

    <
  • 然后还有一个问题,如果 JTextField 中的值发生更改并且用户单击同一节点,然后值保持不变或 JComponent 用原始值刷新,会发生什么,但这是关于业务逻辑,而不是关于如何编码,我的猜测

关于java - 单击节点时,在另一个组件的 focusLost 之前调用 JTree valueChanged 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16642037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com