Reputation: 55
I have a small GUI application, that processes mouse clicks, and stores them in a list:
package test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestGUI extends JFrame {
private final List<String> objects = new ArrayList<>();
private TestTree testTree;
final JPanel canvas = new JPanel() {
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
g.setColor(Color.BLACK);
for (final String object : objects) {
final String[] parts = object.split("--");
g.drawOval(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), 5, 5);
}
}
};
public TestGUI() {
final Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(canvas, BorderLayout.CENTER);
testTree = new TestTree(objects);
cp.add(testTree, BorderLayout.EAST);
setTitle("TestGUI");
canvas.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent me) {}
@Override
public void mousePressed(MouseEvent me) {}
@Override
public void mouseExited(MouseEvent me) {}
@Override
public void mouseEntered(MouseEvent me) {}
@Override
public void mouseClicked(MouseEvent me) {
objects.add(me.getX() + "--" + me.getY());
testTree.update();
canvas.repaint();
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestGUI();
}
});
}
}
I want to represent an overview of the list using a JTree at the side of the canvas. The class responsible for the JTree is as follows:
package test;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
public class TestTree extends JPanel {
final List<String> objects;
private JTree tree;
private final DefaultMutableTreeNode root;
public TestTree(final List<String> theObjects) {
objects = theObjects;
root = new DefaultMutableTreeNode("root");
tree = new JTree(root);
add(new JScrollPane(tree));
}
private void updateTree(final List<String> objects) {
root.removeAllChildren();
final DefaultMutableTreeNode result = new DefaultMutableTreeNode(objects.size() + " objects");
for (final String object : objects) {
final DefaultMutableTreeNode objectNode = new DefaultMutableTreeNode(object);
result.add(objectNode);
}
root.add(result);
tree.updateUI();
}
public void update() {
updateTree(objects);
tree = new JTree(root);
add(new JScrollPane(tree));
}
}
So, which is the correct way of updating the JTree by submitting the list? Because after some clicks my application renders a seperate tree for each added element, instead of one tree that gets updated over time:
Any suggestions would be appreciated. Thank you very much!
Upvotes: 0
Views: 142
Reputation: 20914
Your problem is in method update()
of class TestTree
. You keep adding another JScrollPane
to the TestTree
. You only want one JScrollPane
.
You correctly update the model of the JTree
and that's all you need to do. The JTree
will automatically update itself whenever its model changes.
Also, don't set the size of the JFrame
. Set the size of its components and call method pack()
which will make the JFrame
big enough to contain all its components.
In the below code I have commented out the lines you need to remove from your code.
Class TestTree
package test;
import java.awt.Dimension;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
public class TestTree extends JPanel {
final List<String> objects;
private JTree tree;
private final DefaultMutableTreeNode root;
public TestTree(final List<String> theObjects) {
objects = theObjects;
root = new DefaultMutableTreeNode("root");
tree = new JTree(root);
JScrollPane scrollPane = new JScrollPane(tree);
scrollPane.setPreferredSize(new Dimension(100, 490));
add(scrollPane);
}
private void updateTree() {
root.removeAllChildren();
final DefaultMutableTreeNode result = new DefaultMutableTreeNode(objects.size() + " objects");
for (String object : objects) {
final DefaultMutableTreeNode objectNode = new DefaultMutableTreeNode(object);
result.add(objectNode);
}
root.add(result);
tree.updateUI();
}
public void update() {
updateTree();
// tree = new JTree(root);
// add(new JScrollPane(tree));
}
}
Class TestGUI
package test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestGUI extends JFrame {
private final List<String> objects = new ArrayList<>();
private TestTree testTree;
final JPanel canvas = new JPanel() {
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
g.setColor(Color.BLACK);
for (final String object : objects) {
final String[] parts = object.split("--");
g.drawOval(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), 5, 5);
}
}
};
public TestGUI() {
final Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(canvas, BorderLayout.CENTER);
testTree = new TestTree(objects);
cp.add(testTree, BorderLayout.EAST);
setTitle("TestGUI");
canvas.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent me) {}
@Override
public void mousePressed(MouseEvent me) {}
@Override
public void mouseExited(MouseEvent me) {}
@Override
public void mouseEntered(MouseEvent me) {}
@Override
public void mouseClicked(MouseEvent me) {
objects.add(me.getX() + "--" + me.getY());
testTree.update();
TestGUI.this.pack();
canvas.repaint();
}
});
canvas.setPreferredSize(new Dimension(400, 490));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
// setSize(500, 500);
setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestGUI();
}
});
}
}
Upvotes: 2