动态更改 JTree 的数据模型
dynamically changing data model for JTree
我有一个小型 GUI 应用程序,它处理鼠标点击并将它们存储在列表中:
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();
}
});
}
}
我想在 canvas 旁边使用 JTree 表示列表的概览。负责JTree的class如下:
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));
}
}
那么,提交列表更新JTree的正确方法是什么?因为在点击几次之后,我的应用程序为每个添加的元素呈现一棵单独的树,而不是随着时间的推移而更新的一棵树:
如有任何建议,我们将不胜感激。非常感谢!
您的问题出在 class TestTree
的方法 update()
中。您不断向 TestTree
添加另一个 JScrollPane
。你只想要一个 JScrollPane
.
您正确更新了 JTree
的模型,这就是您需要做的全部。 JTree
会在其模型更改时自动更新。
此外,不要设置 JFrame
的大小。设置其组件的大小并调用方法 pack()
,这将使 JFrame
足够大以包含其所有组件。
在下面的代码中,我注释掉了您需要从代码中删除的行。
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();
}
});
}
}
我有一个小型 GUI 应用程序,它处理鼠标点击并将它们存储在列表中:
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();
}
});
}
}
我想在 canvas 旁边使用 JTree 表示列表的概览。负责JTree的class如下:
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));
}
}
那么,提交列表更新JTree的正确方法是什么?因为在点击几次之后,我的应用程序为每个添加的元素呈现一棵单独的树,而不是随着时间的推移而更新的一棵树:
如有任何建议,我们将不胜感激。非常感谢!
您的问题出在 class TestTree
的方法 update()
中。您不断向 TestTree
添加另一个 JScrollPane
。你只想要一个 JScrollPane
.
您正确更新了 JTree
的模型,这就是您需要做的全部。 JTree
会在其模型更改时自动更新。
此外,不要设置 JFrame
的大小。设置其组件的大小并调用方法 pack()
,这将使 JFrame
足够大以包含其所有组件。
在下面的代码中,我注释掉了您需要从代码中删除的行。
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();
}
});
}
}