java - 当相应列具有空值时,我可以从 jtable 中删除复选框吗?

标签 java swing jtable jcheckbox

我在 jTable 中有 2 列。第一列项目名称,第二列是复选框添加的列。 我尝试将复选框添加到 jTable 列中,但复选框已添加到所有列单元格中。但我只想为 itemname 列中具有值的相应单元格添加复选框。如果 itemname 值为 null,则相应的复选框列我也想设置为空。

最佳答案

使用您自己的 TableCellEditor 和 TableCellRenderer,您可以决定显示您想要的任何内容。这是一个示例,其中我“玩”每隔三行的复选框的可见性:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class TestTable {

    private JFrame f;
    private JTable table;

    private class MyCheckBoxRendererEditor extends JPanel implements TableCellRenderer, TableCellEditor, ActionListener {
        private JCheckBox checkbox;

        DefaultTableCellRenderer defaultRenderer;

        public MyCheckBoxRendererEditor() {
            defaultRenderer = new DefaultTableCellRenderer();
            checkbox = new JCheckBox();
            checkbox.setOpaque(false);
            checkbox.addActionListener(this);
            checkbox.setRequestFocusEnabled(false);
            setOpaque(true);
            add(checkbox);
            validate();
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            stopCellEditing();
        }

        @Override
        public Object getCellEditorValue() {
            return checkbox.isSelected();
        }

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

        @Override
        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }

        @Override
        public boolean stopCellEditing() {
            for (CellEditorListener listener : getListeners(CellEditorListener.class)) {
                listener.editingStopped(new ChangeEvent(this));
            }
            return true;
        }

        @Override
        public void cancelCellEditing() {
            for (CellEditorListener listener : getListeners(CellEditorListener.class)) {
                listener.editingCanceled(new ChangeEvent(this));
            }
        }

        @Override
        public void addCellEditorListener(CellEditorListener l) {
            this.listenerList.add(CellEditorListener.class, l);
        }

        @Override
        public void removeCellEditorListener(CellEditorListener l) {
            this.listenerList.remove(CellEditorListener.class, l);
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            configure(table, value, true, true, row, column);
            return this;
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            configure(table, value, isSelected, hasFocus, row, column);
            return this;
        }

        private void configure(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            defaultRenderer.setBackground(null);
            defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            MyObject myObject = ((MyTableModel) table.getModel()).getValueAt(row);
            checkbox.setVisible(myObject.getValue() != null);
            checkbox.setSelected((Boolean) value);
            setBackground(defaultRenderer.getBackground());
            setBorder(defaultRenderer.getBorder());
        }

    }

    private class MyObject {
        private final String value;
        private boolean checked;

        public MyObject(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public boolean isChecked() {
            return checked;
        }

        public void setChecked(boolean checked) {
            this.checked = checked;
            System.err.println(value + " is " + checked);
        }
    }

    protected void initUI() {
        List<MyObject> data = new ArrayList<TestTable.MyObject>();
        for (int i = 0; i < 20; i++) {
            MyObject object = new MyObject(i % 3 == 1 ? null : "Row " + (i + 1));
            data.add(object);
        }
        table = new JTable(new MyTableModel(data));
        table.getColumnModel().getColumn(1).setCellEditor(new MyCheckBoxRendererEditor());
        table.getColumnModel().getColumn(1).setCellRenderer(new MyCheckBoxRendererEditor());
        table.setRowHeight(30);
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JScrollPane(table), BorderLayout.CENTER);
        f.pack();
        f.setVisible(true);

    }

    public class MyTableModel extends AbstractTableModel {

        private List<MyObject> data;

        public MyTableModel(List<MyObject> data) {
            super();
            this.data = data;
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        public MyObject getValueAt(int row) {
            return data.get(row);
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            switch (columnIndex) {
            case 0:
                return getValueAt(rowIndex).getValue();
            case 1:
                return getValueAt(rowIndex).isChecked();
            }
            return null;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            if (columnIndex == 1) {
                getValueAt(rowIndex).setChecked((Boolean) aValue);
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 1 && getValueAt(rowIndex).getValue() != null;
        }

        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
            case 0:
                return String.class;
            case 1:
                return Boolean.class;
            }
            return Object.class;
        }

        @Override
        public String getColumnName(int column) {
            switch (column) {
            case 0:
                return "Value";
            case 1:
                return "Checked";
            }
            return null;
        }

    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTable().initUI();
            }
        });
    }

}

关于java - 当相应列具有空值时,我可以从 jtable 中删除复选框吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11150474/

相关文章:

java - 由于分析错误,Sonarlint 未处理文件

java - 如何在不使用按钮和面板的情况下将 ActionListener 添加到 JFrame ?

java - 框架中未显示贝塞尔曲线

java - 从 Java JTable 中删除多个项目

java - 字符串内存模型 - java6

java - Unresolved 依赖 SBT play#sbt-plugin;2.0 : not found Play examples on Heroku

java - eclipse 中的 JTable 不显示列名

java - 在 swing 中向现有表添加一列

java - 从本地方法抽象内部类扩展后,无法将内部类中的方法设置为私有(private)

java - 如何将两个 jComboBox 链接在一起并将数据显示到 jtextarea 中?