Editing a specific cell on a TableView - java

I want to edit a specific cell in a TableView using JavaFX (for example, row 3, column 5).
I tried this code but it doesn't work.
//Define the string
String s = "myString";
//Define the number
int value = 5;
//Synthesize the item = row
Item item = new Item(s, value);
//Set the i-th item
table.getItems().set(i, item);

Is this what you need? In your example you do not mention any position but the question title does.
table.getTableView().getItems().get(
t.getTablePosition().getRow())
).setLastName(t.getNewValue()
You can find here a complete example.

Just edit the list you are providing to the table to what you want and just call
yourtable.refresh();

Related

JTable JComboBox is defaulting to display 1st item when list is expanded

I have been trying to determine why my JComboBox is displaying the 1st item in the list through numerous Google searches, but I'm struggling to find relevant help. It could be that I don't know the correct terminology (hence the overly specific title of this question) and thus not finding the information that would explain my issue. I checked out the JComboBox API, and few of the listeners and models that it uses, but they did not seem likely candidates.
The JComboBox in question is inside a JTable, so I am not aware if that changes the default behaviour of it. The code I am using is as below:
//row and col are final due to usage inside anonymous inner class
public TableCellEditor getCellEditor(final int row, final int col)
{
String[] listItems = new String[arrayList.getSize()];
int i = -1;
for(String s : arrayList)
{
i++;
listItems[i] = s;
}
JComboBox<String> box = new JComboBox<>(listItems);
box.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if(e.getStateChange() == ItemEvent.SELECTED)
{
if(e.getItem().equals("Add/Edit Projectile"))
{
//Where Editor is a JFrame that will be opened
new Editor();
}
}
}
});
DefaultCellEditor list = new DefaultCellEditor(box);
}
Please note that the Arraylist in my program does not contain Strings, but instead a more complicated set of custom objects that I believe would distract from the main issue.
I haven't included a Renderer for JComboBox's in the JTable as I was happy enough with the way it appeared, and figured that my problem was more going to be something I have neglected to implement in the model/implemented wrong.
I've also provided a couple of screenshots to better portray my problem. The first image is when the JComboBox is not selected, and simply displaying the currently selected item.
The second image is when I have just clicked the JComboBox to bring up the list. As depicted, it will immediately bring up that first item, no matter what it is.
If anyone has any suggestions as to where to look/solutions, I would be very grateful.
EDIT
My particular table has two columns, where the left column is a variable name, and the right column is the value associated with the variable. The tables role is to display the properties of a selected object, where each value for different variable for different objects are likely to not be the same.
In this particular case, the cell displays a JComboBox with all the available Projectiles in the game we are making. Each enemy has a different type of projectile it defaults to. So when I click on a different enemy in our game area, the table will display all of their current properties (defaults if they have not been changed).
Enemies do have a getter for the Projectile, so I could determine what the currently selected enemy is, get it's projectile, do a toString() to find how it is to be represented in the list, and do a setValueAt().
The only problem is at the moment it is always selecting the first item in the list when the list is expanded.
Unless the values for the JComboBox are dynamically generated for each row, you should be able to just prepare the CellEditor ahead of time, for example...
JComboBox cb = new JComboBox(new String[]{"1", "2", "3", "4"});
DefaultCellEditor editor = new DefaultCellEditor(cb);
JTable table = new JTable(new DefaultTableModel(5, 1));
table.getColumnModel().getColumn(0).setCellEditor(editor);
This will set the selected value of the editor to the value of the cell when the editing process starts
Updated
In the case where the combobox values are dynamically generate per row, you could do something more like...
JComboBox cb = new JComboBox();
DefaultCellEditor editor = new DefaultCellEditor(cb) {
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
JComboBox editor = (JComboBox) getComponent();
String[] listItems = new String[arrayList.getSize()];
int i = -1;
for (String s : arrayList) {
i++;
listItems[i] = s;
}
DefaultComboBoxModel model = new DefaultComboBoxModel(listItems);
editor.setModel(model);
editor.setSelectedItem(value);
return editor;
}
};
JTable table = new JTable(new DefaultTableModel(5, 1));
table.getColumnModel().getColumn(0).setCellEditor(editor);
Note the use of editor.setSelectedItem(value);, this will set the selected value to the cells current value...
You could also re-use the model, clearing it each time and re-filling it with new values. You might find this more efficient if you have a large number of rows as you won't need to constantly create a new model each time a cell is edited
Thow this is an oldie...
Your problem is most likely you don't implement "equals" in the class used in the combo.
The Combo needs to select the current item when it is being prepared and does so by iterating through the elements of the model and selects the first one that is equal to the value in the cell. If none is encountered then it leaves the combo as is (either first element or the last used element in a previous cell edit)
This is how you should default to the previously selected element:
//...
Object selectedItem = box.getSelectedItem();
//Add some elements to the jComboBox
box.setSelectedItem(selectedItem);

