I have a written an AbstractTableModel for my JTable in my application. I see from tutorials that I can make the column to have a combobox by getting the column model and then the specific column for example:
TableColumn sportColumn = table.getColumnModel().getColumn(2);
...
JComboBox comboBox = new JComboBox();
comboBox.addItem("Snowboarding");
comboBox.addItem("Rowing");
comboBox.addItem("Chasing toddlers");
comboBox.addItem("Speed reading");
comboBox.addItem("Teaching high school");
comboBox.addItem("None");
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
But how do I do this for a specific cell or a row?
The JTable’s default implementation is column-based. The only way to change that behavior, if you want to have row or single-cell based choices, is to create a subclass of JTable and override the method public TableCellEditor getCellEditor(int row, int column). Inside your implementation you can use the provided row and column indices to make a different choice. The JTable will always use this method to get the cell editor.
you would need to use, override
prepareEditor
TableCellEditor(required to synchronize editor and renderer)
Related
Ok I have a JTable where I'm displaying a JList on every cell. To do this I had to implement TableCellRenderer and extend DefaultCellEditor. Here is where I return the actual JList to be rendered in GUI.
What I want to do is when user de-selects an item from a JList, I want to also de-select all items for all JLists for that table row starting at the clicked column.
My problem is that I can't figure out a way to de-select all items that come after the current clicked table column. All I can access is this DefaultListModel. I guess I need to access the actual JList in order to remove all selected items.
Below is method I'm using. Any ideas how to do this? Thanks.
public void deselectFromLocation(int row_, int column_){
DefaultTableModel dtm = (DefaultTableModel) table1.getModel();
int cols = dtm.getColumnCount();
for(int i=column_; i<cols;i++){
PCSListModel lm = (PCSListModel) dtm.getValueAt(row_, i);
//How can I access the actual JList object in order to remove all selected items?
//The PCSListMode is DefaultListModel and has no access to JList object. Thanks.
}
}
Presumably, your renderer and editor obtain the existing selection state from your TableModel, perhaps updating an instance of ListSelectionModel that is used as part of preparing the component for use. You can update the other model value(s) in your implementation of stopCellEditing(). Your TableModel will have to fire a suitable TableModelEvent for the other cells; do not do so for the value being edited. A related example is seen here.
Hello I have been working with javax swing and I came across a weird problem and got me questioning.
I can for example:
JTable table = new JTable();
// Indeed, 2 different objects:
// The TableModel (which, i think is supposed to contain rows and columns?
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
// And the column model, supposed to define the columns of a table?
TableColumnModel tcm = table.getColumnModel();
// I can add columns to my table in two different manners
dtm.addColumn("A Column");
// or
TableColumn column = new TableColumn();
column.setHeaderValue("Another column");
column.setWidth(120);
column.setMinWidth(120);
column.setMaxWidth(120);
tcm.addColumn(column);
// And notice that both commands will add a column in the table
// So our table model should now have 2 columns.
// But does it?
System.out.println(dtm.getColumnCount()); // outputs 1;
System.out.println(tcm.getColumnCount()); // outputs 2;
System.out.println(table.getColumnCount()); // outputs 2;
// The visual shows 2 columns, but the model has only 1.
From that I can tell JTable uses tableColumnModel and tableColumnModel gets all the columns added into tableModel, but, when I add a column to the TableModel it gets added to the table, but the tableModel remains outdated.
Now, the problem is: it's really interesting to add a column via columnModel because I can define the sizes, layout, editable options there, but in this way I cannot add any data to it from the tableModel, since that column doesn't appear on the tableModel.
Any thoughts on this?
The TableModel is used to contain data. The data is accessible in row/columns.
The TableColumnModel is used by JTable to control the View of the data. That is it controls the columns that are displayed in the JTable. You can also reorder the columns to display the data in a different order.
...but in this way I cannot add any data to it from the tableModel, since that column doesn't appear on the tableModel
That is correct. The purpose of the TableColumnModel is to simply customize the view, not manipulate data.
Maybe you have an application that contains many columns of data, but access to specific columns is limited by "security level". In this case the data is always stored in the TableModel, but you need to change the view to control which columns of data are visible. So you can remove/add columns from the TableColumnModel.
When you add a column to the TableModel, the JTable gets notified and it recreates all the TableColumns for you. This can be a good or bad thing because when the TableColumnModel is recreated you lose any custom renderers and editor that you may have added to a TableColumn. You can prevent this from happening buy using:
table.setAutoCreateColumnsFromModel( false );
Now the TableColumnModel will not be updated and it is your responsibility to manually create and add the TableColumn to the TableColumnModel.
But in general you:
add/change data through the TableModel.
change the view through the TableColumnModel.
I was re designing my codes with formerly using
JTable jtable = new JTable();
int selectedIndex = jtable.getSelectedColumn();
//implementations
Now, I need to use DefaultTableModel. Is there a method or implementation that is related to this method of JTable? Thanks!
A TableModel has nothing to do with the selected column of the JTable.
It doesn't matter what TableModel you use with the JTable, you still use
int selectedIndex = table.getSelectedColumn();
method to get the selected column.
Of course, there is no selected column when you first create the JTable. The user must select the column or you must set the selection on a particular cell of the table.
So you only use the getSelectedColumn() method in response to some kind of user event.
It means I need setData and setHeaders functions for JTable
Like Gilbert says, there is no method of the AbstractTableModel that will allow you to set the values of the headers after the JTable is up, since it is not a very common requirement. Still there is a simple work-around to that. I can not say if it is the best way to do it, but it will get you there...
columnNumber is the number of the column you want to change and newHeaderString is the new String you want to use.
jTable1.getColumnModel().getColumn(columnNumber).setHeaderValue(newHeaderString);
jScrollPane1.setViewportView(jTable1);
Since there is a getTableHeader() method, you could call it if you need to further modify your table header properties.
As for setting new data in any row, use jTable1.setValueAt(newObject, row, col);
if you use a TableModel, you can change the data contents, but not the column headers.
TableModel model = new DefaultTableModel(rowData, columnNames);
JTable table = new JTable(model)
rowData and columnNames have to be defined before you create the table.
The TableModel interface has a setValueAt method. The TableModel interface has no method for setting column names.
My aim is to provide an interface like a matrix, each cell in matrix will have 2 values and user will select best among the two.
So i thought of going for jTable and combo boxes, the problem is in my matrix the value of each cell in a column is different. But the following code that adds the combo box to whole column of the table and if i change the combo box value, it changes for the whole table. How to insert combo boxes into the table such that each one has different values
javax.swing.JComboBox k = new javax.swing.JComboBox();
k.addItem("1");
k.addItem("2");
k.addItem("3");
k.setEnabled(true);
k.setVisible(true);
this.jTable1.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(k));
I also tried with DefaultTableModel
code is
DefaultTableModel t =new javax.swing.table.DefaultTableModel();
t.setColumnCount(10);
t.setRowCount(10);
t.setValueAt(k, 0, 0);
jTable1.setModel(t);
but i get the output in the gui as
javax.swing.JComboBox[,0,0,0x0,invalid,layout=javax.swing.plaf.metal.MetalComboBoxUI$MetalComboBoxLayoutManager,alignmentX=0.0,alignmentY=0.0,border=,flags=16777544,maximumSize=,minimumSize=,preferredSize=,isEditable=false,lightWeightPopupEnabled=true,maximumRowCount=8,selectedItemReminder=1]
I tried typecasting "k" as JComboBox and JComponent in setValueAt method, which didn't work
Someone please help
Override the getCellEditor(....) method. For example: How to add unique JComboBoxes to a column in a JTable (Java)