Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to display Components in a JTable?

I'm not asking HOW to display a Component in a JTable, as there are several tutorials and examples online. However, I want to know what the BEST way of going about this might be.

For instance, most tutorials I run into have examples that create separate classes (Main class, one that extends JTable, on that extends TableModel, one that extends TableCellRenderer, et cetera). However, I found that you cannot only do it in one class, but one method by simply using the following:

Example Code (SSCCE)


Main

public class Main
{
  public static void main(String[] args)
  {
    javax.swing.JFrame jf = new javax.swing.JFrame("A table with components");
    jf.setLayout(new java.awt.BorderLayout());
    jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    jf.add(new TableWithCompsPanel(), java.awt.BorderLayout.CENTER);
    jf.setVisible(true);
  }
}

TableWithComps

public class TableWithCompsPanel extends java.awt.Container
{
  private Class<?> tableColumnClassArray[];
  private javax.swing.JTable jTableWithComps;
  private Object tableContentsArray[][];

  public TableWithCompsPanel()
  {
    tableContentsArray = new Object[][]
      {
        {"This is plain text",                                            new javax.swing.JButton("This is a button")    },
        {new javax.swing.JLabel("This is an improperly rendered label!"), new javax.swing.JCheckBox("This is a checkbox")}
      };
    tableColumnClassArray = new Class<?>[]{String.class, java.awt.Component.class};
    initGUI();
  }

  private void initGUI()
  {
    setLayout(new java.awt.BorderLayout());
    jTableWithComps = new javax.swing.JTable(new javax.swing.table.AbstractTableModel()
      {
        @Override public int getRowCount()
        {
          return tableContentsArray.length;
        }

        @Override public int getColumnCount()
        {
          return tableContentsArray[0].length;
        }

        @Override public Object getValueAt(int rowIndex, int columnIndex)
        {
          return tableContentsArray[rowIndex][columnIndex];
        }

        @Override public Class<?> getColumnClass(int columnIndex)
        {
          return tableColumnClassArray[columnIndex];
        }
      });
    jTableWithComps.setDefaultRenderer(java.awt.Component.class, new javax.swing.table.TableCellRenderer()
    {
      @Override public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
      {
        return value instanceof java.awt.Component ? (java.awt.Component)value : new javax.swing.table.DefaultTableCellRenderer();
      }
    });
    add(jTableWithComps, java.awt.BorderLayout.CENTER);
  }
}

Question


What I'm wondering is that, if it can be accomplished in such a short amount of code, why do examples go out of their way to separate it out into three, or sometimes even more, classes? Is my code somehow less efficient at runtime? I can understand separating the main class and the class that has the example GUI, but not why you would separate out the example GUI into several classes.

Edit: I see alot of people giving great reasons why this code is impractical. I would appreciate your answers more if you provided an alternative!

like image 768
Ky. Avatar asked Dec 22 '22 02:12

Ky.


1 Answers

The TableModel models the data you want to track in the simplest way possible, for the sake of memory efficiency. The TableCellRenderer defines how to display that data in a table cell.

In your iTunes checkbox example, the simplest way to model the information from a checkbox is a boolean value (true/false). It's a lot more memory efficient to store a collection of 10,000 boolean objects than 10,000 JCheckBox objects.

The TableCellRenderer can then store a single JCheckBox object, and when it is asked for a component to use to paint the cell, it can check/uncheck the checkbox based on the value and return the same component every time. That way, you aren't creating thousands of UI components over and over again as the user scrolls through the table.

like image 124
Kevin K Avatar answered Dec 28 '22 22:12

Kevin K