individual comboboxes in each cell of a jtable (rookie) - java

Today I did a simple student / course selection database.
Everything works fine so far.
Now I want to implement a graphical representation. I decided to use a JTable (wahltabelle) where each column is a course and each row a student.
There a different ways how a student can visit a course. That’s why I want a Combobox in each cell. The currently selected value represents the student’s current selection and can be changed by the course manager.
The values are loaded and stored from / to a database.
Unfortunately I didn’t find out how to represent an individual combobox in each cell of a table. Therefore I currently have a String representation of my comboboxes.
I know that I can easily change the default cell editor for a complete column. But unfortunately I’m not sure how to do that for a individual cell.
Do I have to write my own cellRenderer?
public void addWahldata(List<Fach> faecher)
{
Vector head = new Vector<>();
head.add("");
for(Fach aktuell : faecher)
{
head.add(aktuell.getBezeichner());
}
Vector data = new Vector<>();
wahltabelle.setModel(new DefaultTableModel(data, head));
Vector rowx = new Vector<>();
rowx.add("");
JComboBox temp= null;
for (int i=1; i<wahltabelle.getColumnCount(); i++)
{
JComboBox cb = new AbiMoeglichkeitenGetter().getAbiMoeglichkeiten(wahltabelle.getColumnName(i));
temp = cb;
rowx.add(cb);
}
data.add(rowx);
wahltabelle.setModel(new DefaultTableModel(data, head));
}
Thanks for any explanation.

Related

How to add a JCheckBox column to my JTable without using models?

I wanted to add a JCheckBox column to my JTable without using models. I searched and found some solutions like using models but they are not what I wanted because my project is at its latest stage and might provide some problems and I don't know how to use Models as well. If anyone can help me find a solution I'll be grateful.
for (int cnt = 0; myStudent.currentCourses[cnt] != 0; cnt++){
for (course c : Courses) {
if (myStudent.currentCourses[cnt] == c.getCourseNum() && myStudent.groupNum[cnt] == c.getGroupsContained()) {
data[cnt][0] = String.valueOf(c.getCourseNum());
data[cnt][1] = String.valueOf(myStudent.groupNum[cnt]);
data[cnt][2] = String.valueOf(c.getUnits());
data[cnt][3] = c.getCourseName();
data[cnt][4] = String.valueOf(c.getSignedNum());
data[cnt][5] = c.getProfessorName();
data[cnt][6] = c.getExamDate();
data[cnt][7] = c.getClassSchedule();
data[cnt][8] = c.getPrerequisites();
data[cnt][9] = c.getExtraInfo();
}
}
}
courseTable = new JTable(data, columnNames);
Just to clarify some things that might confuse you (the whole code is about 800 lines). myStudent is an specific object from a student class and Courses is an ArrayList of a course class (the course class has some properties and I set my data with that specific course information using getters). I want to add JCheckBox column to my table for this reason: if the user choose some courses by checkbox (consider we have 4 courses) and then presses a button under the table, I want to remove that course (row) from the table dynamically.

DefaultTableModel addRow method adds row in format: column_name = column_value instead of just column_value

I am experiencing a issue while trying to add new row in my JTable. My JTable is using DefaultTableModel, here is the code I use for adding a new row:
AddDialog diag = new AddDialog(MainWindow.getInstance(),"Add Entity",true,tab);
diag.setVisible(true);
if(diag.isSaved()) {
entity = diag.getEntity();
table = diag.getTableModel();
table.getEntities().add(entity);
if(tab instanceof TablePreview) {
tablePreview = (TablePreview)tab;
tableModel = (DefaultTableModel) (tablePreview.getTableView().getModel());
Object[] newRow = new Object[entity.getAttributes().size()];
int i=0;
for (Entry<String, Object> entry : entity.getAttributes().entrySet()) {
newRow[i++]=entry;
}
tableModel.addRow(newRow);
}else if(tab instanceof ChildTablePreview) {
System.out.println("Tab is instanceof ChildTablePreview");
}
}else {
System.out.println("Entity not saved!");
}
diag is instance of AddDialog which extends JDialog, and when I fill in the fields of the dialog and click save it creates an Entity class which I want to add to the table as a new row. The logic works fine, but when the row gets inserted into the table, for some reason table looks like this:
If anyone has any idea how I can fix this, I would really appreciate the help!
You need to use a custom cell renderer in your JTable.
How data appears is based on the class of the columns. The default renderer simply calls the .toString() function for the objects in the column. If the column contains a key value pair, its common for these to appear as key=value.
You need to set the renderer using the TableColumn method setCellRenderer. You can define this renderer to only display the value for the objects in that column.

