I have a Nattable that can hide his row numbers. now when I hide the row numbers it does not show the dropdown in a cell.
I use this code to hide the row numbers:
if (showRowNumbers) {
compositeGridLayer = new GridLayer(bodyLayer, finalHeaderRow, rowHeaderLayer, cornerLayer);
} else {
compositeGridLayer = new CompositeLayer(1, 2);
compositeGridLayer.setChildLayer(GridRegion.COLUMN_HEADER, columnHeaderLayer, 0, 0);
compositeGridLayer.setChildLayer(GridRegion.BODY, bodyLayer, 0, 1);
compositeGridLayer.setChildLayer(GridRegion.COLUMN_HEADER, finalHeaderRow, 0, 0);
}
For adding the drop down to the cell we register it using:
ComboBoxCellEditor comboBoxCellEditor = new ComboBoxCellEditor(phases, -1);
comboBoxCellEditor.setMultiselect(false);
comboBoxCellEditor.setUseCheckbox(false);
comboBoxCellEditor.setFreeEdit(false);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new ComboBoxPainter(),
DisplayMode.NORMAL, "phaseDropDown");
comboBoxCellEditor.setIconImage(GUIHelper.getImage("plus"));
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, comboBoxCellEditor, DisplayMode.EDIT,
"phaseDropDown");
configRegistry.registerConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER, new DefaultDisplayConverter() {
#Override
public Object canonicalToDisplayValue(Object canonicalValue) {
return super.canonicalToDisplayValue(canonicalValue);
}
}, DisplayMode.NORMAL, "phaseDropDown");
How can I hide the row numbers without removing the drop down in the table?
Not sure what you mean with "hiding row numbers". Hiding would imply that you want to do this dynamically. And the approach you are showing would not be dynamically.
If you mean you want to provide two different compositions, one with row numbers and one without, the approach would be correct. You use a different composition. What I don't understand is why you set a column header twice with different layers.
The next question, what do you mean with "does not show the dropdown"? Don't you see the small triangle or does the combobox not open? I guess you mean the combobox does not open on click. I suppose the reason is that you forgot to register the necessary editing configurations on the newly created CompositeLayer. The GridLayer is created with the default configuration. On the CompositeLayer you do not set any configuration. So actually even print, export and alternate row colors will not work as they are simply not configured.
You need to register the DefaultEditConfiguration and the DefaultEditBindings on the CompositeLayer. This is explained in our NatTable Documentation|Editing. And I'm sure we also have some examples that cover editing in a non-grid composition.
Related
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.
This code below does not work.
Table table = new Table(2);
table.setBorder(Border.NO_BORDER);
I am new to iText 7 and all I wanted is to have my table borderless.
Like how to do it?
The table itself is by default not responsible for borders in iText7, the cells are. You need to set every cell to be borderless if you want a borderless table (or set the outer cells to have no border on the edge if you still want inside borders).
Cell cell = new Cell();
cell.add("contents go here");
cell.setBorder(Border.NO_BORDER);
table.addCell(cell);
You could write a method which runs though all children of a Table and sets NO_BORDER.
private static void RemoveBorder(Table table)
{
for (IElement iElement : table.getChildren()) {
((Cell)iElement).setBorder(Border.NO_BORDER);
}
}
This gives you the advantage that you can still use
table.add("whatever");
table.add("whatever");
RemoveBorder(table);
instead of changing it on all cells manual.
I'd like to define descriptions for Grid header cells, similarly to how AbstractComponent.setDescription(String description) works (i.e. tooltip shown on mouse hover). As the Grid doesn't support this in itself, I tried adding a Label component into the header cell, and then use setDescription() on the label. I can get the info tooltip working like this, but the downside is that clicking on the label component doesn't trigger sorting. If I want to sort the column, I need to click the header cell on the really narrow area that's left between the right edge of the label component and the column border, where the sorting indicator will be shown. If you look at the screenshot below, the highlighted area is the label component, and in order to trigger sorting, the user needs to click on the space on the right side of the component.
Is there a better way to apply descriptions to header cells than the one I described? And if not, is there a way to make the sorting work properly when the header cell contains a Component?
Based on the answer from kukis, I managed to come up with a simpler solution that doesn't require any JavaScript. Instead of adding a Label component into the header cell, I'm adding a div element manually with StaticCell.setHtml(), and setting the title attribute on it:
#Override
protected void init(VaadinRequest request) {
Grid grid = new Grid();
grid.addColumn("to");
grid.addColumn("the");
grid.addColumn("moon");
Grid.HeaderRow headerRow = grid.getDefaultHeaderRow();
headerRow.getCell("to").setHtml("<div title='Hello world'>to</div>");
headerRow.getCell("the").setHtml("<div title='Hello world 2'>the</div>");
headerRow.getCell("moon").setHtml("<div title='Hello world 3'>moon</div>");
grid.addRow("1","2","3");
grid.addRow("d","v","w");
grid.addRow("g","s","h");
setContent(new VerticalLayout(grid));
}
Feature added to Vaadin 8.4.0
Feature added to Grid in Vaadin 8.4.0.
Ticket:
https://github.com/vaadin/framework/pull/10489
Release notes:
https://vaadin.com/download/release/8.4/8.4.0/release-notes.html
Grid headers and footers now support tooltips.
Well, since Grid doesn't support it by itself you can always use JavaScript to achieve desired behaviour. SSCCE:
private final String SCRIPT;
{
StringBuilder b = new StringBuilder();
b.append("var grid = document.getElementById('mygrid');\n");
b.append("var child = grid.getElementsByClassName('v-grid-tablewrapper')[0];\n");
b.append("child = child.firstChild.firstChild.firstChild;\n");
b.append("child.childNodes[0].title='Hello world';\n");
b.append("child.childNodes[1].title='Hello world 2';\n");
b.append("child.childNodes[2].title='Hello world 3';\n");
SCRIPT = b.toString();
}
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
Grid grid = new Grid();
grid.addColumn("to");
grid.addColumn("the");
grid.addColumn("moon");
grid.addRow("1","2","3");
grid.addRow("d","v","w");
grid.addRow("g","s","h");
grid.setId("mygrid");
setContent(layout);
layout.addComponent(grid);
JavaScript.getCurrent().execute(SCRIPT);
}
Another possibility would be to develop your own Grid in GWT based on the Grid provided by Vaadin Team but it is a way higher cost approach.
Another solution would be to, as you have tried, put label in a column and propagate the label-clicked-event to the Grid.
I use my own utillity finction:
public static Grid setHeaderCellDescription(Grid grid, int rowIndex, String property, String description) {
Grid.HeaderCell cell;
String cellHeader = "<span title=\"%s\">%s</span>";
cell = grid.getHeaderRow(rowIndex).getCell(property);
cell.setHtml(String.format(cellHeader, description, cell.getText()));
return grid;
}
You may add some additional checks if need (existing of cell and row number).
Or other variant - instead setHtml use cetComponent.
Grid.HeaderCell cell = grid.getHeaderRow(rowIndex).getCell(property);
Label newLabel = new Label(cell.getText());
newLabel.setDescription(description);
cell.setComponent(newLabel);
Update for Vaadin 23: you can use your own Component as a column header with this method: com.vaadin.flow.component.grid.Grid.Column#setHeader(com.vaadin.flow.component.Component).
So you can use e.g. a Span with a title:
Span headerComponent = new Span();
headerComponent.setText("Your header text");
headerComponent.getElement().setProperty("title", "Your tooltip text");
column.setHeader(headerComponent);
I am new in Java programming. I need to get the indices of selected column and row. I am getting -1 as selected indices for both the column and row. I have searched for a solution but didn't find anything satisfactory.
My code is following:
private void deleteProductButtonActionPerformed(java.awt.event.ActionEvent evt) {
DefaultTableModel tableModel = (DefaultTableModel) this.productDisplaTable.getModel();
JTable table = new JTable(tableModel);
int selectedRowIndex = table.getSelectedRow();
int selectedColIndex = table.getSelectedColumn();
System.out.println(selectedRowIndex );
System.out.println(selectedColIndex);
}
You're checking if a row is selected before the JTable has been displayed before the user can even interact with it.
Instead why not have that code in an ActionListener or some other listener so that the user at least has a chance to select something? This suggests that you might have a misunderstanding on how event-driven programming works and need to study the concepts a little bit more.
What makes you think that creating a a new JTable would have any selected rows or columns
JTable table = new JTable(tableModel); //???
Try using a table that is actually visible to the user instead
In your code you create a new JTable but you don't add this component to any container. Thus it won't never be visible and no row nor column could ever be selected.
Now, while we can add components dynamically in Swing we tipically place all our components before the top-level container (window) is made visible. In this case you should place the table when you initialize your components (don't forget the scroll pane) and do whatever you need to do when the button is pressed.
On the other hand I'm not sure what are you trying to achieve. I mean you already have a table called productDisplaTable. If you want to print the selected row and column in that table then make this little change:
private void deleteProductButtonActionPerformed(java.awt.event.ActionEvent evt) {
//DefaultTableModel tableModel = (DefaultTableModel) this.productDisplaTable.getModel();
//JTable table = new JTable(tableModel);
int selectedRowIndex = this.productDisplaTable.getSelectedRow();
int selectedColIndex = this.productDisplaTable.getSelectedColumn();
System.out.println(selectedRowIndex );
System.out.println(selectedColIndex);
}
Thanks all for taking time to reply.
I got the answer I was looking from #dic19's comment.
Now I clearly see the mistake I was doing. This was due to my lack of knowledge in Java programming.
I have a JTable with multiple rows and every row is presented via Point on a scatter plot. What I have to do is when a given point is selected on the scatter plot I have to associate this selection with selecting of the corresponding row in the JTable.
I have an Integer that represents, which row I have to highlight.
What I tried is:
JTable table = new JTable();
...
...// a bit of code where I have populated the table
...
table.setRowSelectionInterval(index1,index2);
So the problem here is that this method selects all rows in the given range [index1,index2]. I want to select for example rows 1,15,28,188 etc.
How do you do that?
To select just one row, pass it as both the start and end index:
table.setRowSelectionInterval(18, 18);
Or, if you want to select multiple, non-contiguous indices:
ListSelectionModel model = table.getSelectionModel();
model.clearSelection();
model.addSelectionInterval(1, 1);
model.addSelectionInterval(18, 18);
model.addSelectionInterval(23, 23);
Alternately, you may find that implementing your own subclass of ListSelectionModel and using it to track selection on both the table and the scatterplot is a cleaner solution, rather than listening on the scatterplot and forcing the table to match.
It also works without using the ListSelectionModel:
table.clearSelection();
table.addRowSelectionInterval(1, 1);
table.addRowSelectionInterval(15, 15);
table.addRowSelectionInterval(28, 28);
...
Just don't call the setRowSelectionInterval, as it always clears the current selection before.
There is no way to set a random selection with a one method call, you need more than one to perform this kind of selection
table.setRowSelectionInterval(1, 1);
table.addRowSelectionInterval(15, 15);
table.setRowSelectionInterval(28, 28);
table.addRowSelectionInterval(188 , 188 );
And So On....
Here is a generic method to accomplish this:
public static void setSelectedRows(JTable table, int[] rows)
{
ListSelectionModel model = table.getSelectionModel();
model.clearSelection();
for (int row : rows)
{
model.addSelectionInterval(row, row);
}
}