Java SWT 树菜单仅显示一级树
Java SWT Tree Menu Shown only for one level of the tree
我正在制作一个使用 java SWT 树结构的程序。这棵树是建立在从外部文件和用户输入中读取的数据之上的。
对于这棵树,我还附加了一个右键单击菜单。
主要问题是这棵树的菜单遍及他的所有项目,我希望它只在某个级别显示。
我还想为不同的树级别设置不同的菜单或菜单选项。
树的所有创建都在一个函数中:
public void createTree(final Composite container){
try{
for(Object element : container.getChildren()){
if(element instanceof Tree){
((Tree) element).dispose();
}
}
// function to verify if the tree is still in my container composite, and if so, I'll dispose the tree, because I am going to construct a new one
final Tree variantTree = new Tree(container, SWT.CHECK | SWT.V_SCROLL | SWT.H_SCROLL);//creating new tree object
variantTree.setBounds(10, 65, 400, 400);//dimensions
//variantTree.setData("variant"); -- wanted to abuse this method to make a difference between the tree's level,
//but this attribute is shared across all the tree, and I cannot make a distinction between my levels
if(..){
//here I am using the data saved in a tree data structure to populate my SWT Tree
}
variantTree.addListener(SWT.Selection, new Listener(){
//this is a listener used for the tree's checkboxes, using them to select different items from my tree
});
final Menu treeMenu = new Menu(variantTree);
variantTree.setMenu(treeMenu);//adding the right click menu
treeMenu.addMenuListener(new MenuAdapter(){
//the menu's items are declared here: the buttons that I want to have and the their listeners
//i am disposing the menu's items if there are any
MenuItem newItem = new MenuItem(treeMenu, SWT.NONE);
newItem.setText("new button... ");
newItem.addListener(SWT.Selection, new Listener(){
@Override
public void handleEvent(Event event) {
String item = variantTree.getSelection()[0].getText();//can I use this to make different menus for different tree levels?
for(Node element : TestControl.getTree().getChildren()){//getting the tree data structure that I have saved in a static way via a class
if(element.getName().equals(item)){
//opening a file dialog here and doing some operations
}
}
});
});
//this is where I want to make the distinction between the levels of the tree, such as that I will have this menu show up only for the root of my tree, or the first level of the tree, since I will have multiple trees
variantTree.addMenuDetectListener(new MenuDetectListener(){
@Override
public void menuDetected(MenuDetectEvent event) {
// TODO Auto-generated method stub
if(/*condition*/){ //I messed around with the tree's methods and attributes, nothing so far has come in handy to help me make a distinction between my tree's levels
event.doit = true;
//System.out.println(variantTree.getSelectionCount()); --I don't know if this can help me either, I tried to see if this will return differently for every level of the tree, but the return values is always 0
//find some kind of handle
}else{
event.doit = false;
}
}
});
另外,我想在树的第二层显示另一个菜单,我可以使用 String item = variantTree.getSelection()[0].getText();
,以某种方式修改以满足我的需要吗?比方说,String item = variantTree.getSelection()[1].getText();
为第二级?
我的 SWT 树的每个根的最大深度为 3,它看起来像这样:
root1 - 只想要这个项目的菜单
|---儿童 - 1级
|------儿童 - 2 级
root2 - 只想要这个项目的菜单
|---儿童 - 1级
|--------儿童 - 2 级
谢谢。
我已经通过以下方式解决了我的问题。
如果你真的看到我的代码,有以下几行:
for(Node element : TestControl.getTree().getChildren()){//getting the tree data structure that I have saved in a static way via a class
if(element.getName().equals(item)){
//opening a file dialog here and doing some operations
}
}
我正在获取我的树数据结构的第一层,然后我正在验证我的 SWT 树的根名称是否等于树数据结构的根。
使用相同的方法,这将导致 SWT 树的菜单侦听器结束:
variantTree.addMenuDetectListener(new MenuDetectListener(){
@Override
public void menuDetected(MenuDetectEvent event) {
// TODO Auto-generated method stub
for(Node element : TestControl.getTree().getChildren()){
if(variantTree.getSelection()[0].getText().equals(element.getName())){
event.doit = true;
break;//need this, because it will propagate only to the last item, or it will have a strange behaviour
}else{
event.doit = false;
}
}
}
});
其中 element
是我的树数据结构中的一个节点。
希望对遇到同样问题的人有所帮助。
无需比较TreeItem
文本,只需检查项目的级别,例如检查它是否有 parent.
public static void main(String[] args)
{
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setText("Whosebug");
shell.setLayout(new FillLayout());
final Tree tree = new Tree(shell, SWT.NONE);
for (int i = 0; i < 10; i++)
{
TreeItem item = new TreeItem(tree, SWT.NONE);
item.setText("Parent " + i);
for (int j = 0; j < 3; j++)
{
TreeItem child = new TreeItem(item, SWT.NONE);
child.setText("Child " + i + " " + j);
for (int k = 0; k < 3; k++)
{
TreeItem grandChild = new TreeItem(child, SWT.NONE);
grandChild.setText("Child " + i + " " + j + " " + k);
}
}
}
final Menu menu = new Menu(tree);
tree.setMenu(menu);
tree.addMenuDetectListener(new MenuDetectListener()
{
@Override
public void menuDetected(MenuDetectEvent e)
{
TreeItem treeItem = tree.getSelection()[0];
e.doit = getLevelOfItem(treeItem) < 2;
}
});
menu.addMenuListener(new MenuAdapter()
{
public void menuShown(MenuEvent e)
{
TreeItem item = tree.getSelection()[0];
setMenu(menu, item);
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static void setMenu(Menu menu, TreeItem item)
{
int level = getLevelOfItem(item);
MenuItem[] items = menu.getItems();
for (MenuItem i : items)
{
i.dispose();
}
switch (level)
{
case 0:
for(int i = 0; i < 2; i++)
{
MenuItem newItem = new MenuItem(menu, SWT.NONE);
newItem.setText("Menu item " + i);
}
break;
case 1:
for(int i = 0; i < 4; i++)
{
MenuItem newItem = new MenuItem(menu, SWT.NONE);
newItem.setText("Menu item " + i);
}
break;
}
}
private static int getLevelOfItem(TreeItem item)
{
int counter = 0;
while(item.getParentItem() != null)
{
item = item.getParentItem();
counter++;
}
return counter;
}
这将显示第 0 级和第 1 级的不同菜单,而不会显示第 2 级的菜单。
我正在制作一个使用 java SWT 树结构的程序。这棵树是建立在从外部文件和用户输入中读取的数据之上的。 对于这棵树,我还附加了一个右键单击菜单。
主要问题是这棵树的菜单遍及他的所有项目,我希望它只在某个级别显示。
我还想为不同的树级别设置不同的菜单或菜单选项。
树的所有创建都在一个函数中:
public void createTree(final Composite container){
try{
for(Object element : container.getChildren()){
if(element instanceof Tree){
((Tree) element).dispose();
}
}
// function to verify if the tree is still in my container composite, and if so, I'll dispose the tree, because I am going to construct a new one
final Tree variantTree = new Tree(container, SWT.CHECK | SWT.V_SCROLL | SWT.H_SCROLL);//creating new tree object
variantTree.setBounds(10, 65, 400, 400);//dimensions
//variantTree.setData("variant"); -- wanted to abuse this method to make a difference between the tree's level,
//but this attribute is shared across all the tree, and I cannot make a distinction between my levels
if(..){
//here I am using the data saved in a tree data structure to populate my SWT Tree
}
variantTree.addListener(SWT.Selection, new Listener(){
//this is a listener used for the tree's checkboxes, using them to select different items from my tree
});
final Menu treeMenu = new Menu(variantTree);
variantTree.setMenu(treeMenu);//adding the right click menu
treeMenu.addMenuListener(new MenuAdapter(){
//the menu's items are declared here: the buttons that I want to have and the their listeners
//i am disposing the menu's items if there are any
MenuItem newItem = new MenuItem(treeMenu, SWT.NONE);
newItem.setText("new button... ");
newItem.addListener(SWT.Selection, new Listener(){
@Override
public void handleEvent(Event event) {
String item = variantTree.getSelection()[0].getText();//can I use this to make different menus for different tree levels?
for(Node element : TestControl.getTree().getChildren()){//getting the tree data structure that I have saved in a static way via a class
if(element.getName().equals(item)){
//opening a file dialog here and doing some operations
}
}
});
});
//this is where I want to make the distinction between the levels of the tree, such as that I will have this menu show up only for the root of my tree, or the first level of the tree, since I will have multiple trees
variantTree.addMenuDetectListener(new MenuDetectListener(){
@Override
public void menuDetected(MenuDetectEvent event) {
// TODO Auto-generated method stub
if(/*condition*/){ //I messed around with the tree's methods and attributes, nothing so far has come in handy to help me make a distinction between my tree's levels
event.doit = true;
//System.out.println(variantTree.getSelectionCount()); --I don't know if this can help me either, I tried to see if this will return differently for every level of the tree, but the return values is always 0
//find some kind of handle
}else{
event.doit = false;
}
}
});
另外,我想在树的第二层显示另一个菜单,我可以使用 String item = variantTree.getSelection()[0].getText();
,以某种方式修改以满足我的需要吗?比方说,String item = variantTree.getSelection()[1].getText();
为第二级?
我的 SWT 树的每个根的最大深度为 3,它看起来像这样:
root1 - 只想要这个项目的菜单
|---儿童 - 1级
|------儿童 - 2 级
root2 - 只想要这个项目的菜单
|---儿童 - 1级
|--------儿童 - 2 级
谢谢。
我已经通过以下方式解决了我的问题。 如果你真的看到我的代码,有以下几行:
for(Node element : TestControl.getTree().getChildren()){//getting the tree data structure that I have saved in a static way via a class
if(element.getName().equals(item)){
//opening a file dialog here and doing some operations
}
}
我正在获取我的树数据结构的第一层,然后我正在验证我的 SWT 树的根名称是否等于树数据结构的根。
使用相同的方法,这将导致 SWT 树的菜单侦听器结束:
variantTree.addMenuDetectListener(new MenuDetectListener(){
@Override
public void menuDetected(MenuDetectEvent event) {
// TODO Auto-generated method stub
for(Node element : TestControl.getTree().getChildren()){
if(variantTree.getSelection()[0].getText().equals(element.getName())){
event.doit = true;
break;//need this, because it will propagate only to the last item, or it will have a strange behaviour
}else{
event.doit = false;
}
}
}
});
其中 element
是我的树数据结构中的一个节点。
希望对遇到同样问题的人有所帮助。
无需比较TreeItem
文本,只需检查项目的级别,例如检查它是否有 parent.
public static void main(String[] args)
{
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setText("Whosebug");
shell.setLayout(new FillLayout());
final Tree tree = new Tree(shell, SWT.NONE);
for (int i = 0; i < 10; i++)
{
TreeItem item = new TreeItem(tree, SWT.NONE);
item.setText("Parent " + i);
for (int j = 0; j < 3; j++)
{
TreeItem child = new TreeItem(item, SWT.NONE);
child.setText("Child " + i + " " + j);
for (int k = 0; k < 3; k++)
{
TreeItem grandChild = new TreeItem(child, SWT.NONE);
grandChild.setText("Child " + i + " " + j + " " + k);
}
}
}
final Menu menu = new Menu(tree);
tree.setMenu(menu);
tree.addMenuDetectListener(new MenuDetectListener()
{
@Override
public void menuDetected(MenuDetectEvent e)
{
TreeItem treeItem = tree.getSelection()[0];
e.doit = getLevelOfItem(treeItem) < 2;
}
});
menu.addMenuListener(new MenuAdapter()
{
public void menuShown(MenuEvent e)
{
TreeItem item = tree.getSelection()[0];
setMenu(menu, item);
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static void setMenu(Menu menu, TreeItem item)
{
int level = getLevelOfItem(item);
MenuItem[] items = menu.getItems();
for (MenuItem i : items)
{
i.dispose();
}
switch (level)
{
case 0:
for(int i = 0; i < 2; i++)
{
MenuItem newItem = new MenuItem(menu, SWT.NONE);
newItem.setText("Menu item " + i);
}
break;
case 1:
for(int i = 0; i < 4; i++)
{
MenuItem newItem = new MenuItem(menu, SWT.NONE);
newItem.setText("Menu item " + i);
}
break;
}
}
private static int getLevelOfItem(TreeItem item)
{
int counter = 0;
while(item.getParentItem() != null)
{
item = item.getParentItem();
counter++;
}
return counter;
}
这将显示第 0 级和第 1 级的不同菜单,而不会显示第 2 级的菜单。