How to resfresh SWT Table after deleting a row - java

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());

Related

Clear Selection when TableView loses focus

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();
}
});

Java DefaultTableModel- how do I remove the selected row?

I have a table displayed in my Java GUI, which the user can add rows to by clicking an 'Add' button. The cells in the row that is added to the table are all editable by default, and the user can select each row/ cell as they wish.
I now want to add the functionality to remove a row from the table, but I can't seem to find the correct way to do this with a DefaultTableModel data type.
I have added the following code to the action listener for my 'remove row' button:
removeBtn.addActionListener(new ActionListener(){
public void removeRow(){
DefaultTableModel model = (DefaultTableModel)jEntityFilterTable.getModel();
model.removeRow();
}
});
However, the removeRow() method requires a parameter of type int (the index number of the row I want to remove). How can I get the 'selected row' from the DefaultTableModel? There doesn't appear to be a method that allows you to do this...
You can obtain the index from the table.
removeBtn.addActionListener(new ActionListener(){
public void removeRow(){
int selRow = jEntityFilterTable.getSelectedRow();
if(selRow != -1) {
DefaultTableModel model = (DefaultTableModel)jEntityFilterTable.getModel();
model.removeRow(selRow);
}
}
});

What is the best way to listen for changes in JTable cell values and update database accordingly?

I'm building and app with multiple JTables and I need to detect when cell value change occurs so I can update it in the database. I tried TableModelListener and overriding tableChanged, but it fires only when I click away (click on another row) after I have edited a cell.
Any other way to do this?
You can implement the CellEditorListener interface, as shown in this example. Note that JTable itself is a CellEditorListener.
It may also be convenient to terminate the edit when focus is lost, as shown here:
table.putClientProperty("terminateEditOnFocusLost", true);
More Swing client properties may be found here.
I'm agreeing with #mKorbel - unless all your input is checkboxes and dropdowns, you're going to want to wait until the cell editing is stopped (you don't want to commit to the database every time a letter is typed in a textbox).
If the problem is that it's not committing after focus has gone to another component, add a FocusListener that stops editing the table when focus is lost on the table:
Example:
final JTable table = new JTable();
table.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
TableCellEditor tce = table.getCellEditor();
if(tce != null)
tce.stopCellEditing();
}
});
I use the enter key so everytime a user hit enter the cell will update.
DefaultTableModel dtm = new DefaultTableModel(data, columnNames);
JTable table = new JTable(dtm);
table.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
// resul is the new value to insert in the DB
String resul = table.getValueAt(row, column).toString();
// id is the primary key of my DB
String id = table.getValueAt(row, 0).toString();
// update is my method to update. Update needs the id for
// the where clausule. resul is the value that will receive
// the cell and you need column to tell what to update.
update(id, resul, column);
}
}
});
This is also handy if you want to stop the editing on an event handler from selection change or save button.
if (table.isEditing())
table.getCellEditor().stopCellEditing();

Get TableCell content for SQL query

I'm writing an SQL CRUD application and stuck on the delete button problem. I have a table with 4 columns and a delete button in the fifth. To make an SQL query I need to get info from these 4 columns. I can get a row number and a column name, how to get cell content on row/column intersection?
Assuming the fifth column has a custom cell factory that puts the delete button in its custom TableCell, this delete button can own an action like:
btnDelete.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
param.getTableView().getSelectionModel().select(getIndex());
Person item = personTable.getSelectionModel().getSelectedItem();
if (item != null) {
// Logic of deleting current record here
System.out.println(item.getName());
}
}
});
The full sscce, Putting button into the table column more elegantly.

Tab between fields in TableViewer

