java - 在 Jtable 单元格中的复选框旁边插入文本

标签 java swing jtable

我已经摆弄这个问题有一段时间了,我能找到的所有解决方案和工作示例都包含使用内置 boolean TableCellRenderers 渲染的复选框,即一个单元格只能有一个复选框。我没有找到任何工作示例,其中在同一单元格中的复选框旁边会有一些文本,或者更具体地说,是一个允许复选框和文本的 JCheckBox。

最佳答案

当您的数据/要求不符合默认可用功能时,您需要寻求提供定制解决方案

我建议您首先查看 Using custom renderers

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public class Data {
        private String text;
        private boolean selected;

        public Data(String text, boolean selected) {
            this.text = text;
            this.selected = selected;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean state) {
            this.selected = state;
        }

    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            DefaultTableModel model = new DefaultTableModel(new String[] {"Something"}, 0) {
                @Override
                public Class<?> getColumnClass(int columnIndex) {
                    return Data.class;
                }
            };
            model.addRow(new Object[]{new Data("Hello", true)});
            model.addRow(new Object[]{new Data("Goodbye", false)});
            model.addRow(new Object[]{new Data("Do you want to play a game?", true)});
            model.addRow(new Object[]{new Data("Yesturday", false)});
            model.addRow(new Object[]{new Data("Tomorrow", true)});
            model.addRow(new Object[]{new Data("Java", false)});
            model.addRow(new Object[]{new Data("Swift", false)});
            model.addRow(new Object[]{new Data("Helicopter", true)});


            JTable table = new JTable(model);
            table.setDefaultRenderer(Data.class, new DataTableCellRenderer());

            add(new JScrollPane(table));
        }

    }

    public class DataTableCellRenderer extends JCheckBox implements TableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                setBackground(table.getSelectionBackground());
                setForeground(table.getSelectionForeground());
            } else {
                setBackground(table.getBackground());
                setForeground(table.getForeground());
            }

            if (value instanceof Data) {
                Data data = (Data)value;
                setText(data.getText());
                setSelected(data.isSelected());
            }

            return this;
        }

    }

}

此时,我想知道 JTable 是否是最佳解决方案,以及 JList 是否可能更好

当然,另一种可能更适合 JTable 的选择是设计一个自定义 TableModel,它可以将数据分解为单独的列...

Custom table model

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public class Data {

        private String text;
        private boolean selected;

        public Data(String text, boolean selected) {
            this.text = text;
            this.selected = selected;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean state) {
            this.selected = state;
        }

    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            DataTableModel model = new DataTableModel();
            model.add(new Data("Hello", true));
            model.add(new Data("Goodbye", false));
            model.add(new Data("Do you want to play a game?", true));
            model.add(new Data("Yesturday", false));
            model.add(new Data("Tomorrow", true));
            model.add(new Data("Java", false));
            model.add(new Data("Swift", false));
            model.add(new Data("Helicopter", true));

            JTable table = new JTable(model);

            add(new JScrollPane(table));
        }

    }

    public class DataTableModel extends AbstractTableModel {

        private List<Data> rows = new ArrayList<>(25);

        public void add(Data data) {
            int rowCount = getRowCount();
            rows.add(data);
            fireTableRowsInserted(rowCount, rowCount);
        }

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

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

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

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

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Data row = rows.get(rowIndex);
            switch (columnIndex) {
                case 0: return row.isSelected();
                case 1: return row.getText();
            }
            return null;
        }



    }

}

恕我直言,这是使用 JTable 的更好解决方案

关于java - 在 Jtable 单元格中的复选框旁边插入文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47851299/

相关文章:

Java:如何实现3和?

java - 我如何评估哈希表的实现? (引用HashMap)

java - 在文本区域中显示循环结果

java - Java中如何确定输入参数的数量

java - JSplitPanel 内 Jpanel 的大小

java - 哪个 Java 类允许我显示图像占位符?

java - 一些疑问与此 Swing MVC 实现有关。打开数据库连接应该是 Controller 任务?

Java jtable 允许行选择

java - 在 Jtable 行中插入多行

java - Eclipse 中的 Google Web 工具包