Why Selection event not triggered when selection is done using keyboard? - java

I have this Eclipse RCP application which uses SWT. Here is a sample code.
Combo combo = new Combo(shell, SWT.NONE);
combo.setItems(items); // items is a String[]
combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
combo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetDefaultSelected(SelectionEvent e) {
System.out.println("In widgetDefaultSelected");
}
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("In widgetSelected");
}
});
The combo has been set up in the code for auto complete. The selection event is supposed to get triggered for mouse or keyboard events. A selection using mouse triggers the selection event but one with keyboard does not. I am trying to see why.
My eclipse is not the latest, it is version is 3.6.2 and the swt JARs that come with it. I would appreciate any help.

Since the selection event is not triggered with keyboard, I added a KeyListener to the combo widget and check to see if the user has pressed enter key.
combo.addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if (e.keyCode==SWT.CR || e.keyCode==SWT.KEYPAD_CR) { // Enter key
Combo c = (Combo) e.getSource();
System.out.println(c.getText());
// Do rest of processing
}
}
});
Seems like I am getting the selected item out of the list box. So far it seems to be working OK.

Selection event is not used for keyboard events, the Javadoc of Combo#addSelectionListener is pretty clear here:
widgetSelected is called when the user changes the combo's list selection.
widgetDefaultSelected is typically called when ENTER is pressed the combo's text area.

Related

Java SWT: mouseUp() is not fired when opening a Dialog in mousDown()

My program opens a dialog if a certain string is clicked inside a StyledText. So in the mouseDown() I first want to check what has been clicked and then open a dialog. This works. After closing the dialog the mouseUp() is not called. This leads to selecting the text when moving the cursor, as if the user tries to select a text.
I can reproduce the behavior by performing the following tasks:
Click on String in StyledText
-> Dialog Opens
Close Dialog
Move Mouse without clicking
-> Text gets marked as selected
In my use case I don't need mouseUp() to be fired. But having it not fired means the OS assumes that the mouse button is still down and selects text. This may be the correct behavior if a dialog opens and steals the focus. But than there must be a possibility to tell the system, that the mouse button has been released.
myStlyedText.addMouseListener(new MouseListener() {
#Override
public void mouseUp(MouseEvent e) {
System.out.println("MouseUp is fired");
}
#Override
public void mouseDown(MouseEvent e) {
if (certainStringClicked()) {
openDialog();
}
}
#Override
public void mouseDoubleClick(MouseEvent e) {}
});
I can verify that mouseUp() is not called because "MousUp is fired" is not printed on console.
What is the best way to handle this? I already tried to set focus on another widget (setFocus() and forceFocus()), but that didn't help.
I tried to call mouseUp myself:
Event event = new Event();
event.type = SWT.MouseUp;
event.button = 1;
MouseEvent mouseUpEvent = new MouseEvent(event);
mouseUp(mouseUpEvent);
This leads to the message "MousUp is fired", but the selection problem still exists.
I could move the code into the mouseUp() method, but that's not actually what I want. The dialog should appear immediately. What else can I do?
Try adding myStlyedText.notifyListeners(SWT.MouseUp, null); to your code.
It should work.
myStlyedText.addMouseListener(new MouseListener() {
#Override
public void mouseUp(MouseEvent e) {
System.out.println("MouseUp is fired");
}
#Override
public void mouseDown(MouseEvent e) {
if (certainStringClicked()) {
myStlyedText.notifyListeners( SWT.MouseUp, null );
openDialog();
}
}
#Override
public void mouseDoubleClick(MouseEvent e) {}
});
This is not a good solution. But it may be a workaround for some.
It is possible to add SWT.MODELESS to the shell style in the constructor of the Dialog, which extends jface.dialog.Dialog.
setShellStyle(SWT.MODELESS);
MouseUp() get's fired now.
The problem here is that it is possible to open many dialogs by clicking the text although one dialog is already open.

SWT Table - Checkbox / Highlight Listeners

I have a SWT Table with check boxes enable on the rows to allow TableItems to be selected. I currently have a listener on there
myTable.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event selectionEvent) {}});
This listener fires both when a check box for a row is checked and when a row is highlighted / selected, I haven't been able to find a way to separate these actions. Am I using the wrong listener or is there a way to do this?
Thanks for any help.
You can check within the Listener if it's a checkbox event or a selection event:
myTable.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event e)
{
if(e.detail == SWT.CHECK)
{
// Checkbox
}
else
{
// Selection
}
}
});

Editable JCombobox avoid multiple DocumentEvents when the selection change from the popup

