SWT Combo prevent shift + 9 event - java

I'm developing an Eclipse RAP application where I have to use a combo box. The user can type a RQL filter in the combo or to select already existing one. The problem comes when the user types a left bracket "(" - SHIFT + 9 combination. This combination traverse the existing filters - started from first to the last for each combination and deleted all the stuff typed before that.
I tried with the code below and with TraverseListener, but the event continue to occurs.
combo.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent event) {
if (event.character == '\u0000') { // used to prevent SHIFT + 9 (left bracket) combination when typing a filter in the combo
event.doit = false;
}
}
});
Could some one helps me with this? Thanks in advance!

Related

Swing JTable - Using key binding instead of KeyListener on Shift key

I'm sorry if this has been answered before, I tried to look for the solution, but I couldn't find anything relevant. I'm new to this, so there's a chance I completely overlooked or ignored something that would have led me to an easy solution.
I've implemented a key listener for the shift key so that when the user presses shift, he enters the cell exactly one row before into the edit more (please take a look at the code below). Although, there's one problem; If the user is currently entering data into the cell, the shift key doesn't work and when debugging, we can see that the the program never even enters the key listener. I've been told to use key binding instead of key listeners to fix this problem. I've tried to follow some tutorial online and it looks like I've failed. Any help will be much appreciated, thanks a lot!
Two key listeners (Tab works fine, while Shift does not):
table.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
//KeyCode 9 is a key code for the Tab key
if (e.getKeyCode() == 9) {
if(table.isCellEditable(table.getSelectedRow(),table.getSelectedColumn())) {
table.editCellAt(table.getSelectedRow(), table.getSelectedColumn());
} else {
table.editCellAt(table.getSelectedRow(), table.getSelectedColumn() + 1);
}
}
//The problem occurs here
//KeyCode 16 is a key code for the Shift key
if (e.getKeyCode() == 16) {
if(table.isCellEditable(table.getSelectedRow() + 1, table.getSelectedColumn())) {
table.editCellAt(table.getSelectedRow() + 1, table.getSelectedColumn());
table.setColumnSelectionInterval(table.getSelectedColumn(), table.getSelectedColumn());
table.setRowSelectionInterval(table.getSelectedRow() + 1, table.getSelectedRow() + 1);
} else {
table.editCellAt(table.getSelectedRow() + 1, table.getSelectedColumn() + 1);
table.setColumnSelectionInterval(table.getSelectedColumn() + 1, table.getSelectedColumn() + 1);
table.setRowSelectionInterval(table.getSelectedRow() + 1, table.getSelectedRow() + 1);
}
}
}
});
Here's my attempted (and failed) solution:
class ShiftAction extends AbstractAction{
public void actionPerformed(ActionEvent ae){
System.out.println("Shift");
table.editCellAt(table.getSelectedRow() + 1, table.getSelectedColumn());
table.setColumnSelectionInterval(table.getSelectedColumn(), table.getSelectedColumn());
table.setRowSelectionInterval(table.getSelectedRow() + 1, table.getSelectedRow() + 1);
}
}
shiftAction = new ShiftAction();
table.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT,KeyEvent.SHIFT_DOWN_MASK),"doShiftAction");
table.getActionMap().put("doShiftAction",shiftAction);
Hopefully the question's not too stupid, and once again, thanks in advance.
e.getKeyCode() == 9
First of all, don't use magic numbers. People reading the code don't know what "9" means. Use the provided fields from the KeyEvent API: KeyEvent.VK_???.
we can see that the the program never even enters the key listener.
Focus is on the JTextField being used as the editor for the cell so it receives the KeyEvent, not the table.
I've been told to use key binding instead of key listeners to fix this problem.
You need to use the appropriate InputMap. In this case it should be:
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
Read the section from the Swing tutorial on How to Use Key Bindings for more information.

Get associated mouse click from ExpandTree event in SWT

I'm trying to stop the tree from collapsing or expanding when the user double clicks a column on a tree. It should only be allowed if the user clicks on the first column.
See, if a user double clicks the checkbox on node2 world1, the tree expands or collapses. I don't want that to happen. My tree needs SWT.FULL_SELECTION to detect the clicks on each of the columns, so that's not the way to go.
My listener looks like this
tree.addTreeListener(new TreeListener() {
#Override
public void treeExpanded(TreeEvent e) {
TreeItem parent = (TreeItem) e.item;
Point p = new Point (e.x, e.y);
int column = CheckboxClickListener.getColumn(p,parent);
if (column > 0) {
e.doit = false;
}
}
#Override
public void treeCollapsed(TreeEvent e) {
TreeItem parent = (TreeItem) e.item;
Point p = new Point (e.x, e.y);
int column = CheckboxClickListener.getColumn(p,parent);
if (column != 0) {
e.doit = false;
}
}
});
Problem is, the mouse event that generated the click is not the same as the TreeEvent that expands the tree. Thus, the e.x and e.y are both zero, making my Point detection useless. Listening to the mouse event and maintaining the last x and y to check here in the TreeExpand event seems bug-prone since the user may also expand the tree using the keyboard (thus the x and y may not reflect the user action). I also considered adding a time constraint to check that but seems like a bad way to handle the issue.
How can I detect which mouse event triggered the expand event?
PS: e.doit=false does nothing, even outside the if condition, so help with stopping the tree from expanding/collapsing would be appreciated as well :)
Thank you!
I found someone saying this is a bug at this link http://www.eclipse.org/forums/index.php/t/257325/
The following code stops the tree from expanding on doubleclick but I'm not sure why or what are the side effects.
tree.addListener (SWT.MeasureItem, new Listener(){
#Override
public void handleEvent(Event event) {}
});
This stops the expanding when doubleclicking ANY column. Clicking on the small arrow at the left of the TreeItem still expands the tree (as it should).

