Pergunta

I am making a simulator with a JTree updating frequently. The nodes in the tree are all JProgressBars.

I'm calling tree.treeModel.insertNodeInto(,,) and treeModel.reload() to update the tree. the problem is that it instantly updates itself without waiting for a repaint() call. This causes the tree to flash. I have tried setting setDoubleBuffered(true) for the nodes, the tree, and the containers it is in, but nothing changes.

Here's my code: (The class File extends DefaultMutableTreeNode)

public class FileTree extends JTree {

    DefaultTreeModel myTreeModel;

    FileTree(File root) {
        super(root);
        myTreeModel = (DefaultTreeModel) this.getModel();
        this.treeModel = myTreeModel;
        this.setCellRenderer(new ProgressBarCellRenderer());
        this.setEditable(true);
    }

    public void update(File file, File parent) {
        myTreeModel.insertNodeInto(file, parent, parent.getChildCount());
        myTreeModel.reload();
    }

    class ProgressBarCellRenderer extends DefaultTreeCellRenderer {
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            File file = (File) value;
            JProgressBar progressBar;
            progressBar = new JProgressBar(0, file.length);
            progressBar.setValue(file.completed);
            progressBar.setPreferredSize(new Dimension((int)(Math.log(file.size)*50),10));
            return progressBar;
        }
    }

}
Foi útil?

Solução 2

I fixed it. I just changed

myTreeModel.insertNodeInto(file, parent, parent.getChildCount());

to

parent.add(file);

I don't know why it works now. But it does. Any comments are appreciated!

Outras dicas

I suspect that mixing heavy and light components is causing the flashing. The effect can be seen in this example by clicking on the circle or resizing the enclosing frame. For better guidance, please edit your question to include an sscce that exhibits the problem you describe.

I've got the same trouble with custom renderer.

Just make updates inside SwingUtilities.invokeLater

SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            myTreeModel.insertNodeInto(file, parent, parent.getChildCount());
        }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top