简体   繁体   中英

JTree Progress bar blanks out on select

I am having an issue with JTree where the item blanks out on initial select and does not reflect the progress bar until deselected. Ref .gif:

在此处输入图片说明

Code:

import project3.game.Creature;
import project3.game.Job;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.*;

class CreatureCellRenderer extends DefaultTreeCellRenderer {
    private JPanel renderer = new JPanel();
    private DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
    private JLabel label = new JLabel();
    private JProgressBar progressBar = new JProgressBar();

    private Color backgroundSelectionColor;
    private Color backgroundNonSelectionColor;

    public CreatureCellRenderer() {
        progressBar.setMinimum(0);

        renderer.add(label);
        renderer.add(progressBar);

        backgroundSelectionColor = defaultRenderer.getBackgroundSelectionColor();
        backgroundNonSelectionColor = defaultRenderer.getBackgroundNonSelectionColor();
    }

    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        Component returnValue = null;
        if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
            Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
            if (userObject instanceof Creature) {
                Creature creature = (Creature) userObject;
                label.setText(creature.getName());

                Job job = creature.getJob();
                if (job == null) {
                    progressBar.setValue(0);
                } else {
                    progressBar.setMaximum(job.getDuration());
                    progressBar.setValue(job.getSecondsWorked());
                }

                if (selected) {
                    renderer.setBackground(backgroundSelectionColor);
                } else {
                    renderer.setBackground(backgroundNonSelectionColor);
                }
                renderer.setEnabled(tree.isEnabled());

                tree.setRowHeight(30);

                returnValue = renderer;
            }
        }
        if (returnValue == null) {
            returnValue = defaultRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
        }
        return returnValue;
    }

import javax.swing.*;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.*;
import java.util.EventObject;

public class CreatureCellEditor extends DefaultTreeCellEditor {

    public CreatureCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
        super(tree, renderer);
    }

    public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
        return renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
    }

    public boolean isCellEditable(EventObject anEvent) {
        return true;
    }
}

public class MainWindow extends JFrame implements ActionListener {

    public MainWindow() {
        setTitle("Project 1");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLookAndFeel();
        initComponents();
        setLayouts();
        setListeners();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void setController(MainController controller) {
        this.controller = controller;
    }

    private void setLookAndFeel() {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (Exception e) {
        }
    }

    private void initComponents() {
        btnLoadData = new JButton("Load File");
        btnSearchByIndex = new JButton("Search by Index");
        btnSearchByName = new JButton("Search by Name");
        btnSearchByType = new JButton("Search by Type");
        btnSortCreaturesByEmpathy = new JButton("By Empathy");
        btnSortCreaturesByFear = new JButton("By Fear");
        btnSortCreaturesByCapacity = new JButton("By Capacity");
        btnSortTreasuresByWeight = new JButton("By Weight");
        btnSortTreasuresByValue = new JButton("By Value");
        btnStartJob = new JButton("Start Job");
        txtOutput = new JTextArea(30, 80);
        treeCave = new JTree(new DefaultMutableTreeNode());
        treeCave.setPreferredSize(new Dimension(300, 0));

        btnSearchByIndex.setEnabled(false);
        btnSearchByName.setEnabled(false);
        btnSearchByType.setEnabled(false);
        btnStartJob.setEnabled(false);
    }

    private void setLayouts() {
        JPanel top = new JPanel(new GridLayout(4, 4, 5, 5));
        top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        top.add(btnLoadData);
        top.add(btnSearchByIndex);
        top.add(btnSearchByName);
        top.add(btnSearchByType);
        top.add(new JLabel("Sort Creatures"));
        top.add(btnSortCreaturesByEmpathy);
        top.add(btnSortCreaturesByFear);
        top.add(btnSortCreaturesByCapacity);
        top.add(new JLabel("Sort Treasures"));
        top.add(btnSortTreasuresByWeight);
        top.add(btnSortTreasuresByValue);
        top.add(new JLabel(""));
        top.add(btnStartJob);

        JScrollPane scrollPane = new JScrollPane(txtOutput);
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treeCave, scrollPane);

        JPanel bottom = new JPanel(new BorderLayout());
        bottom.add(splitPane, BorderLayout.CENTER);

        add(top, BorderLayout.PAGE_START);
        add(bottom, BorderLayout.CENTER);
        pack();
    }

    private void setListeners() {
        btnLoadData.addActionListener(this);
        btnSearchByIndex.addActionListener(this);
        btnSearchByName.addActionListener(this);
        btnSearchByType.addActionListener(this);
        btnSortCreaturesByCapacity.addActionListener(this);
        btnSortCreaturesByEmpathy.addActionListener(this);
        btnSortCreaturesByFear.addActionListener(this);
        btnSortTreasuresByValue.addActionListener(this);
        btnSortTreasuresByWeight.addActionListener(this);
        btnStartJob.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        Object source = actionEvent.getSource();
        if (source.equals(btnLoadData)) {
            loadGame();
        } else if (source.equals(btnSearchByIndex)) {
            searchByIndex();
        } else if (source.equals(btnSearchByName)) {
            searchByName();
        } else if (source.equals(btnSearchByType)) {
            searchByType();
        } else if (source.equals(btnSortCreaturesByCapacity)) {
            controller.sortCreaturesByCapacity();
        } else if (source.equals(btnSortCreaturesByEmpathy)) {
            controller.sortCreaturesByEmpathy();
        } else if (source.equals(btnSortCreaturesByFear)) {
            controller.sortCreaturesByFear();
        } else if (source.equals(btnSortTreasuresByValue)) {
            controller.sortTreasuresByValue();
        } else if (source.equals(btnSortTreasuresByWeight)) {
            controller.sortTreasuresByWeight();
        } else if (source.equals(btnStartJob)) {
            controller.startJob(selectedCreature, selectedCreatureNode);
        }
    }

