Java 为什么在编辑一个节点后,我会在JTree中短暂失去焦点?

Java 为什么在编辑一个节点后,我会在JTree中短暂失去焦点?,java,swing,focus,jtree,Java,Swing,Focus,Jtree,尝试:F2开始编辑,然后进入停止编辑,焦点切换到下一个组件,并在毫秒内返回到树节点。在本例中,您可以看到JTabbedPane标题中的聚焦绘制矩形闪烁。有了聚焦监听器,它会更清晰 为什么在编辑一个节点后,我会在JTree中短暂失去焦点 如何防止这种行为 public class Focus { private static void createAndShowGUI() { final JTextArea text = new JTextArea("Tab Header gained

尝试:F2开始编辑,然后进入停止编辑,焦点切换到下一个组件,并在毫秒内返回到树节点。在本例中,您可以看到JTabbedPane标题中的聚焦绘制矩形闪烁。有了聚焦监听器,它会更清晰

为什么在编辑一个节点后,我会在JTree中短暂失去焦点

如何防止这种行为

public class Focus {

private static void createAndShowGUI() {
    final JTextArea text = new JTextArea("Tab Header gained focus");

    JTree tree = new JTree();
    tree.setEditable( true );
    int row = 0;
    while( row < tree.getRowCount() ) {
        tree.expandRow( row++ );
    }

    JTabbedPane tabp = new JTabbedPane();
    tabp.addTab( "Lorem", text );
    tabp.addFocusListener( new FocusListener() {
        @Override
        public void focusLost( FocusEvent e ) { }
        @Override
        public void focusGained( FocusEvent e ) {
            text.setText( text.getText() +"\nWoohoo, I got the focus!" );
        }
    });

    JFrame frame = new JFrame( "Focus" );
    frame.setLayout( new BorderLayout() );
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(tree, BorderLayout.WEST);
    frame.getContentPane().add(tabp, BorderLayout.CENTER);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    tree.startEditingAtPath( tree.getPathForRow( 0 ) );

}
public static void main(String[] x) {
    EventQueue.invokeLater(new Runnable() {
        @Override public void run() {
            createAndShowGUI();
        }
    });
}
}
公共类焦点{
私有静态void createAndShowGUI(){
最终JTextArea文本=新的JTextArea(“选项卡标题获得焦点”);
JTree树=新的JTree();
tree.setEditable(true);
int行=0;
while(行
开始编辑时,该树向JTree层次结构添加DefaultCellEditor。此文本字段获得焦点。当编辑停止(按Enter键)时,BasicTreeUI.completeEditing()方法检查树本身还是编辑器组件是焦点所有者。在这种情况下,树将在编辑完成后再次聚焦

在停止算法中,编辑器将从树中删除。它以前是焦点所有者,因此焦点将转移到下一个可聚焦组件(焦点循环)。在您的UI中,这将是选项卡式窗格

由于编辑器以前是聚焦的,因此BasicTreeUI请求树的聚焦

这些步骤完全符合您描述的行为

唯一的解决方案(不完整,但显示了方向)是设置自己的FocusTraversalPolicy:

private static class TreeEditorFocusTraversalPolicy extends DefaultFocusTraversalPolicy {
    private final JTree tree;
    public TreeEditorFocusTraversalPolicy(JTree tree) {
        this.tree = tree;
    }

    @Override
    public Component getComponentAfter(Container aContainer, Component aComponent) {
        if (aComponent instanceof CellEditor) {
            return tree;
        }
        return super.getComponentAfter(aContainer, aComponent); 
    }
}
将此实例设置为您的树:

tree.setFocusTraversalPolicy(new TreeEditorFocusTraversalPolicy(tree));
tree.setFocusCycleRoot(true);
到目前为止的问题是:焦点遍历(Tab,Shift+Tab)不再有效。焦点规避政策是Swing的一个重要组成部分,需要一些时间来制定有效的政策。也许我们可以看看法律反腐败政策,这是默认政策


希望这有助于进一步了解。

编辑完树节点并按enter键后,焦点将保留在刚刚编辑的JTree节点上。再次按F2键时,无论将鼠标移到何处,都可以重新编辑同一节点。焦点似乎没问题。