Java - Coloring Row in JTable depending on value in the tablemodel

I'm trying to color the text of every row in a table depending on one of the columns in the table. I'm having trouble grasping the concept of renderers, and I've tried out several different renderers but don't seem to understand what they do.
I am trying to load the top ten racers from a certain API given to us by our lecturer into the table model, but colouring each row based on the gender of the racer (which is returned by the getCategory() method of a Finisher/Racer object).
FYI, DataTable is an object written by our lecturer. It's basically a 2D array object.
public void showRacers(DefaultTableModel tblModel,
#SuppressWarnings("rawtypes") JList listOfRaces) {
// Clear the model of any previous searches
tblModel.setRowCount(0);
// Initialize an object to the selected city
CityNameAndKey city = (CityNameAndKey) listOfRaces.getSelectedValue();
// Get the runners for this city
DataTable runners = this.getRunners(city);
// Set the column headers
this.setColumnHeaders(tblModel);
// Make an array list of object Finisher
ArrayList<Finisher> finisherList = new ArrayList<Finisher>();
// Make an array that holds the data of each finisher
Object[] finisherData = new Object[6];
// Make a finisher object
Finisher f;
for (int r = 0; r < 10; r++) {
// Assign the data to the finisher object
finisherList.add(f = new Finisher(runners.getCell(r, 0), runners
.getCell(r, 1), runners.getCell(r, 2), runners
.getCell(r, 3), runners.getCell(r, 4), runners
.getCell(r, 5)));
// Add the data into the array
finisherData[0] = f.getPosition();
finisherData[1] = f.getBibNo();
finisherData[2] = f.getTime();
finisherData[3] = f.getGender();
finisherData[4] = f.getCategory();
finisherData[5] = f.getRuns();
// Put it into the table model
tblModel.addRow(finisherData);
}
}
I would greatly appreciate an explanation, rather than just the answer to my question. Guidance to the answer would be great, and some code would be extremely helpful, but please no: "You should have written this: ten lines of code I don't get
Thank you very much! :)
Using a TableCellRenderer will only allow you to color one column. You would have to have one for each column. A much easier approach is to override prepareRenderer(...) in JTable to color an entire row.
See trashgod's answer here or camickr's answer here

How to order Vaadin Table Rows?

I have a table phases that has values that reference to a repository table. In the repository each value has an order number.
Normally in SQL, I would join them and then order by the order column. But if I want to do that in Vaadin I have to use the FreeFormQuery to make this join.
The Problem is that I want to allow users to change values in the table phases. So I would need to implement the FreeFormQueryDelegate. Is there a way to make this work by using a standard TableQuery instead of a FreeFormQuery ?
Maybe manually move the rows in a table ?
Vaadin offers some sort options for tables.
You can sort one specific propertyId or you can sort a set of properties.
// sort one container property Id
table.setSortContainerPropertyId(propertyId);
table.setSortAscending(ascending);
table.sort();
// sort several property Ids
table.sort(propertyId[], ascending[]);
NOTE: the code above is no proper code, it rather shows the method bodies.
I used follow code to rearrange the vaadin table rows, when "Move Up" button click, while selecting a table row.
Object selectedItemId = fieldTable.getValue();
if(selectedItemId != null){
List<Object> items = new ArrayList<>(fieldTable.getItemIds());
int index = items.indexOf(selectedItemId);
if(index < 1){
LOGGER.info("Selected Filed is at the top, cannot move up further");
return;
}
//Rearrange itemids for new order
Object upperRow= items.set(index - 1, selectedItemId);
items.set(index, upperRow);
items.forEach(itemId -> {
//Gets the properties of old table item
Item item = fieldTable.getItem(itemId);
String name = (String) item.getItemProperty(Constants.PROPERTYID_FIELD_NAME).getValue();
Button toggleBtn = (Button) item.getItemProperty(Constants.PROPERTYID_SORT_BUTTON).getValue();
//Remove the old table item
fieldTable.removeItem(itemId);
//Insert old table item into the new position index
Item newItem = fieldTable.addItem(itemId);
newItem.getItemProperty(Constants.PROPERTYID_FIELD_NAME).setValue(name);
newItem.getItemProperty(Constants.PROPERTYID_SORT_BUTTON).setValue(toggleBtn);
int position = items.indexOf(itemId);
if(position == index - 1) {
fieldTable.select(itemId);
}
});
}

