我唯一想要的是使用JComboBox正确实现我的Jtable的第六列。当我单击该字段时,组合框突然出现,但是没有单击我将JComponent引用作为String。 我定义了一个自己的tableModel和tableCellrenderer。
这是我的代码:
package examples;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.util.EventObject;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CellEditorListener;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
public class MyTableExample2 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
@SuppressWarnings("unused")
JFrame frame = new MyFrame();
}
});
}
}
class MyFrame extends JFrame {
private static final long serialVersionUID = 1L;
private JComboBox<String> comboBox = new JComboBox<String>(new String[] {
"Me", "You", "They" });
private String[] columnNames = { "First Name", "Last Name", "Sport",
"# of Years", "Vegetarian", "ComboBox" };
private Object[][] data = {
{ "Kathy", "Smith", "Snowboarding", new Integer(5),
new Boolean(true), comboBox },
{ "John", "Doe", "Rowing", new Integer(3), new Boolean(true),
comboBox },
{ "Sue", "Black", "Knitting", new Integer(2), new Boolean(false),
comboBox },
{ "Jane", "White", "Speed reading", new Integer(20),
new Boolean(true), comboBox },
{ "Joe", "Brown", "Pool", new Integer(10), new Boolean(false),
comboBox } };
private JTable jTable = new JTable(new MyTableModel());
private JScrollPane scrollPane = new JScrollPane(jTable);
private Font font = getContentPane().getFont().deriveFont(Font.BOLD, 15);
private class MyTableCellRenderer extends JLabel implements
TableCellRenderer {
private static final long serialVersionUID = 1L;
public MyTableCellRenderer() {
setOpaque(true);
setLayout(new BorderLayout());
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Font font = getFont().deriveFont(Font.BOLD, 15);
table.setRowHeight((int) getPreferredSize().getHeight() + 5);
if ((row % 2) == 0) {
setBackground(new Color(224, 255, 255));
} else {
setBackground(new Color(135, 206, 250));
}
if (isSelected) {
setBackground(new Color(0, 0, 255));
}
setForeground(Color.BLACK);
setText(value.toString());
setFont(font);
return this;
}
}
private TableCellRenderer tableCellRend = new MyTableCellRenderer();
public MyFrame() {
super("JTable");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
jTable.setColumnSelectionAllowed(false);
jTable.setRowSelectionAllowed(true);
jTable.setFillsViewportHeight(true);
jTable.setFont(font);
jTable.setRowHeight(20);
jTable.setGridColor(new Color(100, 149, 237));
jTable.getColumnModel().getColumn(5)
.setCellEditor(new DefaultCellEditor(comboBox));
jTable.setDefaultRenderer(Object.class, tableCellRend);
jTable.setAutoCreateRowSorter(true);
getContentPane().add(scrollPane);
pack();
centerWindow();
setVisible(true);
}
private class MyTableModel implements TableModel {
@Override
public void addTableModelListener(TableModelListener l) {
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return String.class;
case 2:
return String.class;
case 3:
return Object.class;
case 4:
return Object.class;
case 5:
return String.class;
default:
return null;
}
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int columnIndex) {
switch (columnIndex) {
case 0:
return columnNames[0];
case 1:
return columnNames[1];
case 2:
return columnNames[2];
case 3:
return columnNames[3];
case 4:
return columnNames[4];
case 5:
return columnNames[5];
default:
return null;
}
}
@Override
public int getRowCount() {
return data[0].length - 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 5:
return true;
default:
return false;
}
}
@Override
public void removeTableModelListener(TableModelListener l) {
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
data[rowIndex][columnIndex] = aValue;
}
}
public void centerWindow() {
Dimension dimension = getToolkit().getScreenSize();
setLocation(((int) dimension.getWidth()) / 2 - (getWidth() / 2),
((int) dimension.getHeight()) / 2 - (getHeight() / 2));
}
}
这是点击之前的结果:
答案 0 :(得分:2)
在调用Object.toString()之前,必须过滤对象类型并捕获String值; 因为Object.toString()方法返回有关Object的详细信息,除非它是String。
value = value instanceof JComboBox ? ((JComboBox) value).getSelectedItem().toString() : value.toString();
然后你可以使用该值。
setText(value);
我也注意到你打电话了
table.setRowHeight((int) getPreferredSize().getHeight() + 5);
在getTableCellRendererComponent()中。 不要这样做,它会一次又一次地调用getTableCellRendererComponent()本身,它会使堆栈溢出。
我也对模型进行了一些更改。它有一些像@ getRowCount()&#34;返回数据[0] .length - 1;&#34; (列数返回而不是行数)必须是&#34;返回data.length;&#34;
@Override
public Class<?> getColumnClass(int columnIndex) {
Object value = this.getValueAt(0, columnIndex);
return (value == null ? Object.class : value.getClass());
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int columnIndex) {
return columnNames[columnIndex];
}
@Override
public int getRowCount() {
return data.length;
}