Search code examples
javaswingjtableselectionjtableheader

How to select a column of a JTable in JDialog by selecting a header


enter image description here

What I've been trying to do with a JDialog are...

  1. To select a column of JTable by clicking the header
  2. To check which column is selected by the user
  3. To get the value of the cells inside the column

According to this post and this page , it would be possible to select a column by clicking the header, by setting a JTableHeader.

However, neither of them seem to be applicable to what I'm trying to do.

First of all, I'm not sure where to put JTableHeader. The examples above seem to have put it for the initialization, but I don't see any appropriate space to do this in my coding.

At least I know that the second example is JPanel. So, in order to have a JTableHeader in JDialog, JTableHeader will need to be set in a completely different position, since initComponents() of JDialog cannot be modified manually by default.

In addition, I cannot find how to select a header (unlike individual cells). I assume that I need to set a JTableHeader beforehand.

Finally, I don't see any method to detect which column is selected. At least I found jTable.getValueAt(int, int) method, but this method seems to be made to get a single cell.

Now I suspect that it might be impossible to do them with JTable and JDialog. I'd appreciate if you'd give any insight.

I add a part of initComponents() so that you'd easily understand it.

private void initComponents() {

    //here are irrelevant codes
    jTable1 = new javax.swing.JTable();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

    jLabel1.setFont(new java.awt.Font("MS UI Gothic", 3, 18)); // NOI18N
    jLabel1.setText("Choose level(s) or unit(s)");

    //irrelevant codes

    jTable1.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {"EN6", "EN3", "EN5", "IN1"},
            {"EN2", "EN3", null, "IN4"},
            {null, null, null, "IN1"},
            {null, null, null, "IN2"},

        new String [] {
            "EN2", "EN3", "EN5", "IN1"
        }
    ) {
        Class[] types = new Class [] {
            java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
        };
public Class getColumnClass(int columnIndex) {
            return types [columnIndex];
        }
    });
//lots of lines, seem to be irrelevant
pack();
}

Solution

  • "[...]it would be possible to select a column by clicking the header, by setting a JTableHeader."

    Based on your requirements I don't think you need to provide your own table header but attach a MouseListener to the default one instead. This way and using both rows and columns selection models you can easily achieve your goal.

    Snippet

    final JTable table = new JTable(tableModel);
    table.setColumnSelectionAllowed(true);
    table.getTableHeader().addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            // Get the right column based on MouseEvent#getPoint()
            int columnIndex = table.columnAtPoint(e.getPoint());
            // Set this column as the selected one in the columns selection model
            table.getColumnModel().getSelectionModel().setSelectionInterval(columnIndex, columnIndex);
            // Set all the rows as the selected ones in the rows selection model
            table.getSelectionModel().setSelectionInterval(0, table.getRowCount() - 1);
            // Print the values in selected column
            for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {
                System.out.println(table.getValueAt(rowIndex, columnIndex));
            }
        }
    });
    

    Note: don't forget to allow columns selection.

    See: