I am developing a java application that uses a JTree. What i would like to archive is that when i click on a node that is already selected it gets deselected.
My current solution is to add a mouse listener and a tree selection listener to the jtree. But the problem is that valueChanged gets called only if there is a change in selection (and not if you select the same node twice). To fix this i added a boolean which indicated if the node was clicked for the first time and then i handle the deselect in the mouseReleased function. This works but the problem now is if the node has children and you want to expand it the node gets deselected and reselected again (which i dont want).
How could i fix this problem? Is there any better way of deselecting a already selected node?
The code:
public void initComponents()
{
elementsTree.addTreeSelectionListener(this);
elementsTree.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent me) {
TreePath tp = elementsTree.getPathForLocation(me.getX(), me.getY());
if (tp != null)
{
if(!nodeSelected && elementsTree.getSelectionModel().isPathSelected(tp) )
{
elementsTree.getSelectionModel().removeSelectionPath(tp);
}
}
nodeSelected = false;
}
});
}
public void valueChanged(TreeSelectionEvent e)
{
nodeSelected = true;
}
Thanks!
Just use the method clearSelection() from JTree.
Related
So am trying to make a project where the user can select from a tree a TreeItem called Category , and by that category, a table will sort so it matches it.
The problem is that am using WindowBuilder in Eclipse and I don't see an event that says so, or a way to make it that the point where the cursor is aiming at, is the Item selected (when clicking of course) .
The other thing is that, is there any way to use Jforms using WindowBuilder? I think there is a big difference between them.
And for information, I already searched in the net and all I found is solutions about TreeView which first I am not using and second I tested it and still it doesn't work.
This is the Code I used so I can detect the selected TreeItem when I click but it does not work either:
Tree tree = new Tree(Frame, SWT.BORDER);
tree.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
TreeItem item =
tree.getItem(Display.getCurrent().getCursorLocation());
if(item != null) {
...
You can get the selected TreeItem from the item property of SelectionEvent:
tree.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
// get the selected item
TreeItem item = (TreeItem) e.item;
if(item != null) {
...
In my project I need to fire an event after a node was clicked in my CellTree. I solved this with the following code.
model.setSelectionHandler(new SelectionChangeEvent.Handler()
{
#Override
public void onSelectionChange(SelectionChangeEvent event)
{
//My logic is here
}
});
The problem is that this only works if the node is not selected already. Clicking the node again will not fire the event. Is there a click handler or another event which is fired after a node was clicked?
Please try with SelectionHandler api .
This can be achieved by creating your own TreeItem that implements ClickHandler
public class CustomTreeItem extends TreeItem implements ClickHandler
{
//classes logic here
#Override
public void onClick(ClickEvent event)
{
// TODO Auto-generated method stub
}
}
Sometimes I use something like this:
model.setSelectionHandler(new SelectionChangeEvent.Handler()
{
#Override
public void onSelectionChange(SelectionChangeEvent event)
{
SomeType selected = model.getSelectedObject();
if (selected != null)
{
// Logic here...
model.clear();
}
}
});
But this solution obviously removes visual feedback what was selected.
You could add a DOM handler to your CellTree using [Widget.addDomHandler](http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/Widget.html#addDomHandler(H, com.google.gwt.event.dom.client.DomEvent.Type)):
cellTree.addDomHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
// TODO: check if a node is selected and it was clicked here
}
}, ClickEvent.getType());
Additionally you might need to prevent calling the handler twice if you use the selection handler as well and click a node.
Just a side note: Unfortunately I did not see an easy way to determine if the user actually clicked on a tree item like a bounds check for the click coordinates. So this might get a bit harder to achieve.
I have to handle an event in a combobox when the user click the item (not when the combobox change the state).
I have four combobox:
(1Combo: Parent category)
(2 Combo: The sons of the category 1)
(3 Combo: the sons of the category 2)
(4 combo: the sons of the category 3)
Each one calls the list to add the items for the other one (the sons of the category choosed).
But my problem is that I have an itemstatechange event and I want to know if the item has been clicked NOT if the combo changes state.
public void itemStateChanged(ItemEvent e) {
if (e.getSource()==jComboBoxCategorias1) {
handleEventCombo1();
}
if (e.getSource()==jComboBoxCategorias2) {
handleEventCombo2();
}
if (e.getSource()==jComboBoxCategorias3) {
handleEventCombo3();
}
if (e.getSource()==jComboBoxCategorias4) {
handleEventCombo4();
}
}
You can add a mouse listener to the combobox and implement the mouseClicked method.
comboBox.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println(comboBox.getSelectedItem());
}
});
Don't forget that comboBox is actually a container. So if you really want to have all the mouse events you should add the listener to all the components it contains.
public void addMouseListener(final MouseListener mouseListener) {
this.comboBox.addMouseListener(mouseListener);
final Component[] components = this.comboBox.getComponents();
for(final Component component : components) {
component.addMouseListener(mouseListener);
}
this.comboBox.getEditor().getEditorComponent().addMouseListener(mouseListener);
}
Please visit swing mouse listeners being intercepted by child components for more details.
I'm making a simple menu to delete items on a tree. However, after deleting the items, the tree does not receive a selection event, therefore, the code in the listener does not execute (the listener, in the full code, updates a part of the UI).
I have simplified the code below, leaving out details. It is something like this:
tree.addListener (SWT.Selection, new Listener(){
public void handleEvent(Event e) {
(....)
}
}
I also tried this:
tree.addSelectionListener (new SelectionListener(){
public void widgetDefaultSelected(SelectionEvent e){
(...)
}
public void widgetSelected(SelectionEvent e) {
(...)
}
}
On my menu action (delete selection), there is this:
TreeItem [] selected = tree.getSelection();
tree.deselectAll();
if (selected.length > 0)
{
for( TreeItem i : selected){
i.dispose();
}
}
After deleting the selection, my selection listener does not fire. It does fire if I deselect all itens using the ctrl+click combination.
What should I do? Is there a way to fire the SWT.Selection event to the tree after deleting the itens or should I isolate the code inside the listener to call it again? Shouldn't the tree.deselectAll() fire a Selection event?
You can send a selection event programmatically with:
Event event = new Event();
event.widget = tree;
event.display = tree.getDisplay();
event.type = SWT.Selection;
tree.notifyListeners(SWT.Selection, event);
Have same situation and found
this link mentioning, that programmatically setSelection may never send this event due to design, so always send it (if needed) programmatically after setting too
I have a JTree, and would like for its getTreeCellEditorComponent() method to be invoked when I single click on a node. According to the documentation for the DefaultTreeCellEditor class (which I extended), "Editing is started on a triple mouse click, or after a click, pause, click and a delay of 1200 miliseconds." Is there some way to override this behavior, so that a single-click could start the editing process?
The JTree API recommends a MouseListener, but a key binding is also handy. This example invokes startEditingAtPath() and binds to the Enter key:
final JTree tree = new JTree();
tree.setEditable(true);
MouseListener ml = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
int row = tree.getRowForLocation(e.getX(), e.getY());
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
if (row != -1) {
if (e.getClickCount() == 1) {
tree.startEditingAtPath(path);
}
}
}
};
tree.addMouseListener(ml);
tree.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "startEditing");
Addendum: See also this answer regarding usability.
Technically, you can subclass DefaultTreeCellEditor and tweaks its logic to start editing on the first single click:
JTree tree = new JTree();
tree.setEditable(true);
TreeCellEditor editor =
new DefaultTreeCellEditor(tree, (DefaultTreeCellRenderer) tree.getCellRenderer()) {
#Override
protected boolean canEditImmediately(EventObject event) {
if((event instanceof MouseEvent) &&
SwingUtilities.isLeftMouseButton((MouseEvent)event)) {
MouseEvent me = (MouseEvent)event;
return ((me.getClickCount() >= 1) &&
inHitRegion(me.getX(), me.getY()));
}
return (event == null);
}
};
tree.setCellEditor(editor);
There's a usability quirk, though, as now you can't select without starting an edit - which may or may not be your intention.