SwingX supports configuring the editability on the view layer. No need to touch your model, keep it editable as appropriate:
viewTable = new JXTable(model);
viewTable.setEditable(false);
editTable = new JXTable(model);
题
I have a custom table model whose data I want to edit in one JXTable, but view-only in a second JXTable. Can this be done without having two separate models? Is there some way of overriding model.isCellEditable for the view-only table?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.ComponentAdapter;
import org.jdesktop.swingx.decorator.HighlightPredicate;
public class SSCCE extends JPanel {
private JSplitPane splitPane;
private JXTable viewTable, editTable;
private class CustomModel extends AbstractTableModel {
public static final int SPORT_COL = 0;
public static final int EQUIPMENT_COL = 1;
private final String[] COLUMN_NAMES = {
"Sport",
"Equipment"
};
private Map<String, String> sports;
private List<String> set;
public CustomModel() {
sports = new TreeMap<String, String>();
sports.put("Rugby", "Headguard");
sports.put("Hurling", "Sliotar");
sports.put("Tennis", "Racket");
set = new ArrayList<String>(sports.keySet());
}
public int getRowCount() {
return sports.size();
}
public int getColumnCount() {
return COLUMN_NAMES.length;
}
@Override
public String getColumnName(int columnIndex) {
return COLUMN_NAMES[columnIndex];
}
public Object getValueAt(int rowIndex, int columnIndex) {
String sport = set.get(rowIndex);
switch (columnIndex) {
case SPORT_COL:
return sport;
case EQUIPMENT_COL:
return sports.get(sport);
}
return null;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == EQUIPMENT_COL) {
if (aValue != null) {
String sport = (String) getValueAt(rowIndex, SPORT_COL);
String equip = (String) aValue;
sports.put(sport, equip);
fireTableDataChanged();
}
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == EQUIPMENT_COL;
}
}
private CustomModel model;
public SSCCE() {
super();
model = new CustomModel();
viewTable = new JXTable(model);
editTable = new JXTable(model);
editTable.addHighlighter(new ColorHighlighter(new HighlightPredicate() {
@Override
public boolean isHighlighted(Component renderer, ComponentAdapter adapter) {
return adapter.isEditable();
}
}, Color.GREEN.brighter(), Color.BLACK));
JPanel panelLeft = new JPanel(new BorderLayout(0, 10));
panelLeft.add(new JLabel("Editable"), BorderLayout.NORTH);
panelLeft.add(new JScrollPane(editTable));
JPanel panelRight = new JPanel(new BorderLayout(0, 10));
panelRight.add(new JLabel("How to make non-editable?"), BorderLayout.NORTH);
panelRight.add(new JScrollPane(viewTable));
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLeft, panelRight);
add(splitPane);
}
public static void main(String args[]) {
JFrame frame = new JFrame("One Model | Two Views");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SSCCE(), BorderLayout.CENTER);
frame.setSize(360, 240);
frame.setVisible(true);
}
}
解决方案
SwingX supports configuring the editability on the view layer. No need to touch your model, keep it editable as appropriate:
viewTable = new JXTable(model);
viewTable.setEditable(false);
editTable = new JXTable(model);
其他提示
Create a WrapperTableModel
which delegates all the calls to the inner TableModel
but returns false from isCellEditable().
Set the first editable model to the table1 and the wrapper model (holding reference to the first) in the table2.