Tooltips on filtered rows in a table

I have a JTable and any single row in it has associated a different tooltip when mouse hover a row. I have created a "filter" for this table; when it is applied it perfectly hides the rows need to be hidden but when I hover the mouse on the filtered rows, looks like the tooltip is referring to the row that occupied the same row position of the new current row.
For example:
Table
ROW 1 -> tooltip 1
ROW 2 -> tooltip 2
Apply Filter to Table:
ROW 2 -> tooltip 1
So ROW 2 is displaying the tooltip 1 instead of 2.
TableRowSorter<TableModel> sorter = (TableRowSorter<TableModel>) table.getRowSorter();
sorter.setRowFilter(RowFilter.regexFilter(text));
My table that extends JTable has:
#Override
public String getToolTipText(MouseEvent e) {
final int rowIndex = rowAtPoint(e.getPoint());
TableModel model = getModel();
// take the value from the first column of the selected row
String tip = (String) getModel().getValueAt(rowIndex, 0));
return tip;
}
So it looks like using the model is not (quite obvious) updated respect to the filter. I tried using TableModel model = getRowSorter().getModel() too but without any luck.
How can I point to a correct "filtered model" to retrieve the correct row position?
UPDATE:
I have replaced the "rowIndex" code like this:
final int rowIndex = convertRowIndexToModel(rowAtPoint(e.getPoint()));
It partially solves the problem, but when some rows are added dynamically to the table with the filter applied and I hover new rows I get the exception (with relative API description):
IndexOutOfBoundsException -> if sorting is enabled and passed an index outside the range of the JTable as determined by the method getRowCount
You need to convert the views row index to the model's row index
Have a look at JTable#convertRowIndexToModel
You should not override that JTable#getToolTipText method. Just set the tooltip-text on the component returned by your renderer. The JTable will pick it up automatically. You can see this in the implementation of the getTooltipText method of the JTable

Gwt, CellTable, how can I know which column user clicks for sorting?

Writing GWT application.
I have CellTable and a code that i'v got from google-example code-site.
I need to implement server-side sorting by clicking on table's columns.
My code for that is:
AsyncDataProvider<MYOBJECT> dataProvider = new AsyncDataProvider<MYOBJECT>() {
#Override
protected void onRangeChanged(HasData<MYOBJECT> display) {
final Range range = display.getVisibleRange();
...
int sortingColumnIndex = 0;
boolean isAscending = sortList.get(sortingColumnIndex).isAscending();
// some server-side call here
}
So, how can I know which column an user clicks on ? I.e. Real index of column of header of column or anything for identifying that column user clicked?
I have only HasData display as an event, but it seems is not enough to determinate the column.
Sorting a CellTable server-side
The magic number 0, is the index of the sort column in the sort list, and not the column index from the cell table.
So sortList.get(0).getColumn() gets you the column that the user clicked on. You have to worry about the other columns in the sortList only if you plan to implement sorting on multiple columns.
ColumnSortList sortList = dataTable.getColumnSortList();
Column<?, ?> column = sortList.get(0).getColumn();
Above will give you the required column.

Categories

Resources