某些单元格中的复选框,但不是所有单元格中的复选框 - JTable

时间:2013-05-09 02:03:41

标签: java swing jtable tablecellrenderer

这可能是一个模糊的查询,所以请原谅我。

自定义JTable(我修改了查询并将根据提供的SSCCE进行讨论)。我将创建一个JTable,根据JTable中选中的复选框提供授权

此JTable的目的是向用户显示应用程序的所有菜单选项。这个JTable有三列: 第一栏:Bollean类(复选框) 第二列:类String(主菜单项) 第三列:类String(子菜单项)

要提供授权,用户应选择与子菜单项对应的复选框,最后选择“授权”按钮(由于我的授权功能正常,我没有包含授权按钮)

现在UI要求是在JTable的第一列中,我应该只显示与子菜单项对应的复选框,而不是在第一列的每个单元格中显示复选框(换句话说,它不应该显示与主菜单对应的复选框)菜单项)

下面的图片是预期输出(虽然我的第一列中的所有单元格都带有复选框)

Expected UI

public class SwingSolution extends JPanel {

    public SwingSolution() {
        super(new GridLayout(1,0));

        String[] columnNames = {"", "Main Menu", "Sub Menu"};

        Object[][] data = {
        {false, "File", ""},
        {false, "", "New"},
        {false, "", "Save"},
        {false, "", "Close"},
        {false, "Edit", ""},
        {false, "", "Delete"},
        {false, "", "Format"},
        {false, "Project", ""},
        {false, "", "Create New"},
        {false, "", "Delete"},
        {false, "", "Build"},
        {false, "", "Properties"},
        };

        DefaultTableModel model = new DefaultTableModel(data, columnNames);
        final JTable table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                switch (column) {
                    case 0:
                        return Boolean.class;
                    case 1:
                        return String.class;
                    case 2:
                        return String.class;
                    default:
                        return Boolean.class;
                }
            }
        };

        table.getColumnModel().getColumn(0).setMaxWidth(30);
        table.getColumnModel().getColumn(1).setMaxWidth(100);
        table.getColumnModel().getColumn(2).setMaxWidth(120);

        table.setPreferredScrollableViewportSize(new Dimension(250, 195));
        table.setFillsViewportHeight(true);

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Add the scroll pane to this panel.
        add(scrollPane);
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("SimpleTableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        SwingSolution newContentPane = new SwingSolution();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

我尝试使用单元格渲染器进行各种操作,并使用google搜索JTable和自定义单元格,但无法弄明白。任何帮助将不胜感激

3 个答案:

答案 0 :(得分:5)

基本上,你将为你提供细胞渲染器和编辑器。

在这种情况下,我将第一列值/类型更改为int。这使我能够提供boolean以外的其他含义。

如果列值为0,则该单元格不是“可选”,取消选中1,则会检查2

我还修改了isCellEditable的{​​{1}}方法,只允许“有效”单元格可编辑。

enter image description here

TableModel

我没有完成编辑,但基本概念是一样的......

答案 1 :(得分:2)

重写getCellRenderer()方法以返回适当的渲染器。类似的东西:

@Override
public TableCellRenderer getCellRenderer(int row, int column)
{
    int modelColumn = convertColumnIndexToView(column);

    if (modelColumn == 0 && getValueAt(row, column).equals(""))
        return getDefaultRenderer(String.class);
    else
        return super.getCellRenderer(row, column);
}

您还需要更改模型中的数据:

{"", "File", ""},

最后,您还可以覆盖isCellEditable()方法,使空单元格不可编辑。

然后,您可以使用默认的布尔渲染器/编辑器来显示列中的其他行。

答案 2 :(得分:2)

您可以使用Boolean包装类而不是原始类型编写自己的TableCellRenderer并覆盖getTableCellRendererComponent(..)方法。

public class CustomTableCellRenderer extends DefaultTableCellRenderer
{
    public CustomTableCellRenderer()
    {
        super();
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, 
            boolean isSelected, boolean hasFocus, int row, int column)
    {
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        if(value instanceof Boolean)
        {
            if(value != null)
            {
                 JCheckBox jcb = new JCheckBox();
                 jcb.setSelected((Boolean) value);

                 return jcb;
            }
            return new JPanel();
        }
    return this;
    }
}

然后只需设置infos.setDefaultRenderer(Boolean.class, new CustomTableCellRenderer());并使用new Boolean(true)替换数组中的原始类型。如果您不想拥有JCeckBox,则会显示null而不是Boolean,并且会显示空的JPanel