Adding double-click expansion to the Tree Viewer in SWT - java

Double-Clicking tree items works completely fine, but when I press CTRL + M on the keyboard then the tree items expand\collapse, can someone please tell me the reason behind this? Is this a bug in Eclipse or why does this double-click functionality get triggered when I press CTRL+M.
Thanks.

Use TreeViewer.addDoubleClickListener to listen for tree double clicks not a mouse listener. You could use something like this:
private class DoubleClickListener implements IDoubleClickListener
{
#Override
public void doubleClick(final DoubleClickEvent event)
{
final IStructuredSelection selection = (IStructuredSelection)event.getSelection();
if (selection == null || selection.isEmpty())
return;
final Object sel = selection.getFirstElement();
final ITreeContentProvider provider = (ITreeContentProvider)treeViewer.getContentProvider();
if (!provider.hasChildren(sel))
return;
if (treeViewer.getExpandedState(sel))
treeViewer.collapseToLevel(sel, AbstractTreeViewer.ALL_LEVELS);
else
treeViewer.expandToLevel(sel, 1);
}
}
Update:
Using TreeViewer.addDoubleClickListener is the preferred way to do double click handling for all classes derived from StructuredViewer.
Each double click listener is run using SafeRunnable which deals with any exceptions that the listener may throw, this safeguards the rest of the code for errors in the listeners.
The DoubleClickEvent provides direct access to the model object data so it is not necessary to deal with Tree or TreeItem objects to work out selections.
The double click code in the TreeViewer interfaces correctly with the OpenStrategy single / double click to open code.

I think the following code will be better , cause it will not cause the tree item to reload children and will keep the original state of other tree items.
_treeViewer.addDoubleClickListener( new IDoubleClickListener()
{
#Override
public void doubleClick( DoubleClickEvent event )
{
ISelection selection = event.getSelection();
if( selection instanceof ITreeSelection )
{
TreePath[] paths= ((ITreeSelection)selection).getPathsFor(selectedItem);
for (int i= 0; i < paths.length; i++)
{
_treeViewer.setExpandedState(paths[i], !_treeViewer.getExpandedState(paths[i]));
}
}
}
}
} );

Related

How do you create a custom item in Spigot 1.16.5?

I'm making a plugin that adds some useful items like House Building Wand, Exploding Sword, etc. But how can I add those items using the plugin?
Normally, you would want to make a class for your item.
For example, you can make a class HouseBuildingWand.java and add some Java logic in it.
public class HouseBuildingWand {
public static ItemStack getHouseBuildingWand() {
ItemStack houseBuildingWand = new ItemStack(Material.YOUR_ITEM);
return houseBuildingWand;
}
}
To make the ability, you have to use Java knowledge.
To add enchantments, flags, lore, names, check out https://bukkit.gamepedia.com/Plugin_Tutorial#Item_Manipulation.
To get the item, you would need a command or an event that would give you the item.
To check how the item was clicked, you can use an event listener with the event PlayerInteractEvent. Example:
#EventHandler
public void onRightClick (PlayerInteractEvent event) {
Player p = event.getPlayer();
if (event.getAction() == Action.RIGHT_CLICK_AIR) {
if (event.getItem().getType() == Material.YOUR_ITEM) {
// insert logic
}
}
}

TestFX clickOn() on particular text on combobox/choicebox

I‘m new to TestFX GUI-testing with fxrobot (javafx).
My current task is about clicking on a choice on a drop down menu created with combobox. I didn‘t find any tutorials mentioning this issue.
Is it really possible to implement the clickOn() method selecting a text in a combobox/drop down menu? Is there an example how to do it?
Thanks a million!
This is an example of a way where a user selects the given text in the given combobox.
void user_selects_combo_item(String comboBoxId, String itemToSelect) {
ComboBox<?> actualComboBox = lookupControl(comboBoxId);
// Find and click only on arrow button. This is important for editable combo-boxes.
for (Node child : actualComboBox.getChildrenUnmodifiable()) {
if (child.getStyleClass().contains("arrow-button")) {
Node arrowRegion = ((Pane) child).getChildren().get(0);
robot.clickOn(arrowRegion);
Thread.sleep(100); // try/catch were skipped for shorter code.
robot.clickOn(itemToSelect);
}
}
Assert.fail("Couldn't find an arrow-button.");
}
private <T extends Node> T lookupControl(String controlId) {
T actualControl = robot.lookup(controlId).query();
assertNotNull("Could not find a control by id = " + controlId, actualControl);
return actualControl;
}

Double click listener on a tree viewer