Display Data in a Jtable upon Row Selection from Another JTable

I have read one of the question in this website. and since I had the same problem with the one who asked the same question as mine, I want to do a follow up question. HOW DO YOU PUT THIS INTO CODE:
Ask the master table what its selected row is (getSelectedRow()).
Convert this view row index to a model row index (convertRowIndexToModel()).
Ask the model for the data at this index, ands extract the ID of the data. The model should be a class that you wrote, extending AbstractTableModel.
Then get the data to display in the three sub-tables from this ID, and change the model (or the data contained in the model) of these three tables.
Thanks in advance. i am quite having a hard time in this part of my program. since i only know about
tablePersonalProperty.setModel(DbUtils.resultSetToTableModel(rs));
when displaying all the items from the table. what i need is to DISPLAY the items with the same id from what i have chosen from the main table...
Before we can help you write code, we need more information.
Do your tables both have exactly the same columns?
Are you using your own custom data model already? If not, then you probably need to try that on your own. I can't write this for you since I don't know what you need to include in your model. If you are using netbeans, then you can use the form designer to help you write the table model. Just look at the properties of the JTable after you add it to the JFrame of JPanel. I ended up creating my own anyway, but the code that Netbeans generated helped get me started.
This sample code will help you to do what you are looking for, it show how to move table row from one table to another in a click event in rows,
public class InsertRows{
public static void main(String[] args) {
new InsertRows();
}
public InsertRows(){
final JTable table, table2;
final DefaultTableModel model, model2;
JFrame frame = new JFrame("Inserting rows in the table!");
String data[][] = {{"Vinod","100"},{"Raju","200"},{"Ranju","300"}};
String col[] = {"Name","code"};
Object[][] selrowData = {};
model = new DefaultTableModel(data,col);
model2 = new DefaultTableModel(selrowData,col);
GridLayout gl = new GridLayout(2,1);
table = new JTable(model);
table2 = new JTable(model2);
//Insert first position
model.insertRow(0,new Object[]{"Ranjan","50"});
//Insert 4 position
model.insertRow(3,new Object[]{"Amar","600"});
//Insert last position
model.insertRow(table.getRowCount(),new Object[]{"Sushil","600"});
ListSelectionModel cellSelectionModel = table.getSelectionModel();
cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
String selectedData = null;
String selectedData2 = null;
Object[][] val = {};
int selectedRow = table.getSelectedRow();
int selectedColumns = table.getColumnCount();
model2.insertRow(0,new Object[]{(String) table.getValueAt(selectedRow, selectedColumns-selectedColumns),(String) table.getValueAt(selectedRow, selectedColumns-1) });
}
});
frame.setLayout(gl);
frame.add(new JScrollPane(table));
frame.add(new JScrollPane(table2));
frame.setSize(600,600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Problem with adding JCombobox in JTable in Java?

I have added a combobox in a JTable, the adding code as follows:
Vector<String> header = new Vector<String>();
Vector data = new Vector();
String[] h = new String[]{"Music", "Movie", "Sport"};
header.add("Code");
header.add("Name");
header.add("Salary");
header.add("Hobby");
loadData(); // Add some data to the table
DefaultTableModel tblModel;
tblModel = (DefaultTableModel) this.tblEmp.getModel();
tblModel.setDataVector(data, header);
// Adding combobox to the last column
TableColumn hobbyColumn = tblEmp.getColumnModel().getColumn(3);
hobbyColumn.setCellEditor(new MyComboBoxEditor(h));
Things worked fine until I dynamically add a new row to the table using the code:
Vector v = new Vector();
v.add("E333");
v.add("Peter");
v.add(343);
v.add(""); // This last colum is the combobox so I put it as ""
data.add(v);
tblEmp.updateUI();
Data is added to the table but the combobox in the last column cannot be selected anymore. The combobox is still displayed when I click on the row but cannot select a value.
How can I handle this problem, please?
Never use the updateUI() method. Read the API to see what this method actually does. It has nothing to do with changing the data in a model.
JTable already supports a combo box editor so there is no need to create a custom MyComboBoxEditor. Read the JTable API and follow the link to the Swing tutorial on "How to Use Tables", for a working example of using a combo box as an editor.

How to make a columns in JTable Invisible for Swing Java

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.

Categories