    private void loadGame() {
        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new File("."));
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            File f = chooser.getSelectedFile();
            controller.loadFile(f.getAbsolutePath());
        }
    }

    private void searchByIndex() {
        try {
            String input = JOptionPane.showInputDialog(this, "Index:");
            int index = Integer.parseInt(input.trim());
            controller.searchByIndex(index);
        } catch (NumberFormatException e) {
            showError(e.getMessage());
        }
    }

    private void searchByName() {
        String input = JOptionPane.showInputDialog(this, "Name:");
        String name = input.trim();
        if (name.length() == 0) {
            showError("You must enter a name!");
            return;
        }
        controller.searchByName(name);
    }

    private void searchByType() {
        String input = JOptionPane.showInputDialog(this, "Type:");
        String type = input.trim();
        if (type.length() == 0) {
            showError("You must enter a type!");
            return;
        }
        controller.searchByType(type);
    }

    public void showMessage(String message) {
        JOptionPane.showMessageDialog(this, message);
    }

    public void showError(String error) {
        JOptionPane.showMessageDialog(this, error, "Error", JOptionPane.ERROR_MESSAGE);
    }

    public void setOutputText(String text) {
        txtOutput.setText(text);
    }

    public void populateTree(Cave cave) {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Cave");
        for (Party party : cave.getParties()) {
            DefaultMutableTreeNode partyNode = new DefaultMutableTreeNode(party);

            for (Creature creature : party.getCreatures()) {
                DefaultMutableTreeNode creatureNode = new DefaultMutableTreeNode(creature);
                partyNode.add(creatureNode);
            }

            root.add(partyNode);
        }

        TreeModel model = new DefaultTreeModel(root);
        treeCave.setModel(model);
        DefaultTreeCellRenderer renderer = new CreatureCellRenderer();
        treeCave.setCellRenderer(renderer);
        treeCave.setCellEditor(new CreatureCellEditor(treeCave, renderer));
        treeCave.setEditable(true);

        treeCave.addTreeSelectionListener(new TreeSelectionListener() {
            @Override
            public void valueChanged(TreeSelectionEvent e) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode)treeCave.getLastSelectedPathComponent();
                if (node.getUserObject() instanceof Creature) {
                    selectedCreatureNode = node;
                    selectedCreature = (Creature)node.getUserObject();
                    btnStartJob.setEnabled(true);
                } else {
                    selectedCreatureNode = null;
                    selectedCreature = null;
                    btnStartJob.setEnabled(false);
                }
            }
        });
    }

    public void updateTreeNode(TreeNode node) {
        DefaultTreeModel model = (DefaultTreeModel) treeCave.getModel();
        model.nodeChanged(node);
    }

    public void enableSearch() {
        btnSearchByIndex.setEnabled(true);
        btnSearchByName.setEnabled(true);
        btnSearchByType.setEnabled(true);
    }

    private JButton btnLoadData;
    private JButton btnSearchByIndex;
    private JButton btnSearchByName;
    private JButton btnSearchByType;
    private JButton btnSortCreaturesByEmpathy;
    private JButton btnSortCreaturesByFear;
    private JButton btnSortCreaturesByCapacity;
    private JButton btnSortTreasuresByWeight;
    private JButton btnSortTreasuresByValue;
    private JButton btnStartJob;
    private JTextArea txtOutput;
    private JTree treeCave;

    private MainController controller;

    private Creature selectedCreature;
    private TreeNode selectedCreatureNode;

I am still very new to Java, so I'm not really sure where I am going wrong with this. Any and all assistance would be greatly appreciated.

EDIT Adding a link to a workable program that shows the problem. It is not minimal yet, but I am in the process of creating one that is. Program Example

Here is a simple example of CreatureCellEditor :

import java.awt.*;
import java.util.EventObject;
import javax.swing.*;
import javax.swing.tree.*;

class CreatureCellEditor extends DefaultTreeCellEditor {
    private JProgressBar bar = new JProgressBar();
    public CreatureCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
        super(tree, renderer);
    }
    @Override public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
        System.out.println(value);
        Component c = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
        System.out.println(c.getSize());
        if (leaf) {
          return bar; //OK
        } else {
          return c; //NG
        }
    }
    @Override public boolean isCellEditable(EventObject anEvent) {
        return true;
    }
}

public class Main {
  public JComponent makeUI() {
    JTree treeCave = new JTree();
    DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
    treeCave.setCellRenderer(renderer);
    treeCave.setEditable(true);
    treeCave.setCellEditor(new CreatureCellEditor(treeCave, renderer));
    //treeCave.setEditable(true);
    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(treeCave));
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new Main().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM