Javafx How to make TableColumn cells selectable but not editable using Javafx - javafx-8

I am trying to create table using Javafx, i need for some columns cells to be selectable but not editable,
if i used : textColumn.setEditable(true);
but it will make it editable
if i used : textColumn.setEditable(false); it will be neither selectable nor editabe
how can i make column selectable but not editable ?
Here it is my code sample
TableColumn<Tuple, String> textColumn= new TableColumn<>();
textColumn.setText(column.getName());
textColumn.setMinWidth(column.getWidth());
textColumn.setEditable(true);

There is no default copying mechanism for TableView (columns could contain arbitraty value types that could require costom treatment when copying to the clipboard). You should implement the copying mechanism yourself, if needed.
Example:
tableView.setOnKeyReleased(evt -> {
if (evt.isControlDown() && evt.getCode() == KeyCode.C) {
List<TablePosition> selectedCells = table.getSelectionModel().getSelectedCells();
if (!selectedCells.isEmpty()) {
TablePosition selectedCell = selectedCells.get(0);
if (selectedCell.getTableColumn() == textColumn) {
String value = textColumn.getCellData(selectedCell.getRow());
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putString(value);
clipboard.setContent(content);
}
}
}
});
This needs to be done in addition to doing
tableView.getSelectionModel().setCellSelectionEnabled(true);
It assumes you're using to the standard cell type.

Related

How do I select entire column on selecting row cell in NatTable?

We have a NatTable with no header and I treated the 1st row as a Header,
- Register CELL_PAINTER to change the visualization to look this row similar to header.
Also registered the CustomCommandHandler which implements ILayerCommandHandler to prevent cell/row selection for the 1st row.
selectionLayer.registerCommandHandler(new CustomCommandHandler());
Cell selection is working fine for other cells.
public boolean doCommand(final ILayer layer, final ILayerCommand command)
{
if (command instanceof ViewportSelectRowCommand)
{
return ((ViewportSelectRowCommand) command).getRowPosition() <= 1;
}
else if (command instanceof SelectCellCommand)
{
return ((SelectCellCommand) command).getRowPosition() <= 1
}
return false;
}
Now how can I select the entire column on selecting cells on 1st row. So that it should not affect the cell selection for other row cells.
Clicking any cells on 1st row should select entire column.
Clicking any cells on other rows should select the same cell. (currently this is happening)
Although I am not quite sure what sense it makes to only have a body that is configured in a complicated way to look and behave like it has headers without really having headers (IMHO this does not make any sense), you need to register a custom handler that checks for the column position and transform the SelectCellCommand into a SelectColumnCommand.
this.selectionLayer.registerCommandHandler(new SelectCellCommandHandler(this.selectionLayer) {
#Override
public boolean doCommand(ILayer targetLayer, SelectCellCommand command) {
if (command.convertToTargetLayer(targetLayer)
&& command.getColumnPosition() == 0) {
return targetLayer.doCommand(
new SelectColumnCommand(
targetLayer,
command.getColumnPosition(),
command.getRowPosition(),
command.isShiftMask(),
command.isControlMask()));
}
return super.doCommand(targetLayer, command);
}
});
But I expect there will be more issues on the way as the immitated headers do not behave like real headers also in other scenarios. You could also try to override getRegionLabelsByXY(int, int) but I am not sure if this would work or cause more problems.

How to add a row style dynamically ? - Ag-grid

I want to change the style of a row dynamically in ag-grid. What I'm trying to achieve is to change the background color of my ag-grid row if the row has been edited by the user.
cellValueChanged(event) {
//Add it only if the old value has changed
if (event.oldValue != event.newValue) {
// This will replace with latest edited value if it has been edited already
this.edittedRows[event.rowIndex.toString()] = event.data;
}
}
I'm keeping track of the edited row by listening to cellValueChanged event. I need to change the row style here.
I've looked into ag-grid documentation and found how to add row styles, row classes and row class rules but I could't find a way to add a style to a row dynamically when the user has changed something on it.
By using redrawRows I was able to achieve this.
First I added rowClassRules for my grid options like below
private initGrid() {
this.gridOptions.rowClassRules = {
'modified' : this.isEditedRow()
};
}
private isEditedRow() {
return (params) => {
return params.data.edited;
}
}
modified is my css class which has all the styles for an edited row.
Then in my row data I'm adding a new property edited.
And changed the cellValueChanged as below,
cellValueChanged(event) {
//Add it only if the old value has changed
if (event.oldValue != event.newValue) {
// This will replace with latest edited value if it has been edited already
// Setting edited flag to change the background
event.data.edited = true;
this.edittedRows[event.rowIndex.toString()] = event.data;
let row = this.gridApi.getDisplayedRowAtIndex(event.rowIndex);
this.gridApi.redrawRows({ rowNodes: [row] });
}
}
Find the documentation for redrawRows here.
Add below line in your CellValueChanged Function:
gridOptions.rowStyle = {background: 'coral'};
cellValueChanged(event) {
//Add it only if the old value has changed
if (event.oldValue != event.newValue) {
// This will replace with latest edited value if it has been edited already
this.edittedRows[event.rowIndex.toString()] = event.data;
gridOptions.rowStyle = {background: 'coral'};
}
}
Plunker - https://plnkr.co/edit/i1K3YXpGGgNEOU2JjZCf?p=preview

How to remove ContentEdit.Static element in ContentTools

