viernes, 3 agosto 2007
Updated: Displaying a jTable inside another jTable // JTable cellRenderer
After some users asking for answers in my past post, I updated the code of the embedded JTable to make it less buggy and more stable.
This is the "new" code:
/* We initialize the Objects where we'll store our data */
/* First an array Object which will be our main table */
Object[][] data = null;
/* We create an Array String to hold the name of the main table columns In this example case we are going to store a contact name, his email address(es) and his phone numer(s) We're also going to store the creation date.*/
String[] columns = {"Name", "E-Mail","Phone","Creation Date"};
/* First thing is to populate our data object with some example values*/ public void populateData(){ /* Two contacts*/ data = new Object[3][columns.length]; data[0][0] = "Peter"; String[] emails = {"peter@yahoo.com", "strange@name.com"}; data[0][1] = emails; String[] phones = {"555 35 25 65" , "555 35 24 63"}; data[0][2] = phones; data[0][3] = new Date(); data[1][0] = "Jackson"; data[1][1] = "Jack@hotmail.com"; String[] phones2 = {"555 35 24 33" , "555 11 88 88", "332 55 25 34"}; data[1][2] = phones2; data[1][3] = new Date(); data[2][0] = "Robert"; data[2][1] = "rob@hotmail.com"; data[2][2] = "555 28 95 81"; data[2][3] = new Date(); /* AS you can see, we've stored two contacts one with two e-mail accounts and two phone numbers, and another member with three phone numbers*/ } /* Next we create our table models */ public void createModel(){ /* First we create the main model We overide the AbstractTableModel necessary methods*/ AbstractTableModel modelo = new AbstractTableModel() { public String getColumnName(int col) { return columns[col].toString(); } public Class getColumnClass(int col) { if(getRowCount() <1)return null; return data[0][col].getClass(); } public int getRowCount() { return data.length; } public int getColumnCount() { return columns.length;} public Object getValueAt(int row, int col) { return data[row][col]; } public boolean isCellEditable(int row, int col){ return true; } public void setValueAt(Object value, int row, int col) { data[row][col] = value; fireTableCellUpdated(row, col); }}; /* We apply the model to the main jTable */ jTableData.setModel(modelo); /* We create a cell Renderer to display the data of the multivalue fields*/ TableCellRenderer jTableCellRenderer = new TableCellRenderer() { /* Magic Happens */ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { /* If what we're displaying isn't an array of values we return the normal renderer*/ if(!value.getClass().isArray()){ return table.getDefaultRenderer( value.getClass()).getTableCellRendererComponent( table, value, isSelected, hasFocus,row, column); } else{ final Object[] passed = (Object[])value; /* We create the table that will hold the multivalue *fields and that will be embedded in the main table */ JTable embedded = new JTable( new AbstractTableModel() { public int getColumnCount() { return 1; } public int getRowCount() { return passed.length; } public Object getValueAt(int rowIndex, int columnIndex) { return passed[rowIndex]; } public boolean isCellEditable(int row, int col){ return true; } }); if(isSelected){ embedded.setBackground(jTableData.getSelectionBackground()); embedded.setForeground(jTableData.getSelectionForeground()); } if(hasFocus){ embedded.setRowSelectionInterval(0,1); } /* If this is what you plan to enable mouseClick detection, in your table, IT WONT WORK. Have a look at TableCellEditor.*/ embedded.addMouseListener(new MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { System.out.println("PEPE"); } }); setPreferredSize(embedded.getPreferredSize()); if(getPreferredSize().height != table.getRowHeight(row)) { table.setRowHeight(row, getPreferredSize().height); } return embedded; } } }; /* Finally we apply the new cellRenderer to the whole table */ TableColumnModel tcm = jTableData.getColumnModel(); for(int it = 0; it < tcm.getColumnCount(); it++){ tcm.getColumn(it).setCellRenderer(jTableCellRenderer); // tcm.getColumn(it).setCellEditor(jTableCellEditor); } /*Note: if we need to edit the values inside the embedded jtable * we will need to create a TableCellEditor too. */ }

In the above image you can see the result.
Technorati Tags: java j2se gui JTable Embed Table contact TableModel TableCellRenderer TableCellEditor Swing
Posted by at 8:41 AM in Java