JButton在单表单元格java中,而不是整列

时间:2014-12-06 03:46:37

标签: java swing jtable tablecellrenderer tablecelleditor

我一直在研究JTables,并且已经找到了一些很好的资源来解释如何为列设置CellRenderer和CellEditor,但是发现尝试设置单个单元格的渲染器和编辑器的可能性稍差。

我的表的一般想法是有两列,其中左列显示变量名称,右列允许修改相关变量。我已经能够执行验证的大多数单元格,甚至找到了如何以我需要的方式使用DefaultCellRenderer和DefaultCellEditor,但尝试使用我正在努力的自定义渲染器和编辑器。下面我试着说明我的设计下的表格看起来如何: (左手值是变量名,右手是值)

x 0

y 0

isDestructable [复选框]

图像[可点击的单元格]


图像值应允许用户单击该单元格,然后将调出JFileChooser,并提取响应并在单元格内呈现String表示形式。我写了很多代码片段,但是尝试将它们链接在一起就是我真正迷失的部分。下面我提供了迄今为止与这些功能相关的代码:

/*
Code that creates the table and passes a custom model to it. Code for setting the other
types of renderers and editors I have already got working have been omitted
*/
table = new JTable(new MyDataModel(columnNames, values))
{
    public TableCellRenderer getCellRenderer(int row, int col)
    {
        if(col == 1)
        {
            if(table.getModel().getValueAt(row, 0).equals("image"))
            {
                //This is where I would want to set my renderer I believe
            }
        }

        return super.getCellRenderer(row, col);
    }

    public TableCellEditor getCellEditor(int row, int col)
    {
        if(col == 1)
        {
            if(table.getModel().getValueAt(row, 0).equals("image"))
            {
                //This is where I would want to set my editor I believe
            }
         }

         return super.getCellEditor(row, col);
     }
};

/*
As an inner class, I have created the following editor that should display a JFileChooser
when the user clicks on the cell
*/
private class ButtonTableCellEditor extends AbstractTableCellEditor implements TableCellEditor
{
    private JFrame mainframe;
    private JFileChooser jfc;

    public ButtonTableCellEditor(JFrame frame)
    {
        mainframe = frame;
        jfc = new JFileChooser();
    }

    @Override
    public void addCellEditorListener(CellEditorListener arg0)
    {

    }

    @Override
    public void cancelCellEditing()
    {
        //Hide the JFileChooser here
        super.cancelCellEditing();
    }

    @Override
    public Object getCellEditorValue()
    {
        //Here we need to return the filename that has been returned by the JFileChooser
        return "test";
    }

    @Override
    public boolean isCellEditable(EventObject arg0)
    {
        return true;
    }

    @Override
    public void removeCellEditorListener(CellEditorListener arg0)
    {
        //Not sure that I will actually need to use this at all
    }

    @Override
    public boolean shouldSelectCell(EventObject arg0)
    {
        int returned = jfc.showOpenDialog(mainFrame);

        if(returned == JFileChooser.APPROVE_OPTION)
        {
            System.out.println("File was fine");
        }
        else
        {
            stopCellEditing();
        }

        return true;
    }

    public boolean stopCellEditing()
    {
        return false;
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean arg2, int row, int col)
    {
         //This is something I know that is incredibly important based off other examples, but
         //I am unsure what to do in here in my case
         return null;
     }
}

所有我真的需要帮助(我认为)是将ButtonTableCellEditor与我需要的单个单元格链接(条件是左手栏等于"图像",以及如何处理getTableCellEditorComponent(在我的情况下。任何帮助都会非常感激,我现在​​已经被困了一段时间。

此外,这是我的第一个问题(我已经阅读了很多问题,并试图尽可能多地注意),所以如果我提出问题的方式有任何反馈,以便以后的问题可能会更好结构化,这将是最受欢迎的。谢谢大家!

1 个答案:

答案 0 :(得分:0)

基于Intercept JTable Selection ChangeEvents中提供的答案,以及MadProgrammer调查ListSelectionListeners的极其有用的方向,我已经能够提出以下解决方案:

table = new JTable(new CustomModel(columnNames, values))
{
    /*
    I have omitted the other functions I have overridden here as they are not necessary for the
    solution*/

    @Override
    public void changeSelection(int row, int col, boolean toggle, boolean extend)
    {
        if(col == 1 && table.getModel().getValueAt(row, 0).equals("image"))
        {
            /*
            imageChooser is the name of the JFileChooser I am using, and I am passing the
            main frame of my application to centre the window that appears
            */
            int returned = imageChooser.showOpenDialog(frame);

            if(returned == JFileChooser.APPROVE_OPTION)
                table.getModel().setValueAt(imageChooser.getSelectedFile().getName(), row, col);
        }

        super.changeSelection(row, col, toggle, extend);
    }
}

我不相信这个解决方案具有很高的可扩展性,但出于我的程序的目的,它的效果非常好。只要单击了适当的单元格,我就已成功打开JFileChooser,并且单元格内的String将更改为表示所选文件的名称。

单元格本质上充当按钮而不会呈现为一个按钮。根据UI外观要求,这可能并不总是合适的,因为它看起来像普通的表格单元格,可能会导致可用性问题。

编辑:

一种更具伸缩性的方法是使用类似“instanceof”的方法确定第1列中值的类型,因为这将适用于该类型的所有对象。