3
我有一个3列JTable。第2列是一个复选框,我想为该行启用/禁用JSpinner。JTable与JSpinner启用/禁用
我一直在努力,除了一件事情--JSpinner看起来并不像它的残疾人(文本和微调按钮变灰)。我不太清楚如何实现这一点。我试着在JSpinner上强制调用setEnabled(false),但表似乎没有正确重画。
下面是一些代码,我已经得到了通过其他StackOverflow的实例工作:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class SpinnerTable {
public JComponent makeUI() {
String[] columnNames = { "Name", "Spinner Enable", "Spinner" };
final Object[][] data = { { "aaa", true, 1 }, { "bbb", true, 10 },
{ "ccc", true, 10 } };
final DefaultTableModel model = new DefaultTableModel(data, columnNames) {
@Override
public Class<?> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
JTable table = new JTable(model) {
@Override
public void setValueAt(Object aValue, int row, int column) {
super.setValueAt(aValue, row, column);
}
@Override
public boolean isCellEditable(int row, int column) {
if (column == 2)
return (Boolean) model.getValueAt(row, 1);
return super.isCellEditable(row, column);
}
};
table.setRowHeight(36);
table.setAutoCreateRowSorter(true);
TableColumn column = table.getColumnModel().getColumn(2);
column.setCellRenderer(new ComboBoxCellRenderer());
column.setCellEditor(new ComboBoxCellEditor());
return new JScrollPane(table);
}
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 SpinnerTable().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class SpinnerPanel extends JPanel {
protected JSpinner spinner = new JSpinner() {
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
return new Dimension(40, d.height);
}
};
public SpinnerPanel() {
super();
setOpaque(true);
add(spinner);
}
}
class ComboBoxCellRenderer extends SpinnerPanel implements TableCellRenderer {
public ComboBoxCellRenderer() {
super();
setName("Table.cellRenderer");
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setBackground(isSelected ? table.getSelectionBackground() : table
.getBackground());
if (value != null) {
spinner.setValue(value);
}
return this;
}
}
class ComboBoxCellEditor extends SpinnerPanel implements TableCellEditor {
public ComboBoxCellEditor() {
super();
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
fireEditingStopped();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
fireEditingStopped();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
this.setBackground(table.getSelectionBackground());
spinner.setValue(value);
return this;
}
// Copid from DefaultCellEditor.EditorDelegate
@Override
public Object getCellEditorValue() {
return spinner.getValue();
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
if (anEvent instanceof MouseEvent) {
MouseEvent e = (MouseEvent) anEvent;
return e.getID() != MouseEvent.MOUSE_DRAGGED;
}
return true;
}
@Override
public boolean stopCellEditing() {
fireEditingStopped();
return true;
};
transient protected ChangeEvent changeEvent = null;
@Override
public boolean isCellEditable(EventObject e) {
return true;
}
@Override
public void cancelCellEditing() {
fireEditingCanceled();
}
@Override
public void addCellEditorListener(CellEditorListener l) {
listenerList.add(CellEditorListener.class, l);
}
@Override
public void removeCellEditorListener(CellEditorListener l) {
listenerList.remove(CellEditorListener.class, l);
}
public CellEditorListener[] getCellEditorListeners() {
return listenerList.getListeners(CellEditorListener.class);
}
protected void fireEditingStopped() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((CellEditorListener) listeners[i + 1])
.editingStopped(changeEvent);
}
}
}
protected void fireEditingCanceled() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((CellEditorListener) listeners[i + 1])
.editingCanceled(changeEvent);
}
}
}
}
fireTableRowsUpdated(row,row);不需要关注DefaultTableModel,那么这个通知器被调用两次 – mKorbel
@dubdubdubdot移动所有东西,从JTable到DefaultTableModel – mKorbel
的每条代码行都将简单的微调器放到了渲染器上,而JPanel是无用的,或者还有另一个选项所有的JComponents到JPanel,[那么将有一列的JTable](http://stackoverflow.com/a/15090127/714968) – mKorbel