I have a selection changed listener on a tree viewer wherein If I single click the items in the tree depending on the selected item the combo viewer's selection changes accordingly.
Now I need to implement a double-click functionality on the same tree so that the tree expands and collapses hiding the functionality of the selection changed listener. Right now the priority is on the selection changed listener so even if I add a double-click listener to the same tree the selection change event gets triggered. Is there any way I can have both selection change listener(for selection change events) and Double-click listener(to expand/collapse tree items) on the same tree?
Code for IDoubleClickListener
public class TreeViewerDblClkListener implements IDoubleClickListener {
#Override
public void doubleClick(DoubleClickEvent event) {
Object obj = event.getSource();
if (obj instanceof TreeViewer) {
TreeViewer viewer = (TreeViewer) obj;
ISelection selection = viewer.getSelection();
if (selection instanceof IStructuredSelection) {
Object item = ((IStructuredSelection) selection).getFirstElement();
if (viewer.getExpandedState(item)) {
viewer.collapseToLevel(item, AbstractTreeViewer.ALL_LEVELS);
} else {
viewer.expandToLevel(item, 1);
}
}
}
}
}
It does throw an assertion failed exception.
org.eclipse.core.runtime.AssertionFailedException: null argument:
at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
at org.eclipse.jface.viewers.AbstractTreeViewer.getExpandedState(AbstractTreeViewer.java:1202)
at com.commons.viewers.TreeViewerDblClkListener.doubleClick(TreeViewerDoubleClickListener.java:20)
at org.eclipse.jface.viewers.StructuredViewer$1.run(StructuredViewer.java:845)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
Is anyone aware of what is happening here?

How to add a function in jTable that sorts the column?

I know that by using JTable the column is sorted when we click on the column heading, but what I want is that, when I right-click on the column name a function name 'sort' should be displayed. Any suggestion in doing it?
Start by adding a MouseListener to the table. See How to write mouse listeners
You will need to translate the click point to a column, see JTable#columnAtPoint.
You will then need to update the SortKey for the table. Check out Sorting and Filtering for an example
If I understand you correctly, you want to sort by some explicit action (triggered f.i. in a popup) instead of by the normal left-click.
If so, the tricky part is to force the ui-delegate to do nothing. There are two options:
hook into the default mouse listener installed by the ui delegate, as described in a recent QA
let the ui do its stuff, but fool it by a sorter implementation that doesn't follow the rules (beware: that's as dirty as the first approach!)
The mis-behaving sorter:
public class MyTableRowSorter extends TableRowSorter {
public MyTableRowSorter(TableModel model) {
super(model);
}
/**
* Implemented to do nothing to fool tableHeader internals.
*/
#Override
public void toggleSortOrder(int column) {
}
/**
* The method that really toggles, called from custom code.
*
* #param column
*/
public void realToggleSortOrder(int column) {
super.toggleSortOrder(column);
}
}
// usage
final JTable table = new JXTable(new AncientSwingTeam());
table.setRowSorter(new MyTableRowSorter(table.getModel()));
Action toggle = new AbstractAction("toggleSort") {
#Override
public void actionPerformed(ActionEvent e) {
JXTableHeader header = SwingXUtilities.getAncestor(
JXTableHeader.class, (Component) e.getSource());
Point trigger = header.getPopupTriggerLocation();
int column = trigger != null ? header.columnAtPoint(trigger) : -1;
if (column < 0) return;
int modelColumn = header.getTable().convertColumnIndexToModel(column);
((MyTableRowSorter) header.getTable().getRowSorter())
.realToggleSortOrder(modelColumn);
}
};
JPopupMenu menu = new JPopupMenu();
menu.add(toggle);
table.getTableHeader().setComponentPopupMenu(menu);
Yeah, couldn't resist throwing in some SwingX api, lazy me :-) With plain Swing, you'll have to write some lines more but the basics are the same: install the tricksy sorter and use its custom toggle sort to really sort whereever needed, f.i. in a mouseListener.

Poll for pressed buttons in Java

I have a WorldWind application build based on the Java SDK. It has a great event handler for detecting when you click on objects, but I've run into a snag. While I can click on and select individual objects, I can't determine if the user is pressing the control key while they click (if they want to select multiple objects). I can implement event handlers for both the mouse and the keyboard, but I can't for the life of me figure out how to tie the two together. How could I make my mouse listener poll the system for a list of currently depressed keys?
You can call getModifiers() and bitwise compare to see if the control key (or shift key was depressed during the event.
public void mouseClicked( MouseEvent e ) {
if( ( e.getModifiers() & ActionEvent.CTRL_MASK ) > 0 ) {
// Control key depressed
}
}
For a MouseEvent , you could just call the getModifiers() to get a mask of modifier keys(shift/control/alt etc.) keys that are pressed .
For the general case, use a variable to tie them together ?
Your keyhandler sets/clears the variable when it registers a keypress, your mouselistener checks that variable.
If you need to decople these a bit more, just create a instance that both your key listener and mouselistener accesses.
public class Pressedkeys {
private boolean shiftPressed = false;
private boolean controlPressed = false;
public void setShiftPressed(boolean pressed) {
this.shiftPressed = pressed;
}
public void setControlPressed (boolean pressed) {
this.shiftPressed = pressed;
}
public boolean isControlPresed() {
return controlPressed ;
}
...
}
Pressedkeys k = new PressedKeys();
MyMouseThing t = new MyMouseThing(k);
//your mousething mouse handler would check k.isControlPressed();
MyKeyboardThing t = new MyKeyboardThing (k);
//your KeyBoardThing - which has a key handler would set k.setControlPressed(..);

Categories