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. */
          
    }

JTable with another embedded JTable

In the above image you can see the result.

Technorati Tags:

Posted by admin at 8:41 AM in Java

Google
 
« August »
SunMonTueWedThuFriSat
   1234
567891011
12131415161718
19202122232425
262728293031