【问题标题】:Strange behavior after replacing a JTree in a JScrollPane在 JScrollPane 中替换 JTree 后的奇怪行为
【发布时间】:2011-07-24 18:05:38
【问题描述】:

这是my previous post 的后续问题。我正在尝试使用以下代码将 JTree 放置在 JScrollPane 中。 JTree 的初始化看起来很好,在 JTextField 中键入 100 然后 Enter 之后也很好。但是当我滚动垂直幻灯片、调整窗口大小或尝试扩展新的 JTree 节点时,我发现树回到了只有 10 个节点的原始状态。感谢您的帮助。

import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;


public class RandomJTree2 extends JFrame {

    private final JTextField jtf = new JTextField(10);
    private JTree tree;
    JScrollPane jsp;
    private Random generator = new Random();

    private JTree buildTree(int nnodes) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(0);
        DefaultMutableTreeNode cnode = node;
        for (int i = 1; i <= nnodes; i++) {
            System.out.println(i);
            DefaultMutableTreeNode newn = new DefaultMutableTreeNode(i);
            int j = generator.nextInt(2);
            System.out.println("j=" + j);
            if (j == 0 && i != 1) {
                DefaultMutableTreeNode parent = (DefaultMutableTreeNode)cnode.getParent();
                if (parent != null) {
                    parent.add(newn);
                    cnode = parent;
                } else {
                    node.add(newn);
                    cnode = newn;
                }
            } else {
                cnode.add(newn);
                cnode = newn;
            }
        }
        return new JTree(node);
    }

    public RandomJTree2() {
        setLayout(new BorderLayout());
        add(jtf, BorderLayout.NORTH);
        tree = buildTree(10);
        jsp = new JScrollPane(tree);
        add(jsp, BorderLayout.CENTER);

        jtf.addKeyListener(new KeyAdapter() {
                public void keyPressed(KeyEvent e) {
                    int key = e.getKeyCode();
                    if (key == KeyEvent.VK_ENTER) {
                        invalidate();
                        //                        jsp.remove(tree);
                        //                        tree = buildTree(Integer.parseInt(jtf.getText()));
                        //                        jsp.add(tree);
                        //                        remove(jsp);
                        tree = buildTree(Integer.parseInt(jtf.getText()));
                        jsp = new JScrollPane(tree);
                        add(jsp, BorderLayout.CENTER);
                        validate();
                    }
                }
            });

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        pack();
        setVisible(true);
    }

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

【问题讨论】:

    标签: java swing


    【解决方案1】:

    你在这里:

     tree = buildTree(Integer.parseInt(jtf.getText()));
     remove(jsp); //<--------------------
     jsp = new JScrollPane(tree);
     add(jsp, BorderLayout.CENTER);
     validate();
    

    您需要先移除旧的滚动窗格,然后再放入新的滚动窗格。

    【讨论】:

    • 谢谢!我以为我试过了,但没有奏效。无论如何,它现在工作正常。 :)
    • revalidate() + repaint() 以防止 Swing repaint +1 出现任何可能的问题
    • @mKorbel:你是说我不需要添加和删除,只需重新验证和重新绘制就足够了吗?
    • @Qiang Li 这两条代码行适用于所有情况,添加/删除/替换 JComponents,使用 LayoutManagers 更改/调整大小/减少某些内容,您必须删除,然后添加,最后的代码行将是revalidate + repaint :-) 这应该是 Swing 中的炼金术/技巧
    【解决方案2】:

    额外的小注释,如果在文本字段为空(或其他格式无效的数字)时在文本字段中按回车,则会出现错误。

    try {
        int yourNumer = Integer.parseInt(jtf.getText()); // pass this to buildTree() 
        if (key == KeyEvent.VK_ENTER) {// do your stuff}
    } catch (NumberFormatException e){
    // show a dialog or somthing :D
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 2012-08-31
      • 2015-01-15
      相关资源
      最近更新 更多