I have designed one GUI in which I have used one JTable from which I have to make 2 columns invisible . How should I do that ?
Remove the TableColumn from the TableColumnModel.
TableColumnModel tcm = table.getColumnModel();
tcm.removeColumn( tcm.getColumn(...) );
If you need access to the data then you use table.getModel().getValueAt(...).
For a more complex solution that allows the user to hide/show columns as they wish check out the Table Column Manager.
First remove the column from the view
table.removeColumn(table.getColumnModel().getColumn(4));
Then retrieve the data from the model.
table.getModel().getValueAt(table.getSelectedRow(),4);
One thing to note is that when retrieving the data, it must be retrieve from model not from the table.
I tried 2 possible solutions that both work, but got some issue with the 1st solution.
table.removeColumn(table.getColumnModel().getColumn(4));
or
table.getColumnModel().getColumn(4).setMinWidth(0);
table.getColumnModel().getColumn(4).setMaxWidth(0);
table.getColumnModel().getColumn(4).setWidth(0);
In my recent case, I preferred the 2nd solution because I added a TableRowSorter.
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
When using table.removeColumn(table.getColumnModel().getColumn(4)), it will physically remove the column from the view/table so you cannot use table.getValueAt(row, 4) - it returns ArrayIndexOutOfBounds. The only way to get the value of the removed column is by calling table.getModel().getValueAt(table.getSelectedRow(),4). Since TableRowSorter sorts only what's on the table but not the data in the DefaultTableModel object, the problem is when you get the value after sorting the records - it will retrieve the data from DefaultModelObject, which is not sorted.
So I used the 2nd solution then used table.getValueAt(table.getSelectedRow(),4);
The only issue I see with the 2nd approach was mentioned by #camickr: "When you set the width to 0, try tabbing, when you hit the hidden column focus disappears until you tab again. This will confuse users."
i had the same problem and because of i am using TableColumnModel removColumn(); does'not help me so i used this
table.getColumnModel().getColumn(0).setWidth(0);
table.getColumnModel().getColumn(0).setMinWidth(0);
table.getColumnModel().getColumn(0).setMaxWidth(0);
and worked fine for me it hide a column 0 and i still able to get value from it
Set the min, max and "normal" width to 0:
jTable.getColumn("ABC").setMinWidth(0); // Must be set before maxWidth!!
jTable.getColumn("ABC").setMaxWidth(0);
jTable.getColumn("ABC").setWidth(0);
Note: Since you can't set a maxWidth < minWidth, you need to change minWidth, first (javadoc). Same is true for width.
The second approach is to extend TableColumnModel and override all the methods to create the illusion (for the JTable) that your model doesn't have those two columns.
So when you hide a column, you must return one less when the table asks for the number of columns and when it asks for the column X, you may have to add +1 to the column index (depending on whether it is to the left or right of the hidden column), etc.
Let your new table model forward all method calls (with the corrected indexes, etc) to the actual column model and use the new table model in the JTable.
If you remove the column from the JTable the column is still present in the TableModel.
For example to remove the first ID column:
TableColumnModel tcm = table.getColumnModel();
tcm.removeColumn(tcm.getColumn(0));
If you want to access the value of the removed column, you have to access it through the getValueAt function of the TableModel, not the JTable. But you have to convert to rowIndex back to rowIndex in the model.
For example if you want to access the first column of the selected row:
int modelRow = table.convertRowIndexToModel(table.getSelectedRow());
int value = (Integer)table.getModel().getValueAt(modelRow,0);
I have tried them all: they don't help. The BEST way ever is to make a new table model without the column you want to delete. This is how you do it:
table = (DefaultTableModel) <table name>.getModel();
DefaultTableModel table1 = new DefaultTableModel();
Vector v = table.getDataVector();
Vector v1 = newvector(v,<column index you want to delete>);
Vector newvector(Vector v,int j){
Vector v1= new Vector();
try{
Vector v2;
Object[] o = v.toArray();
int i =0;
while(i<o.length){
v2 = (Vector) o[i];
v2.remove(j);
v1.add(v2);
i++;
}
}
catch(Exception e){
JOptionPane.showMessageDialog(null,"Error in newvector \n"+e);
}
return v1;
}
Vector getColumnIdentifiers(int i) {
Vector columnIdentifiers = new Vector();
int j=0;
while(j<i){
columnIdentifiers.add(("c"+(j+1)));
j++;
}
return columnIdentifiers;
}
table1.setDataVector(v1,getColumnIdentifiers((<column count>-1)));
<table name>.setModel(table1);
You could create a subclass of the model, and override TableModel.getColumnCount as follows:
int getColumnCount() {
return super.getColumnCount()-2;
}
The last two columns would then not be displayed in the JTable.
Related
I am using the SWT library in my software, not in Eclipse. I need to swap two rows at runtime in a table SWT that I populated via an array. I used the following method:
I take the array
swap two elements(with Collection.swap)
I empty the table
I reinsert the elements from the array
I'd like to know if there is a better method, do I have to reinsert all the elements in the table? because when there are so many rows the visual effect is evident and it seems a waste since I would like to swap only two rows at a time.
Here is the code:
if(table.getSelectionIndices()[0]<table.getItemCount()&&table.getSelectionIndices()[0]>0) {
Collections.swap(pluginsTmp, table.getSelectionIndices()[0], table.getSelectionIndices()[0]-1);
int nextSelectionIndex=table.getSelectionIndices()[0]-1;
updateTable();
table.setSelection(nextSelectionIndex);
}
In this case it serves to "go up" the selected item, exchanging it with those above
public void updateTable() {
table.removeAll();
for(int a=0;a<pluginsTmp.size();a++) {
Plugin p = pluginsTmp.get(a);
TableItem item = new TableItem(table, SWT.NONE);
item.setText(0,p.getClass().getName().toString());
item.setText(1,p.getVersionMajor()+"."+p.getVersionMinor()+"."+p.getVersionBuild());
item.setText(2,p.getAuthor());
item.setText(3,(p.isEnabled())?"Enabled":"Disabled");
item.setData("className",p.getClass().getName().toString());
item.setData("status",(p.isEnabled())?"1":"0");
}
}
Thank you all
Just call setText and setData on the two table items that have changed.
You can get an existing TableItem from the table using
TableItem item = table.getItem(index);
where index is the row in the table.
I would like to populate more than one JTable using the code below. The amount of columns in the 2D array can be variable. So I would like to use a method that accepts an integer to indicate the number of columns to add in the following line:
tableModel.addRow(new Object[]{arr[i][0], arr[i][1]});
I'm trying to figure a way to add (for each new JTable) a specified number of arr[i][0], arri, to a table determined by a method argument.
DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
for (int i = 0; i < arr.length; i++) {
tableModel.addRow(new Object[]{arr[i][0], arr[i][1]});
}
Is this possible?
This is linked in a way to my previous question: How to populate a JComboBox using a method
In order for data to be displayed in a JTable, you must have a column defined in the TableColumnModel of the table.
So you need to define your DefaultTableModel with the maximum number of columns that is possible.
Then you just use the addRow(...) method. The DefaultTableModel will automatically pad the row with null values up to the maximum number of columns.
i was setting the number of rows of my Table in java using properties of the table but how can i add new row inside the code because i don't know the number of inputs that should be entered?
but how can i add new row inside the code
This will depend on the implementation of the TableModel, for example, the DefaultTableModel provides two addRow methods.
The TableModel itself doesn't provide this functionality directly and is dependent on the physical implementation to provide this functionality if and when required.
See How to Use Tables for more details
first, i set the number of rows equal "0" in the properties of the table
second, write this code in the for loop with your condition
ArrayList arr = new ArrayList();
for (int i = 0; i < shipmain.files.length; i++) {
arr.add(shipmain.files[i]);
arr.add(shipmain.fabricName[i]);
arr.add(shipmain.color[i]);
DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
model.addRow(arr.toArray());
jTable1.setModel(model);
arr.remove(shipmain.files[i]);
arr.remove(shipmain.fabricName[i]);
arr.remove(shipmain.color[i]);
}
AddRow() function must take an object and ArrayList provided that
I tried to create a jTable by adding a column of type boolean, to tick the wanted rows. And get them into another similar jTable.
I used jTable1.getModel().setValueAt(int, int, int); but can't put selected String values to the value parameter.
Can someone help me please?
I used jTable1.getModel().setValueAt(int, int, int); but can't put selected String values to the value parameter.
Sure you can, the signature is setValueAt(Object, int, int). The first parameter is Object, not "int" so you can put any Object into a TableModel.
If you are talking about adding new rows of data to the second table then you need to use the addRow(...) method of the DefaultTableModelof your table. That is, the DefaultTableModel will initially contain no data so you can't just use the setValueAt(...) method. Instead you need to add a new row of data for every row that is selected in the first table.
If you need more help than post your SSCCE that demonstrates the problem.
JTable is very flexible and could add and delete any row you desire.
The number of columns that constitute a row may vary from table to another so JTable has a model object through which you can manipulate the rows of the table.
The JTable will have a DefaultTableModel. You can add rows to the model with your data.
If you get the column values of a selected row of a JTable for example:
String obj1 for row1, String obj2 for row2, String obj3 for row3, ...ect
OR IF YOU NEED BOOLEAN :
Boolean obj1 for row1, Boolean obj2 for row2, Boolean obj3 for row3, ...ect
Then you can make the following:
Object[] row = { obj1 , obj2 , obj3 };
You get the object model of the destination table as follows:
DefaultTableModel model = ( DefaultTableModel ) jTable1.getModel();
Then add the manually created row to it:
model.addRow( row );
And that's it!
JAVA
NETBEANS
// resultsTable, myModel
JTable resultsTable;
DefaultTableModel myModel; //javax.swing.table.DefaultTableModel
myModel = (DefaultTableModel) resultsTable.getModel();
// event of clicking on item of table
String value = (String) myModel.getValueAt(resultsTable.getSelectedRow(), columnIndex)
I use JTable and DefaultTableModel to view a table of various info
and I want to get a value of a certain column of the selected index of the table.
The code I wrote above works fine except when:
I use the sort of the GUI (click on the field name I want to sort on the table)
The table is properly sorted but after that when I select a row, it gets
the value of the row that was there before the sort.
This means that after sorting (using the JTable's GUI)
the 'myModel' and 'resultsTable' objects have different row indexes.
How do I synchronize those two?
You need to use the 'convertXXX' methods on the JTable see the JavaDoc
int row = resultsTable.getSelectedRow();
if (row != -1) {
row = table.convertRowIndexToModel(row);
String value = (String) myModel.getValueAt(row, columnIndex)
A problem with using the JTable.getValueAt() is to get the column you want. When the columns are moved around in the GUI the indexes "change" to match the view. By using the AbstractTableModel.getValueAt() and the JTable.convertXXX() (as outlined by Guillaume) it's just a matter of using the column indexes for the model when retrieving data.
Except from the solution Guillaume gave (Thanks)
I did this:
// resultsTable, myModel
JTable resultsTable;
DefaultTableModel myModel; //javax.swing.table.DefaultTableModel
myModel = (DefaultTableModel) resultsTable.getModel();
// event of clicking on item of table
String value = (String) **resultsTable**.getValueAt(resultsTable.getSelectedRow(), columnIndex)
I used the resultsTable Object instead of the myModel Object to get the value.