首先,我应该说我正在使用netbeans,而且我是整个java GUI游戏的新手。
所以,我的问题是我创建了自己的特定于我的项目的Tree结构,现在我想用我的结构构建JTree。
我正在阅读关于Jtree的主题,根据我的理解,我需要在我的结构中实现TreeModel接口。我也读过的另一种方法是使用DefaultMutableTreeNode,但我找不到任何使用它的例子,这对我来说很清楚。
现在我构建了整个树结构并填充了数据,并试图避免重建它。如何将树实现为Jtree?
package models;
import java.util.ArrayList;
import java.util.List;
public class IngredientTree {
private Node root;
public IngredientTree(){
root = new Node();
}
public IngredientTree(Node rootData) {
root = rootData;
}
public void setRoot(Node n){
root = n;
}
public Node getRoot(){
return root;
}
public void addToTree(Ingredient i){
if(root.getData().getName()=="") // Then it must be the root
root.setData(i);
else
addToTree(root,i);
}
private void addToTree(Node n, Ingredient i){
if(isFirstAdd(n)) //Has no parent and no children
n.addChild(new Node(i,n));
else if(n.hasChildren()){ //Has parent and children
if(!inChildren(n,i)){
if(inNode(n,i))
n.addChild(new Node(i,n));
}
else{
for(Node child : n.getChildren()){
addToTree(child,i);
}
}
}
else{ //Has parent but no children
n.addChild(new Node(i,n));
}
}
private boolean isFirstAdd(Node n){
return(!n.hasParent() && !n.hasChildren());
}
private boolean inChildren(Node n,Ingredient i){
for(Node child : n.getChildren()){
if(inNode(child,i))
return true;
}
return false;
}
private boolean inNode(Node n,Ingredient i){
return(i.getStartIndex() > n.getData().getStartIndex() &&
i.getEndIndex() < n.getData().getEndIndex());
}
public int countIngredients(){
return countIngredients(this.getRoot());
}
private int countIngredients(Node r){
int count = 0;
if(!r.hasChildren()){
return 1;
}else{
for(Node child: r.getChildren()){
count += countIngredients(child);
}
}
return count;
}
}
答案 0 :(得分:2)
您是否会建议实施树模型并围绕该结构进行重建?
是。引用here的FileTreeModel
就是一个例子。如How to Use Trees: Creating a Data Model中所述,“您只需要实现树模型,以便它使用现有数据结构中的信息。”
答案 1 :(得分:0)
我希望这堂课对您有帮助
package dharm.mytasks.component;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import dharm.mytasks.ui.helper.CommonHelper;
public class Tree<T extends Object> extends JTree {
private static final long serialVersionUID = 1L;
public Tree(T rootUserObj){
this(new TreeNode<>(rootUserObj));
}
public Tree(TreeNode<T> root) {
super(root);
this.setPreferredSize(new Dimension(150, 0));
// this.setRootVisible(false);
this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
this.setExpandsSelectedPaths(true);
}
@SuppressWarnings("unchecked")
public TreeNode<T> getRoot() {
return (TreeNode<T>) getModel().getRoot();
}
public void fillChildren(Consumer<TreeNode<T>> childFiller){
getRoot().fillChildren(childFiller);
}
/** Loop for all nodes (deep=true) */
public void forEachNodes(Consumer<TreeNode<T>> childConsumer){
TreeNode<T> root = getRoot();
childConsumer.accept(root);
root.forEach(childConsumer, true);
}
public T getRootUserObject(){
return getRoot().getUserObject();
}
public TreeNode<T> getSelectedNode(){
@SuppressWarnings("unchecked")
TreeNode<T> node = (TreeNode<T>) getSelectionModel().getSelectionPath().getLastPathComponent();
return node;
}
public T getSelectedUserObject(){
TreeNode<T> node = getSelectedNode();
if(node != null /*&& node.isLeaf()*/) {
return node.getUserObject();
}
return null;
}
public void setSelectedNode(TreeNode<T> node){
setSelectionPath(new TreePath(node.getPath()));
}
public void onChange(Consumer<T> consumer){
super.addTreeSelectionListener(evt->{
TreePath selectedPath = evt.getNewLeadSelectionPath();
if(selectedPath==null) return;
@SuppressWarnings("unchecked")
TreeNode<T> node = (TreeNode<T>) selectedPath.getLastPathComponent();
if(node != null && node.isLeaf()) {
T userObject = node.getUserObject();
consumer.accept(userObject);
}
});
}
public void onMouseRightClickOnNode(BiConsumer<TreeNode<T>, MouseEvent> consumer){
Tree<T> tree = this;
CommonHelper.onMouseRightClick(tree, evt->{
TreePath path = getPathForLocation(evt.getX(), evt.getY());
if(path==null) return;
tree.setSelectionPath(path);
TreeNode<T> node = tree.getSelectedNode();
consumer.accept(node, evt);
});
}
public void showPopupOnRightClick(BiConsumer<MyJPopupMenu, TreeNode<T>> popupMenuItemFiller){
this.onMouseRightClickOnNode((node,evt)->{
MyJPopupMenu popup = new MyJPopupMenu();
popupMenuItemFiller.accept(popup,node);
popup.show(evt.getComponent(), evt.getX(), evt.getY());
});
}
public static class TreeNode<T> extends DefaultMutableTreeNode {
private static final long serialVersionUID = 1L;
public TreeNode(T userObj){
super(userObj);
}
/** @param userObj
* @return child node
*/
public TreeNode<T> addChild(T userObj) {
TreeNode<T> child = new TreeNode<>(userObj);
add(child);
return child;
}
@Override
public T getUserObject(){
@SuppressWarnings("unchecked")
T userObject = (T) super.getUserObject();
return userObject;
}
@SuppressWarnings("unchecked")
public List<TreeNode<T>> getChildren(){
return (List<TreeNode<T>>) children;//.clone();
}
public void fillChildren(Consumer<TreeNode<T>> childFiller){
if(getChildCount() != 0)
super.removeAllChildren();
childFiller.accept(this);
forEach(child->child.fillChildren(childFiller), false);
}
/**
* @param childConsumer
* @param deep <code>true</code>=access all, <code>false</code>=first level children
*/
public void forEach(Consumer<TreeNode<T>> childConsumer, boolean deep){
getChildren().forEach(child->{
childConsumer.accept(child);
if(deep)
child.forEach(childConsumer, deep);
});
}
}
}
public class CommonHelper {
/**
* @param comp component where listener should add
* @param onRighClickConsumer
*/
public static void onMouseRightClick(Component comp, Consumer<MouseEvent> onRighClickConsumer){
comp.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e) && e.getClickCount()==1)
onRighClickConsumer.accept(e); //call on right click
}
});
}
}
答案 2 :(得分:0)
我希望这堂课对您有帮助
package dharm.mytasks.component;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import dharm.mytasks.ui.helper.CommonHelper;
public class Tree<T extends Object> extends JTree {
private static final long serialVersionUID = 1L;
public Tree(T rootUserObj){
this(new TreeNode<>(rootUserObj));
}
public Tree(TreeNode<T> root) {
super(root);
this.setPreferredSize(new Dimension(150, 0));
// this.setRootVisible(false);
this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
this.setExpandsSelectedPaths(true);
}
@SuppressWarnings("unchecked")
public TreeNode<T> getRoot() {
return (TreeNode<T>) getModel().getRoot();
}
public void fillChildren(Consumer<TreeNode<T>> childFiller){
getRoot().fillChildren(childFiller);
}
/** Loop for all nodes (deep=true) */
public void forEachNodes(Consumer<TreeNode<T>> childConsumer){
TreeNode<T> root = getRoot();
childConsumer.accept(root);
root.forEach(childConsumer, true);
}
public T getRootUserObject(){
return getRoot().getUserObject();
}
public TreeNode<T> getSelectedNode(){
@SuppressWarnings("unchecked")
TreeNode<T> node = (TreeNode<T>) getSelectionModel().getSelectionPath().getLastPathComponent();
return node;
}
public T getSelectedUserObject(){
TreeNode<T> node = getSelectedNode();
if(node != null /*&& node.isLeaf()*/) {
return node.getUserObject();
}
return null;
}
public void setSelectedNode(TreeNode<T> node){
setSelectionPath(new TreePath(node.getPath()));
}
public void onChange(Consumer<T> consumer){
super.addTreeSelectionListener(evt->{
TreePath selectedPath = evt.getNewLeadSelectionPath();
if(selectedPath==null) return;
@SuppressWarnings("unchecked")
TreeNode<T> node = (TreeNode<T>) selectedPath.getLastPathComponent();
if(node != null && node.isLeaf()) {
T userObject = node.getUserObject();
consumer.accept(userObject);
}
});
}
public void onMouseRightClickOnNode(BiConsumer<TreeNode<T>, MouseEvent> consumer){
Tree<T> tree = this;
CommonHelper.onMouseRightClick(tree, evt->{
TreePath path = getPathForLocation(evt.getX(), evt.getY());
if(path==null) return;
tree.setSelectionPath(path);
TreeNode<T> node = tree.getSelectedNode();
consumer.accept(node, evt);
});
}
public void showPopupOnRightClick(BiConsumer<MyJPopupMenu, TreeNode<T>> popupMenuItemFiller){
this.onMouseRightClickOnNode((node,evt)->{
MyJPopupMenu popup = new MyJPopupMenu();
popupMenuItemFiller.accept(popup,node);
popup.show(evt.getComponent(), evt.getX(), evt.getY());
});
}
/** Reload/refresh in GUI */
public void reload(){
((DefaultTreeModel) getModel()).reload();
}
public static class TreeNode<T> extends DefaultMutableTreeNode {
private static final long serialVersionUID = 1L;
public TreeNode(T userObj){
super(userObj);
}
/** @param userObj
* @return child node
*/
public TreeNode<T> addChild(T userObj) {
TreeNode<T> child = new TreeNode<>(userObj);
add(child);
return child;
}
@Override
public T getUserObject(){
@SuppressWarnings("unchecked")
T userObject = (T) super.getUserObject();
return userObject;
}
@SuppressWarnings("unchecked")
public List<TreeNode<T>> getChildren(){
return (List<TreeNode<T>>) children;//.clone();
}
public void fillChildren(Consumer<TreeNode<T>> childFiller){
if(getChildCount() != 0)
super.removeAllChildren();
childFiller.accept(this);
forEach(child->child.fillChildren(childFiller), false);
}
/**
* @param childConsumer
* @param deep <code>true</code>=access all, <code>false</code>=first level children
*/
public void forEach(Consumer<TreeNode<T>> childConsumer, boolean deep){
getChildren().forEach(child->{
childConsumer.accept(child);
if(deep)
child.forEach(childConsumer, deep);
});
}
}
}