最近在写一个模拟学校教务系统时遇到的一个问题,我想要让教师或者管理员添加课程,要求GUI界面表格显示添加上课时间地点等,要求表格单元中下拉框让其选择。
一开始我的思路是这样的:
获取JTable的某一列,设置列的表格单元编辑器cellEditor为缺省,并置入JComboBox:

public void setComboBox(int col,String[] items){
        TableColumn tc=table.getColumnModel().getColumn(col);
        tc.setCellEditor(new DefaultCellEditor(new JComboBox(items)));

但是这种方式只是为某一列设置一个cellEditor对象,也就是说获取到的该列的所有行的单元格的Editor组件上都是同一个对象JComboBox;
显然这是不正确的,那有没有办法让每一行每一列的所有单元格上都有不同的JComboBox对象?
我查了一些资料后,发现重写一个自己的TableCellEditor类可以实现。具体如下:
自己写的类JComboBoxCellEditor继承AbstractCellEditor和实现TableCellEditor,里面内置一个List对象存放JComboBox,这样,本质上讲该单元格编辑器实际上还是一个一整列的编辑器,但是由于其中包含list对象,可以存放每一行的JComboBox。
这样设计后,要重写方法
public Component getTableCellEditorComponent(JTable jTable, Object o, boolean b, int row, int col),这个方法是你点击表格中的第row行第col列的单元格时会调用的一个重要方法,点击后,应该返回该单元格上存放那个的组件,我们存放的是JComboBox,所以应该根据row来获取list中的JComboBox组件,此方法实现代码如下:

public Component getTableCellEditorComponent(JTable jTable, Object o, boolean b, int row, int col) {
        this.table=jTable;
        this.row=row;
        this.val=o;
        //以上三句话其实用处不大,走个过场。
        /**这里,当row大于当前list中的数量时,
        说明该row行是新添加的,应该让list加入新JComboBox组件。**/
        if(row>=jComboBoxList.size()){
            jComboBoxList.add(new JComboBox(items));
            return jComboBoxList.get(row);
        return this.jComboBoxList.get(row);

除此之外,还应该重写public Object getCellEditorValue()方法,此方法是你在某个单元格中选择了某个值后应该得到的内容。不信的话可以试试只返回一个null看看什么效果,你会发现无论你选择了下拉框的哪个内容,最后显示的永远是空。
此方法具体代码如下:

public Object getCellEditorValue() {
        String item=jComboBoxList.get(jComboBoxList.size()-1).getSelectedItem().toString();
        return item;

至此,贴出完整的自己写的

JComboBoxCellEditor类代码:

public class JComboBoxCellEditor extends AbstractCellEditor implements TableCellEditor {
    int row;
    private JTable table;
    private JComboBox jComboBox;
    private List<JComboBox> jComboBoxList;
    private String[] items;
    private Object val=null;
    public JComboBoxCellEditor(String[] items){
        jComboBox=new JComboBox(items);
        this.items=items;
        jComboBoxList=new ArrayList<>();
        jComboBoxList.add(jComboBox);
    public boolean isCellEditable(EventObject eventObject){
        return true;
    @Override
    public Component getTableCellEditorComponent(JTable jTable, Object o, boolean b, int row, int col) {
        this.table=jTable;
        this.row=row;
        this.val=o;
        if(row>=jComboBoxList.size()){
            jComboBoxList.add(new JComboBox(items));
            return jComboBoxList.get(row);
        return this.jComboBoxList.get(row);
    @Override
    public Object getCellEditorValue() {
        String item=jComboBoxList.get(jComboBoxList.size()-1).getSelectedItem().toString();
        return item;
    public int getSelectedIndex(int row){
        return jComboBoxList.get(row).getSelectedIndex();
		//设置col列为JComboBoxCellEditor
		TableColumn tc=table.getColumnModel().getColumn(col);
        tc.setCellEditor(new JComboBoxCellEditor(items));

如果要获取table上的某个单元格的JComboBox组件选择的序号,可以这么获取:

public int getComboBoxSelectedIndex(int row,int col){
        JComboBoxCellEditor jComboBoxCellEditor=(JComboBoxCellEditor)table.getCellEditor(row,col);
        int index=jComboBoxCellEditor.getSelectedIndex(row);
        return index;

最后给个运行截图

这是我做一个教务系统中的教师添加课程功能初始界面:
下拉框
上课时间和第几大节两列都是下拉框,选择不同的内容:
下拉框
点击提交后,获取所有内容,以下的结果是我按照一定格式化后得到的内容:
在这里插入图片描述
可以看到,下拉框获取的内容是正确独立的(13:30-15:15在我们学校是第3大课,同理接下来就是第4大课)。

项目用到一个需求就是在Jtable单元格中加复选框Jcheckbox或者Jbutton,在网上终于找到了解决的办法。可惜,加两个Jbutton的问题还没有解决。 先记下如何在如何在Jtable单元格中加复选框Jcheckbox和JComboBox。 第一种:自定义自己的TableModel类。 这种方法核心是需要实现getColumnClass()方法,只要覆盖tablemodel的getC...
package com.zte.settool; import javax.swing.table.AbstractTableModel; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ColumnModelTest{ public ColumnMod...
使用Jcombox作为Jtable单元格,想支持下拉和可手工输入,发现手工输入值后,焦点一离开,输入的值丢失,变为下拉选择的值,必须使用敲回车的方式或者tab键的方式才能保存,觉得这样很不方便,特意研究了源码,发现重写列的TableCellEditor的getCellEditorValue()即可。 但同时也存在另一个问题,发现焦点值被带到下一行,所以又重写了getTableCellEditor...
int column = table.getColumnCount();//获取列数 在Jframe的构造方法中,使用table的getRowCount方法可以获取表格的行数,getColumnCount方法可以获取表格的列数。若想获取选中单元格的值可以使用下边的代码。
我们都知道JTable提供了columnModel可以设置指定的实现了TableCellEditor接口的控件但其实现时是整个列使用同一个cellEditor 例如combobox的celleditor就会导致整个列的combobox中的数据相同,这在条件选择时可以这样,但大多数时候我们需要每一行的combobox中的内容不一样 就是说思路上我们要指定每一样的不一样的combobox才可以实现
table = new JTable(model){ private static final long serialVersionUID = 0L; Color color = getForeground(); public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
JTable设置单个单元格颜色 今天在写JavaGUI时,想给表格的单个单元格填充颜色,找了好久 好像并没有看到很明确的方法,为了设置单个单元格的颜色,需要重载jTable对象中的prepareRenderer函数,根据单元格的行号和列号,设置对应的单元格。 String[][] display = {{"a", "b"}, {"c", "d"}}; javax.swing.JTable jTable = new javax.swing.JTable(display, new String[] {
第一 如果你的光标还停留在那个单元格,这时候JTable默认该单元格还没有结束编辑,不会保存当前的值。 第二 如果你的光标不在那个单元格了,这时候JTable应该会认为单元格已经结束编辑,所以会读取编辑后的值。 根据你的描述,你应该是第一种操作,那么你可在点击那个按钮的时候,强制Jtable结束编辑状态,一般可以通过jTable.getCellEditor().stopCel
尝试Swing已经一星期,感觉Swing里的坑还是很多的,对于我这种刚入门的新手来说,接口确实有些不顺手。         闲话休提。需求是这样的,绘制一个数据表格,假如其中某个单元格的数据超出阈值,该单元格标红。         在Swing的库里简略地翻了一阵子的结果是,并没有找到现成的、设置单个单元格的接口,