I created a new tool in ContentTools that adds a static table (I don't want you to edit).
But being a static element doesn't maintain focus and I can not remove it when I click remove button.
I can do so that the table is not editable but can be removed if you click on it?
That's how I created the element:
new ContentEdit.Static('div', {'data-ce-moveable': true}, '<table><thead><tr><th>Foo head</th></tr></thead><tbody><tr><td>Foo body</td></tr></tbody></table>')
Thank you!
Static elements can't be interacted with for the most part (other elements can be dragged around them but that's about it). ContentEdit/Tools does allow you to restrict the some behaviour for elements but not being able to modify the content of a text element isn't one right now (though I think this might be a worthy addition).
However whilst there's no set way to do this at the moment here's an approach you can use that should provide the behaviour you describe (do let me know how you get on):
ContentEdit.Root.get().bind('mount', function(element) {
// We only care about `TableCell` elements
if (element.type() != 'TableCell') {
return;
}
// We only want to make the element read-only if the parent table has
// the `data-read-only` attribute.
var table = element.closest(function(node) {
return node.type() == 'Table';
});
if (table.attr('data-read-only') !== undefined) {
// Disable text editing for the table cell
element.tableCellText()._onKeyDown = function(ev) {
ev.preventDefault();
}
}
// Disable dragging of the table rows
var tableRow = element.closest(function(node) {
return node.type() == 'TableRow';
});
tableRow.can('drag', false);
tableRow.can('drop', false);
});

Eclipse Scout Neon Focus inside rows after import data

I have some dependencies hierarchy on my form, so I implemented hierarchy check on server side of the scout. If one field is changed, it triggered check if other need to be changed as well. This is done with export/import form data.
MyFormData input = new MyFormData();
FormDataUtility.exportFormData(this, input);
input = BEANS.get(IMYService.class).validate(input, field);
FormDataUtility.importFormFieldData(this, input, false, null, null);
validate function change all other fields that need to be changed.
My problem is with editing cells in editable tables.
If I change value in cell, and this chain validation is triggered, after importing form data I lose focus in cell. So instead, tab will move me to another cell, tab trigger import and focus in cells are lost. And this is a really bad user experience.
How to fix this?
How to stay in focus (of next cell) after import has been called?
Marko
I am not sure, if this applies for you, but you can try the following:
I assume, that you do your export/validate/import logic in the execCompleteEdit(ITableRow row, IFormField editingField) of your column class. I suggest, that you calculate your next focusable cell by yourself and request its focus after importing the form data.
As an example, you can do this like that:
#Override
protected void execCompleteEdit(ITableRow row, IFormField editingField) {
super.execCompleteEdit(row, editingField);
// create form data object
// export form data
// call service and validate
// import form data
// request focus for next cell
focusNextAvailableCell(this, row);
}
with focusNextAvailableCell(this, row) as following:
private void focusNextAvailableCell(IColumn<?> col, ITableRow row) {
if (col == null || row == null) {
return;
}
IColumn<?> nextColumn = getColumnSet().getColumn(col.getColumnIndex()+1);
ITableRow nextRow = getTable().getRow(row.getRowIndex());
if (nextColumn == null) {
// no next column (last column lost focus)
// check if next row is available
nextRow = getTable().getRow(row.getRowIndex()+1);
// maybe select first cell again?
if (nextRow == null) {
nextColumn = getColumnSet().getColumn(0);
nextRow = getTable().getRow(0);
}
}
if (nextColumn != null && nextRow != null) {
getTable().requestFocusInCell(nextColumn, nextRow);
}
}
You should be aware, that you have to call this after every form data import in your execCompleteEdit method of your column. Also this is triggered not only when switching cells through pressing the tab key, but also when clicking with the mouse button.
Best regards!

Editable SWT table

How to edit SWT table Values without Using Mouse Listeners?
Do the TableEditor snippets in the below link help?
SWT Snippets
The first example in the TableEditor section uses a SelectionListener on the table (unlike the second example which uses a MouseDown event you mentioned you don't want)
You could perhaps make use of the TraverseListener or KeyListener too to help you achieve what you want.
final int EDITABLECOLUMN = 1;
tblProvisionInfo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
// Clean up any previous editor control
final TableEditor editor = new TableEditor(tblProvisionInfo);
// The editor must have the same size as the cell and must
// not be any smaller than 50 pixels.
editor.horizontalAlignment = SWT.LEFT;
editor.grabHorizontal = true;
editor.minimumWidth = 50;
Control oldEditor = editor.getEditor();
if (oldEditor != null)
oldEditor.dispose();
// Identify the selected row
TableItem item = (TableItem) e.item;
if (item == null)
return;
// The control that will be the editor must be a child of the
// Table
Text newEditor = new Text(tblProvisionInfo, SWT.NONE);
newEditor.setText(item.getText(EDITABLECOLUMN));
newEditor.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent me) {
Text text = (Text) editor.getEditor();
editor.getItem()
.setText(EDITABLECOLUMN, text.getText());
}
});
newEditor.selectAll();
newEditor.setFocus();
editor.setEditor(newEditor, item, EDITABLECOLUMN);
}
});
Here tblProvision is the name of your table. you can just now edit Your table by clicking on it. I have Declare EDITABLECOLUMN. this is the column that u want to edit.
If you can use JFace as well and not just pain SWT, have a look at the JFace Snippets, especially
Snippet036FocusBorderCellHighlighter - Demonstrates keyboard navigation by highlighting the currently selected cell with a focus border showing once more the flexibility of the new cell navigation support
Snippet034CellEditorPerRowNewAPI - Demonstrates different CellEditor-Types in one COLUMN with 3.3-API of JFace-Viewers
You can get or set the value of a item, for example:
Table table = new Table(parent, SWT.NONE);
TableItem item = new TableItem(table, SWT.NONE);
item.setText("My new Text");
I suggest you to us TableViewer, it is very powerful table which it you can use databinding very easy too.