I have an editable JComboBox with a single listener on it.
It is a documentListener that execute some code when the user insert or remove some text inside the combobox textfield:
((JTextComponent)combobox.getEditor().getEditorComponent()).getDocument().addDocumentListener(..)
My problem is that when the user select an element from the popup and the content of the combobox textfield changes there are two events executed into the documentListener, one is a removeUpdate() corresponding to the deletion of the previous content and the other is a insertUpdate() corresponding to the insertion of the new value.
I want that only one execution of my code is done and not two. How can I avoid that the code is executed two times when the user select an entry from the popup?
I tried various combination of different listener but for now without result.
What I want in the end is that my code is execute only one time when:
- The user change the text into the combobox textfield.
- The user select an element from the combobox popup
Thanks in advance.
[EDIT 1]
As requested I updated adding SSCCE
myCombobox = new javax.swing.JComboBox<String>();
myCombobox.setEditable(true);
((JTextComponent)myCombobox.getEditor().getEditorComponent()).getDocument().addDocumentListener(
new DocumentListener(){
#Override
public void insertUpdate(DocumentEvent e) {
System.out.println("insert performed");
}
#Override
public void removeUpdate(DocumentEvent e) {
System.out.println("remove performed");
}
#Override
public void changedUpdate(DocumentEvent e) {
System.out.println("change performed");
}
});
myCombobox.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent event) {
if (event.getStateChange() == ItemEvent.SELECTED) {
System.out.println("Action performed");
}
}
});
Note that in this case I have an ItemEvent instead of an ActionEvent because I'm continuing to modify my code searching for a solution in any case the behavior should not be influenced by this.
You can check ((JTextComponent)combobox.getEditor().getEditorComponent()).hasFocus() to be sure user types in the editor.

Set the checkbox of a CheckboxTableViewer when the row is clicked

I am very new to SWT. Started working on it today actually. I have a table of type CheckboxTableViewer. What i want to be able to do is whenever the user selects the row (i.e clicks anywhere on the row) I want the check box to be checked (ticked). Currently I have a listener on the CheckboxTableViewer as follows:
diagnosesTableViewer.addCheckStateListener(new ICheckStateListener() {
#Override
public void checkStateChanged(CheckStateChangedEvent event) {
Nomenclature changedStateNomenclature = (Nomenclature) event
.getElement();
if (event.getChecked()) {
selectedNomenclatures.add(changedStateNomenclature);
} else {
selectedNomenclatures.remove(changedStateNomenclature);
}
}
});
I am able to select the row by checking on the checkbox. But i want to select the check box even when the user selects the row by clicking anywhere on that row on any column (not just the checkbox).
I guess that logic would go somewhere in the addSelectionChangedListener for the addSelectionChangedListener. But I am not sure how to go about it. Can anyone help me with this?
Use this code: Add selection listener to the table. ctv is the instance of of your CheckboxTableViewer.
Also I assumed CheckboxTableViewer allow only single selection not multi.
ctv.getTable().addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
int df = ctv.getTable().getSelectionIndex();
ctv.setChecked(ctv.getElementAt(df), !ctv.getChecked(ctv.getElementAt(df)));
}
});

MouseListener in Java Swing sometimes not respond

I've implemented right mouse click for open menu listener on my main Jframe, it works fine except one problem. One out of 5 (give or take) clicks it not responding, this can be very annoying for the user. Here is my code:
contentPane = new JPanel();
contentPane.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3)
{
//Do Stuff
}
}
});
Can you please help me
You won't get clicks from sub-components of contentPane.
I think your problem is that you have added things to your panel. When the user clicks at regions occupied by a sub-component, that sub-component get's the click event.
Quick fix: I would recommend you to add the same mouse listener to all sub-components.
You are not "clicking"
A click is when the mouse is pressed and release really quickly. If you are not careful you might get events for (for instance) "pressed, moved, released" instead of "clicked".
Quick fix: use mouseReleased event instead.
Use this Code instead:
private MouseAdapter listener = new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (downer) {
downer = false;
if (new Rectangle(e.getComponent().getLocationOnScreen(), e.getComponent().getSize())
.contains(e.getLocationOnScreen())) {
downer = false;
// CODE
new Thread(new Runnable(){
public void run(){
//Your Listener code
}
}).start();
/// COde
}
}
}
boolean downer = false;
public void mousePressed(java.awt.event.MouseEvent e) {
downer = true;
}
};
This code only reacts if you press on the component and release on the component AND starts a new Thread for the custom task. This should work allways, because the AWT Thread isnt blocked with long calculations.

Categories