简体   繁体   中英

Non editable JTable with existing TableModel

I know I can make JTable not editable by override isCellEditable() function like that:

DefaultTableModel tableModel = new DefaultTableModel() {
    @Override
    public boolean isCellEditable(int row, int column) {
       //all cells false
       return false;
    }
};

table.setModel(tableModel);

but I am using someone else's class (which I can't change) that generates TableModel for me.

Is there any other way that I can achieve non-editable JTable ?

EDIT:

I want non-editable JTable but I want to keep row selection (highlight whole row)

EDIT 2:

This is code that worked for me:

table.setModel(DbUtils.resultSetToTableModel(rs));

for (Class c: Arrays.asList(Object.class, Number.class, Boolean.class)) {
    TableCellEditor ce = table.getDefaultEditor(c);
    if (ce instanceof DefaultCellEditor) {
            ((DefaultCellEditor) ce).setClickCountToStart(Integer.MAX_VALUE);
    }
}

Is there any other way that I can achieve non-editable JTable ?

Override the isCellEditable(...) method of JTable :

JTable table = new JTable( tableModel )
{
    @Override
    public boolean isCellEditable(int row, int column)
    {
        return false;
    }
};

From the JTable API it can be seen that there are several methods that can be used to control a table's selection behavior:

setCellSelectionEnabled(boolean cellSelectionEnabled);
setColumnSelectionAllowed(boolean val);
setRowSelectionAllowed(boolean rowSelectionAllowed);

You can look up the specific descriptions to see if what you want is achieved with any combination of those. From the same API it can also be seen that JTable inherits the method

setEnabled(boolean enabled);

which is described as Sets whether or not this component is enabled. A component that is enabled may respond to user input, while a component that is not enabled cannot respond to user input. Some components may alter their visual representation when they are disabled in order to provide feedback to the user that they cannot take input.

Also, if you cannot change the model class, but you are not forced to use the exact model, you might be able to create a new class extending from it that overrides the isCellEditable method and set this model to the tables.

Here is another approach:

  • table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE)
  • disable a startEditing action
  • DefaultCellEditor#setClickCountToStart(Integer.MAX_VALUE)
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class NonEditableButKeepRowSelectionTableTest {
  public JComponent makeUI() {
    String[] columnNames = {"String", "Integer", "Boolean"};
    Object[][] data = {
      {"aaa", 12, true}, {"bbb", 5, false},
      {"CCC", 92, true}, {"DDD", 0, false}
    };
    DefaultTableModel model = new DefaultTableModel(data, columnNames) {
      @Override public Class<?> getColumnClass(int column) {
        return getValueAt(0, column).getClass();
      }
    };
    JTable table = new JTable(model);
    //table.setEnabled(false);

    table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);

    table.getActionMap().put("none", new AbstractAction() {
      @Override public void actionPerformed(ActionEvent e) {
        System.out.println("dummy");
      }
    });
    table.getInputMap().put(KeyStroke.getKeyStroke("pressed F2"), "none");

    for (Class c: Arrays.asList(Object.class, Number.class, Boolean.class)) {
      //TEST: table.setDefaultEditor(c, null);
      TableCellEditor ce = table.getDefaultEditor(c);
      if (ce instanceof DefaultCellEditor) {
        ((DefaultCellEditor) ce).setClickCountToStart(Integer.MAX_VALUE);
      }
    }
    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(table));
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new NonEditableButKeepRowSelectionTableTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM