Clear Selection when TableView loses focus - java

I'm trying to clear the selection when my table view loses focus. Right now, when I click on my add button, a new EMPTY row is added and I set it so the first column is on edit. If I click anywhere outside that cell, nothing happens. The cell remains selected which is not really what I want.
I'd prefer for the cell to become unselected when my tableview is unfocused.
I use a javafx.scene.control.TableView over a custom entry.
I tried setting on each column a setOnEditCancel but it doesn't work.
expressionTableColumn.setOnEditCancel(event -> {
final ObservableList<TableEntry> items = tableView.getItems();
if (items.contains(EMPTY_ENTRY)) {
items.remove(EMPTY_ENTRY);
}
tableView.getSelectionModel().clearSelection();
}
);
I'd prefer to clearSelection on table losing focus. Any ideas?

Add a ChangeListener to the focused property of Node (which TableView inherits). Then, when the new value of said property is false, retrieve the SelectionModel from the TableView's selectionModel property and call clearSelection().
tableView.focusedProperty().addListener((obs, oldVal, newVal) -> {
if (!newVal) {
tableView.getSelectionModel().clearSelection();
}
});

Related

Enable edit only for the selected row in the table

I am fairly new in JavaFX. I have a table with multiple columns and an Edit button in each row. Whenever I click on the Edit 1st cell is selected for edit of that row. Everything goes fine but the problem is whenever I select a row and click on a cell of it also gets in edit mode though I have not clicked Edit. I think it's because I have made tableView.setEditable(true) but I want to enable edit only when I click Edit button and only for that row, not others when I double click/ single click. I have seen this but they have solved it by a pop-up. I don't want that.
In the initialize() method I tried this way but it's not working exactly. Can anyone show me the correct way to do this, please?
tableBuilding.setRowFactory(tv -> {
TableRow<ModelBrBuilding> row = new TableRow<>();
row.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
if (e.getButton() == MouseButton.SECONDARY) {
e.consume();
}
});
row.addEventFilter(MouseEvent.MOUSE_PRESSED,event -> {
if ( event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2 ) {
event.consume();
}
});
return row ;
});
and my button action looks like
EditButton.setOnAction((ActionEvent event)->{
TableRow row = cell.getTableRow();
tableBuilding.requestFocus();
tableBuilding.getSelectionModel().select(row.getIndex());
int i=tableBuilding.getSelectionModel().getSelectedIndex();
tableBuilding.edit(i,colName);
});
There may be a more elegant solution to this, but you could simply set the TableView editable right before you call tableView.edit(int, TableColumn) and then set it back to not being editable when the edit is either committed or cancelled. Or you can do this set\unset editable thing on each specific TableColumn.
For instance, in your Button's action handler:
button.setOnAction(evt -> {
evt.consume();
tableView.requestFocus();
tableView.edit(-1, null); // cancel any current edit if there is one
tableView.getSelectionModel().select(tableCell.getIndex());
tableView.setEditable(true);
tableView.edit(tableCell.getIndex(), tableColumn);
});
And then for the TableColumn:
EventHandler<TableColumn.CellEditEvent<S, T>> handler = evt -> tableView.setEditable(false);
tableColumn.setOnEditCancel(handler);
tableColumn.setOnEditCommit(handler);
// or you can use the addEventHandler(EventType, EventHandler) method

JList remove selected items on keystroke and click

My task is to enable removing Jlist selected elements when alt is pressed and jlist is clicked. I did this by adding mouse listener to my jlist:
list.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
java.util.List selectedItems = list.getSelectedValuesList();
if (e.isAltDown()){
for (Object o : selectedItems){
cm.removeElement(o); //cm is my custom model
}
}
}
});
My issue is that when there are two elements selected and I click the list with alt pressed only nearest element gets selected and is removed then. I have no clue how to remove several elements with this input combination.
The problem is that the mouse click clears all the previous selections and then selects the row you just clicked on. So therefore only that row is deleted.
So instead you should be handling a "right mouse" click and then use the right mouse button only for the deletion of the item.
if (e.isAltDown() && SwingUtilities.isRightMouseButton(e)) {
Or if you really want to do this on a left mouse click then you would probably need to use a ListSelectionListener. Every time the selection changes you would need to use the getSelectedValuesList() method and save the List returned from the method. Then in the MouseListener you would access the saved List instead of getting the currently selected List of items.
I don't like this approach because the logic is now contained in two separate listeners. Although I guess you could create a class that implement both the selection listener and the mouse listener.
This is not a perfect answer. But it solves the issue.
I just tried to see how the selection event works. When he selection happens an Mouse pressed event is triggered and then the Selection happens. So the MouseListeners which are already added to the component are responsible to make the selection. Removing the MouseListeners which are already in place would prevent the selection happen using mouse. So i did this.
MouseListener[] adapters = list.getMouseListeners();
for (int i = 0; i < adapters.length; i++) {
list.removeMouseListener(adapters[i]);
}
Now user will not be able to do the selection using mouse but he will be make the selection using keyboard. So the below would work.
list.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
java.util.List selectedItems = list.getSelectedValuesList();
if (e.isAltDown()){
for (Object o : selectedItems){
model.removeElement(o); //cm is my custom model
}
}
}
});
I think the answer given by camickr, should be followed.

How to resfresh SWT Table after deleting a row

I have a SWT Table and a couple of buttons to add and remove rows in the table, the add button works fine, after clicking it the new row is immediately added at the end of the table but when I select a row and then click the delete button seems that nothing happens, but when I click on the table it is refreshed displaying the correct result, the question is, how can I refresh the table after deleting a row?
I tried calling this methods with no success:
table.redraw();
table.refresh();
This is how my table looks like:
Table table = new Table(container, SWT.BORDER | SWT.FULL_SELECTION);
And my Delete button:
Button btnRemove = new Button(container, SWT.NONE);
btnRemove.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
table.remove(table.getSelectionIndices());
}
});
Found the problem, I have a Text component inside the rows, so If I delete the row seems that the Text field remains, so the solution is to dispose the Text before removing the row, like this:
textField.dispose();
table.remove(table.getSelectionIndex());

Excel-like JTable Cell Editor, with an empty cell at edition start

I'm trying to have a JTable edition working like in excel: if I start editing a cell, the cell becomes empty for receiving the new entry. The goal is to avoid the user having to delete the existing cell content first.
I can already detect cell start/stop edition by adding a PropertyChangeListener working as follow:
public void propertyChange(PropertyChangeEvent e)
{
// A cell has started/stopped editing
if ("tableCellEditor".equals(e.getPropertyName()))
{
if (table.isEditing())
processEditingStarted();
else
processEditingStopped();
}
}
Trying to clear the table model at processEditingStarted() does not work with the code bellow:
private void processEditingStarted()
{
SwingUtilities.invokeLater( this );
}
public void run()
{
row = table.convertRowIndexToModel( table.getEditingRow() );
column = table.convertColumnIndexToModel( table.getEditingColumn() );
oldValue = table.getModel().getValueAt(row, column);
newValue = null;
table.getModel().setValueAt(null, row, column);
table.updateUI();
}
However the editor content keeps the former value.
Does someone has clues to hide the current value of the cell during edition?
Optionnaly it should be able to restore the former cell content if the user did not actually modify the value.
I"ve never seen a spreadsheet remove data when you start editing a cell.
Table Select All Editor shows a different approach.
I did it like this. First I am using the event keyReleased and then getting the row and column number on which I am working and then setting the value at that row. Code goes like this.
private void purchases_TBLKeyReleased(java.awt.event.KeyEvent evt) {
int rowWorking = purchases_TBL.getSelectedRow();
int columnWorking = purchases_TBL.getSelectedColumn();
if(columnWorking==3){
model.setValueAt(null, rowWorking, columnWorking);
}
}
This makes the third column of the table null as soon as I focus move on to that using keyboard.
Note: The same piece of code can be placed in MouseClicked event.

Actionperformed not triggered for JComboBox

I have an ActionListener attached to a JComboBox(uneditable). Once an item from the JComboBox is selected, I have to make the next button in the frame visible.
The skeleton of the code looks like this:
public void actionPerformed(ActionEvent evt)
{
if(evt.getSource()==jComboBox){
if(jComboBox.getSelectedIndex()==-1)
//Display an alert message
else{
nextButton.setVisible(true);
//Do other actions
}
}
}
It is found that actionPerformed is called only when the second, third, fourth (and so on) items are selected. But actionPerformed is not called when the first item is selected the very first time. But if the first item is selected after selecting other items actioPerformed gets called and the code works fine.
This error appears on some systems and doesn't on other systems. Any help in this regard would be appreciated.
Thanks in Advance!!
This is the normal behavour. The ActionEvent is not fired when you reselect the same item. If you want the event to be fired when you create the combo box then your code should be something like:
JComboBox comboBox = new JComboBox(...);
comboBox.setSelectedIndex(-1); // remove automatic selection of first item
comboBox.addActionListener(...);
comboBox.setSelectedIndex(0);
or
JComboBox comboBox = new JComboBox();
comboBox.addActionListener(...);
comboBox.addItem(...);
comboBox.addItem(...);
Seems like you first condition is a little wrong.
If you want to execute certain code if no item is in your JComboBox, you should check content size : jComboBox.getItemCount()==0 instead of jComboBox.getSelectedIndex()==-1, because selected index can depend upon various conditions, while getItemCount() is only 0 when, well, combo box is empty :-)

Categories