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
Related
I have created a click handler on a gwt label, but it fails to fire. Whats wrong? Same method works for other widgets like icon etc.
#UiField Label fileName;
---
---
public void addClickHandler() {
fileName.sinkEvents(Event.ONCLICK);
handler = this.addHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
event.preventDefault();
event.stopPropagation();
Window.alert("UI clicked");
}
}, ClickEvent.getType());
}
As I pointed out in comment. Reason why it is not working is because you are adding native event handler to this, and as i but you need to sink DOM events on element to be able to handle them. As you did not do this for this element but for Label it won't work.
As You want to handle click element on Label, you need to add your handler to fileName and that will work
A combo box will fire an event if a DIFFERENT value is selected. I want to be also be able to listen to the SAME item being selected (that is, valueProperty has no change). There seems to be no way to do this.
I tried extending the ComboBox and finding a way to listen for the little popup menu being closed, but I don't even have access to that! What can I do?
Here is what I was trying:
class ResponsiveComboBox<E> extends ComboBox<E> {
public ResponsiveComboBox() {
super();
assert getContextMenu() != null; //Asssertion failed!
this.getContextMenu().setOnHiding((WindowEvent event) -> {
fireEvent(new ActionEvent());
});
}
}
comboBox.showingProperty().addListener((obs, wasShowing, isShowing) -> {
if (! isShowing) {
System.out.println("Combo box popup hidden");
}
});
This event handler might be triggered before the value is changed.
I have a cell table showing some data. For each row, I want to have two columns which contain edit / delete buttons. When each button is clicked, it should be able to notify a listener which button was clicked (and preferably also be able to pass in the object that row is associated with).
How can I do this? Specifically, I know how to render a button, but how can I process the on-click event and pass in the object which the user clicked to edit or delete?
This is the standard approach:
myTable.addCellPreviewHandler(new Handler<MyObject>() {
#Override
public void onCellPreview(CellPreviewEvent<MyObject> event) {
if ("click".equals(event.getNativeEvent().getType())) {
if (event.getColumn() == 0 || event.getColumn() == 1) {
MyObject object = event.getValue();
Window.alert("Column clicked: " + event.getColumn());
}
}
}
});
This is a more efficient solution, because you only have one handler attached to a table, instead of trying to attach a handler to each button in each row.
I think you can make a foreach through all the rows in the celltable (I never worked with celltables)
And then you can add your own ClickHandler to the Button.
Something like that (not tested):
final int row = myrow; // add the row value or a object identifier or similar
Button delete_button = new Button("delete");
delete_button.addClickHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event) {
// Insert your delete funciton
delete(row);
}
});
You mentioned a Listener, Listener are depreciated, use Handler instead.
I have a JComboBox component in the panel and ItemListener attached to it. But it gets fired after every up/down keypress (when scrolling though opened popup list). I want to change the selected value after the user accepts selection by pressing for example Enter key.
This is not a case when using mouse. When I move mouse over the combobox's list the highlight follows mouse pointer, but selected item is not changed until I press the mouse button. I would like to have the same behavior for keyboard, i.e. moving highlight via up/down arrow does not change selected item, but pressing Enter does.
I believe you should be able to do:
comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
after you have created your comboBox instance to get this functionality
In Java 8 they have fixed this behaviour, but only trigger if u set one UI property
UIManager.getLookAndFeelDefaults().put("ComboBox.noActionOnKeyNavigation", true);
the JComboBox.isTableCellEditor method works for arrow movement through the list, but does not work for type-ahead supported by the KeySelectionManager. i.e. you still get ActionEvents for every non-navigation key the user types, as the JComboBox interprets those characters for searching though the model to move to (or move close to) the user's intended selection.
this solution has a drawback in that it changes the action command for mouse clicks, which was a OK compromise for me because the the flow of the GUI forces the user to change the focus away from the combo box
I ended up making a special KeyListener, that relys on changing the combo box's default action command from comboBoxChanged to comboBoxMovement. Here's the line of code I need after my combo box is all initialized:
setExplicitSelectionManager(myComboBox);
... and here is the method and its contained class that do all the work:
private void setExplicitSelectionManager(JComboBox comboBox) {
class ExplicitSelectionManager implements KeyListener, FocusListener {
private JComboBox src;
private KeyListener superKeyListener;
ExplicitSelectionManager(JComboBox src) {
this.src = src;
// we like what the default key listener does, but not the action command
// it uses for ActionEvents it fires for plain text type-ahead characters
this.superKeyListener = src.getKeyListeners()[0]; // we only have one
src.removeKeyListener(superKeyListener); // will be replace right away, below
}
#Override
public void keyTyped(KeyEvent e) {
// basic combo box has no code in keyTyped
}
#Override
public void keyPressed(KeyEvent e) {
// in the default JComboBox implementation, the KeySelectionManager is
// called from keyPressed. I'm fine with the implementation of
// the default, but I don't want it firing ActionEvents that will cause
// model updates
src.setActionCommand("comboBoxMovement");
this.superKeyListener.keyPressed(e);
src.setActionCommand("comboBoxChanged");
if (e.getKeyCode() == 10) {
src.setSelectedIndex(src.getSelectedIndex());
}
}
#Override
public void keyReleased(KeyEvent e) {
// basic combo box has no code in keyReleased
}
#Override
public void focusGained(FocusEvent e) {
}
#Override
// this will also give us the event we want, if the user decides to Tab out of
// the combo box, instead of hitting Enter
public void focusLost(FocusEvent e) {
src.setSelectedIndex(src.getSelectedIndex());
}
}
ExplicitSelectionManager newSelectionManager = new ExplicitSelectionManager(comboBox);
comboBox.addKeyListener(newSelectionManager);
comboBox.addFocusListener(newSelectionManager);
}
... and here's the action performed method
private void comboBoxActionPerformed(java.awt.event.ActionEvent evt) {
JComboBox source = (JComboBox) evt.getSource();
// "comboBoxChanged" is the default,
// so any normal JComboBox can also use this action listener
if (evt.getActionCommand().equals("comboBoxChanged")) {
updateModel(source.getName(), (String) source.getSelectedItem());
}
}
Its the expected behavior with the ItemListener. whenever the displayed value changes the event is fired. For your requirement use an ActionListener.
MyJList myList = new MyJList();
myList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()){
System.out.println("Selected!");
}
}
});
.
.
.
class MyList extends JList{
public MyList () {
super();
this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setSelectedIndex(0);
}
}
When I click on list item with mouse, I see message «Selected!».
When program start, this message not shown, but item #0 is selected.
You setSelectedIndex in the constructor
Then after that, add the SelectionListener
when setSelectedIndex is called...there is no Listener
This is exactly what should happen. valueChanged is only called when the user selects the item. setSelectedIndex does not invoke any listeners.
Look at the order of you code:
a) you create the list and set the index to 0
b) you add the ListSelectionListener. Well nothing has changed since you added the listener so no event is fired.
Try adding:
list.setSelectedIndex(1)
after adding the listener to see if the event is fired.