What I'd like to do is be able to tab between elements in table.
I currently am creating my table like this.
this.tableViewer =
new TableViewer(parent , SWT.FULL_SELECTION);
tableViewer.setUseHashlookup(true);
table = tableViewer.getTable();
GridData gridData = new GridData(GridData.FILL_BOTH);
gridData.grabExcessVerticalSpace = true;
table.setLayoutData(gridData);
table.setLinesVisible(true);
table.setHeaderVisible(true);
...
/** Create the Cell Editor Array - will hold all columns **/
editors = new CellEditor[table.getColumnCount()];
/** Cell Editor Row 1 **/
/** Set the column properties **/
tableViewer.setColumnProperties(columnNames);
/** Assign the cell editors to the viewer **/
tableViewer.setCellEditors(editors);
/** Set the cell modifier for the viewer **/
tableViewer.setCellModifier(new MyCellModifier(this));
//Create the Table Viewer
/** Table Viewer Content and Label Provider **/
tableViewer.setContentProvider(new MyContentProvider(this));
tableViewer.setLabelProvider(new MyLabelProvider());
But I'm not sure how to set up the tabulation. Everything else works as far as editing columns, showing data, etc. Just stuck on this last part.
If I've missed obvious documentation or javadocs - my apologies and even pointing to those would be great.
Although the solution thehiatus posted is very low level and will probably work (I haven't tested it), JFace gives you a framework for this specific problem. See the org.eclipse.jface.viewers.TableViewerFocusCellManager along with org.eclipse.jface.viewers.CellNavigationStrategy classes to solve this problem.
I think by default tab does not jump from cell to cell in an swt table. Instead it traverses to the next control. So you'll also need to tell it not to traverse when tab is pressed
KeyListener keyListener = new KeyLisener()
{
public void keyPressed(KeyEvent evt)
{
if (evt.keyCode == SWT.TAB)
{
// There are numerous setSelection methods. I'll leave this to you.
tableViewer.getTable().setSelection(...)
}
}
public void keyReleased(KeyEvent evt){}
}
TraverseListener traverseListener = new TraverseListener()
{
public void keyTraversed(TraverseEvent evt)
{
if (evt.keyCode == SWT.TAB)
evt.doit = false;
}
}
tableViewer.getTable().addKeyListener(keyListener);
tableViewer.getTable().addTraverseListener(traverseListener);
Also, as derBiggi suggested, the listeners need to be added to the Table object, not the TableViewer.
I couldn't get the desired behavior with a TraverseListener (it would not traverse within the table), and I had trouble getting it to work with a FocusCellManager and CellNavigationStrategy. I finally found this solution that enables me to tab from column to column within a row and automatically activate the editor.
Viewer viewer = ...
TableViewerFocusCellManager focusCellManager =
new TableViewerFocusCellManager(
viewer,
new FocusCellHighlighter(viewer) {});
ColumnViewerEditorActivationStrategy editorActivationStrategy =
new ColumnViewerEditorActivationStrategy(viewer) {
#Override
protected boolean isEditorActivationEvent(
ColumnViewerEditorActivationEvent event) {
ViewerCell cell = (ViewerCell) event.getSource();
return cell.getColumnIndex() == 1 || cell.getColumnIndex() == 2;
}
};
TableViewerEditor.create(viewer, focusCellManager, editorActivationStrategy,
TableViewerEditor.TABBING_HORIZONTAL);
You need to add a KeyListener and set the selection or focus to the next cell:
tableViewer.getTable().addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent e) {
System.out.println("Key Pressed");
if (e.keycode == SWT.TAB)
{
System.out.println("Detected TAB key");
// set table viewer selection
}
}
public void keyReleased(KeyEvent e) {
System.out.println("Key Released");
}}
);
I also had to implement tabbing between elements in a table. We use Grid from Nebula as the table.
Firstly, I had to suppress tabbing the focus preventing it from moving out of the table.
and then I added a Key Listener which moves the focus/selection to the next cell:
I also made my own algorithm to move the selection one cell to the right and when at the end of the row, move it to the beginning of the next row. When end of table is reached, the selection moves back to the first cell in the table.
This solved the problem for me.

Categories