I have a javafx tableview and I'm trying to write a keylistener so the user can quickly select rows and edit their contents.
So far I can focus the table with a key press and select/focus a row with a digit key press. However I then want the user to be able to tab through the row to select the cell he wants to edit.
My problem is whenever I press the tab when a row is selected, it always starts selecting cells from the first row.
Here is the code from my key listener:
....
else if(code.isDigitKey()){
TableView tv = scene.getSelectedTable();
if(tv != null){
tv.getSelectionModel().select(code.ordinal()-24);
tv.getFocusModel().focus(code.ordinal()-24);
//Something required here to set tab position to start of this row
}else{
System.out.println("null");
}
}
Is there a way to set a tab starting position?
SOLUTION:
Tab simply goes to the next JavaFX control element that it knows about. The TableView had focus so when I pressed tab it went to the next control element which just so happened to be inside the table. Tab does not traverse through table cells.
So the work around I came to was to call the edit method on the first cell in the selected row:
....
else if(code.isDigitKey()){
TableView tv = scene.getSelectedTable();
if(tv != null){
tv.getSelectionModel().select(code.ordinal()-24);
tv.getFocusModel().focus(code.ordinal()-24);
tv.edit(code.ordinal()-24, ((TableColumn)(tv.getColumns().get(0))));
}else{
System.out.println("null");
}
}
Then in my CellFactory for that column (It happens to be a Spinner), I override startEdit:
#Override
public void startEdit(){
this.spinner.requestFocus();
}
Note the column and table must be editable.
Related
I have a jbutton which loads data from a DB, and then populates a jtable (using a DefaultTableModel)
Then, I have this event on the row selection of the table:
jTableDettagliFattura.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent event) {
int selected= jTableDettagliFattura.getSelectedRow();
String id = jTableDettagliFattura.getModel().getValueAt(selected, 0).toString();
System.out.println(id);
}
});
When I load the table for the first time (using the button), everything works fine. But if I select one of the table rows, and then reload the table with the button, I get the "java.lang.ArrayIndexOutOfBoundsException: -1", at the command "jTableDettagliFattura.setModel(model);" (that was perfectly working the first time).
What could be the problem?
Is the selection event somehow "ruining" my model?
But if I select one of the table rows, and then reload the table with the button, I get the "java.lang.ArrayIndexOutOfBoundsException: -1"
There is no row selected when the model is reloaded. The listener probably fires an event to indicate the selection was removed.
Try:
int selected = jTableDettagliFattura.getSelectedRow();
if (selected == -1) return;
The main point is don't assume a row is selected. Validate the index before doing your processing.
I am trying to get the sum of column 4 on typing/editing the value on column 4. Immediately i change the figure i.e as i type on any row of column 4 it should change my sum which i set on a jTextField.
I have tried TableModelListener and ListSelectionListener but it has not worked efficiently because i have to click on the row for it to get the summary.
jTable1.getModel().addTableModelListener(new TableModelListener(){
public void tableChanged(TableModelEvent evt){
float sum = 0;
int[] rows = jTable1.getSelectedRows();
for(int i=0;i<jTable1.getRowCount();i++){
try{
sum = sum +
Float.parseFloat(jTable1.getValueAt(rows[i],4).toString());
}
catch(Exception e){
continue;
}
}
jTextField15.setText(Float.toString(sum));
getsummaries();
}
});
Immediately i change the value on Column 4 i would like it ot autosum on jTextField15.
it has not worked efficiently because i have to click on the row for it to get the summary.
The model is only updated when the cell loses focus because that is when the value you are typing is saved to the model. This is because you could start typing numbers and then use the "escape" key to cancel the editing.
If you really want to update the total as the user types into the editor, then instead of using a TableModelListener, you will need to add a DocumentListener to the text field used by the editor:
DefaultCellEditor editor = (DefaultCellEditor)table.getDefaultEditor(Integer.class);
JTextField textField = (JTextField)editor.getComponent();
textField.getDocument().addDocumentListener(...);
See the section from the Swing tutorial on Listening For Changes on a Document for more information and examples.
Of course if you do this, you will also need to handle the case when the editor is cancelled. So you will also need to add a PropertyChangeListener to the JTable and listen for tableCellEditor property change.
I have not yet gotten a solution to this yet. On typing on JTable it's difficult to record the sum. A workaround would be to create a button and it computes the total on the jTextField.
I tried using the same example from TreeCursor documentation:
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/plain/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet360.java
On whichever cell I press enter (SWT.CR) for the first time, say I press on the cell 'root11', after this any cell that I click, 'root11' appears in it.
My requirement is to select the text from a cell to copy. I do not want to edit. So every time i click on a cell to copy its text, the text from the cell that was selected first time appears.
Any pointers on what could be causing this?
Thanks in advance!
When ENTER is pressed on an item, the widgetDefaultSelected method is called. There, the ControlEditor sets a Text with the selectedTreeItem text as its editor: editor.setEditor(text);.
This Text is then only disposed when ENTER or ESC is pressed on it, and in no other occasions. This means that the Text will still be visible with its original content even when you select another item.
To change this behavior you could modify the widgetSelected method to, for example, dispose the Text so it would be no longer visible or update its text with the current selected item.
To remove the Text:
#Override
public void widgetSelected(SelectionEvent e) {
// get the current editor
Text text = (Text) editor.getEditor();
if (text != null && !text.isDisposed()) {
// remove the editor
text.dispose();
}
tree.setSelection(new TreeItem[] { cursor.getRow() });
}
To update the Text content:
#Override
public void widgetSelected(SelectionEvent e) {
// get the current editor
Text text = (Text) editor.getEditor();
if (text != null && !text.isDisposed()) {
// update the text in the editor
TreeItem row = cursor.getRow();
int column = cursor.getColumn();
text.setText(row.getText(column));
}
tree.setSelection(new TreeItem[] { cursor.getRow() });
}
Can somebody give me a hint because I am stucked. And I haven't found the appropriate solution for my problem.
I have a Grid, with 1-3 rows. I click on the row -> the row is selected.
I want to have this row to be deselected after I click somewhere else (outside this row) but inside the grid.
Here is simple screenshot, to help you visialize it better.
What kind of listener should I use for this case? I have tried ItemClickListener -> haven't helped.
Try putting your grid in a separate layout and add LayoutClickListener to it:
gridLayout.addLayoutClickListener(new LayoutEvents.LayoutClickListener() {
#Override
public void layoutClick(LayoutEvents.LayoutClickEvent event) {
if(grid.getSelectedRow() != null) {
grid.deselectAll();
}
}
});
gridLayout.asSingleSelect().addSelectionListener(e->{
if(e.getFirstSelectedItem().isPresent()) {
system.out.println("selected");
}else {
// when deselected make some actions here
system.out.println("deSelected");
}
});
Selection:
If you click on the same row of data for the first time , it will print selected ,since there are values present on what you clicked .
Deselection:
Now try to click on the same selected row for the second time , now it will go to deselection mode. since there are no values when you deselected.Now no need to click anywhere on the grid ,you can click on the same row of data for two times for the selection and deselection.
I am using Custom Data Grid from GWT showcase example ..
http://gwt.googleusercontent.com/samples/Showcase/Showcase.html#!CwCustomDataGrid
Every thing is working fine ..I have sub Rows inside my rows in the cell table ..
I have anchor cell.. which are in the main row and in the sub row ..
the ClickHandler for the main row is working but not in the sub row ..
this is my code for that cell
// ViewDetail.
td = row.startTD();
td.className(cellStyles);
td.style().trustedColor("blue");
td.style().cursor(Cursor.POINTER);
if (isNetworkRow) {
//td.text("subRowsAnchor");
} else {
}
renderCell(td, createContext(19), viewDetailsColumn, rowValue);
I am rendering the cell in both cases , either its a row or sub row
so i can see the anchor and its clickHandler also works ..
Is there any way i can differentiate that which anchor is been clicked ,, main rows or sub row's.
I just tried to make a small work around . i.e changing the name of the anchor text if its a sub row .. as u can c in my code ..td.text..
but then get the error on renderCell...
Attributes cannot be added after appending HTML or adding a child element.
Any idea , what could be solution...
thanks
To distinguish between which row has been clicked (according to the showcase sample, but should be the same in general), simply rely on which row has been selected (provided that you haven't overridden/disabled the selection handling).
Set up a FieldUpdater to the column (that renders itself using your anchor cell) and check for the subrow selection using getKeyboardSelectedSubRow(). Something like:
yourColumn.setFieldUpdater(new FieldUpdater<T, String>() {
public void update(int index, T object, String value) {
if (yourGrid.getKeyboardSelectedRow() != -1 ) {
if (yourGrid.getKeyboardSelectedSubRow() > 0) {
// Subrow selected.
} else {
// Main row selected.
}
}
}
});