ListSelectionEvent, firing an event when clicking the currently selected item in JList

Let 'x' be an item in the JList. When I click it for the first time, the event fires, when I click it again, the event does not fire. I have to click some other item and then come back to 'x'.
How can I fire the event repeatedly from 'x' without having to deal with other items.
This is my code:
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (list.getSelectedIndex() == -1) {} else {
String clicked = (String)list.getSelectedValue();
//method to fire is here
}
}
updateDisplays();
}
The ListSelectionListener reflects changes to the lists selection, you could use a MouseListener instead...
For example...
MouseListener ml = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent evt) {
if (SwingUtilities.isLeftMouseButton(evt) && evt.getClickCount() == 1) {
if (list.getSelectedIndex() != -1) {
int index = list.locationToIndex(evt.getPoint());
System.out.println("You clicked item # " + index);
}
}
}
}
list.addMouseListener(ml);
You can add a MouseListener and watch for clicks. Note that a click that changes the selection will fire both the MouseListener and your ListSelectionListener.
Another option is to immediately clear the selection from your ListSelectionListener; that way the next click will reselect and retrigger, although you will lose the ability to navigate through items with the keyboard.
It seems like sort of an unusual UX decision, though, to assign significance to a click on an already selected item in a list.
Adding based on your question comments: If you go the MouseListener route, I recommend looking for double-clicks instead of single-clicks if the click is going to execute an action (especially if the action changes data and is not undoable). Also note that your ListSelectionListener will execute actions as you navigate through the list with the keyboard, which may not be what you intend.
If your commands in your history list are typed, you could also consider using a drop-down combo box for both command entry and the history list, where a selection from history fills in the command text but does not execute. You'd also have an opportunity to add auto-complete from command history.

JavaFX TextArea: how to set tabulation width

How do I set tab width of JavaFX TextArea ?
When I use tabulation (tab key) in TextArea, the width of the tabulation is wide. I want to control the width, i.e., use 4 spaces. In the documentation I could not find a method to do this.
I tried this code (where taInput is a TextArea), but it is not working as it should:
taInput.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent e) {
if (e.getCode() == KeyCode.TAB) {
// TAB SPACES
StringBuilder sb = new StringBuilder(config.getTabSpacesCount());
for (int i=0; i<config.getTabSpacesCount(); i++) {
sb.append(' ');
}
taInput.insertText(taInput.getCaretPosition(), sb.toString());
e.consume();
}
}
});
Finally I found a way to do this.
It seems that the setOnKeyPressed() method is not good for this task because the event is handled after the keyPress action is executed.
The addEventFilter() handles the events before their actions are executed, so you can manipulate the events.
My new code:
taInput.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent e) {
if (e.getCode() == KeyCode.TAB) {
String s = StringUtils.repeat(' ', config.getTabSpacesCount());
taInput.insertText(taInput.getCaretPosition(), s);
e.consume();
}
}
});
#tenotron
your code also executes same logic for combination of TAB key with set of modifiers ( shift, control, alt, meta or shortcut). Meaning
In TextArea
Pressing TAB key = Ctrl(modifier) + TAB = .... = your logic.
To fix this issue , you have to use KeyCombination
Sample Code :
textArea.addEventFilter(KeyEvent.KEY_PRESSED,
new EventHandler<KeyEvent>() {
final KeyCombination combo = new KeyCodeCombination(
KeyCode.TAB);
#Override
public void handle(KeyEvent event) {
// check for only tab key
if (combo.match(event)) {
textArea.insertText(textArea.getCaretPosition(),
"I am not real TAB");
event.consume();
}
}
});
now Pressing TAB key results "I am not Real TAB" , ctrl+TAB will highlight the next Node on the scene.
Reference :
Correctly Checking KeyEvents
KeyCombination
From JavaFX 14 onward, the best way to deal with this is to use CSS to change the tab width, as shown in my answer to Setting the tab spacing/size visualization for a JavaFX TextArea
Replacing tab characters with multiple spaces doesn't have the same effect as tabs advance to the next tab stop, they don't add a fixed-width gap. Even if you adjusted for the characters preceding the tab, when not using a fixed-width font, an integer number of actual spaces may not give you the correct position.
Try making what you want displayed as a String. Then use s.replace("\t", " ");
if you want four spaces. This worked for me.

In Java, how to make shortcuts that similar to Emacs?

I want to know how to add shortcuts similar to Emacs's in my Java application. For example C-x C-f and C-x b.
Thanks.
Java provides a means to identify Modifier keys.
By Modifier keys I mean
Alt -- e.isAltDown();
Ctrl -- e.isControlDown();
Shift -- e.isShiftDown()
These acan be paired with other normal key press buttons from your keyboard to identify whether a combination has been pressed.
if( (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_X) )
{
}
e.getModifiers() can be used to identify the modifier as well as the mouse button clicked. This returns bit mask.
See here. http://www.leepoint.net/notes-java/GUI-lowlevel/keyboard/keyboard.html
I would use it something like this for Ctrl. This is overly simplified code, but you will get an idea.
JTextField sampleTxtFld= new JTextField();
sampleTxtFld.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e)
{
if((e.isControlDown() && e.getKeyCode() == KeyEvent.VK_X)
{
//identifies whether Ctrl + X has been pressed
// do some action here
}
}
public void keyReleased(KeyEvent e)
{
//some key released code here
}
public void keyTyped(KeyEvent e) {
}
});
As far as I know EMACS is an editor. If you want to change the KeyStrokes for editing command on Swing text components then you need to use Key Bindings. You can use the existing text Actions but just bind them to different KeyStrokes. See Key Bindings for a list of all the default bindings an some example of how to rebind and Action.

Categories

Resources