Inserting text alongside a checkbox in a Jtable cell

99封情书 提交于 2019-12-24 09:50:07

问题


I have been fiddling around with this for a while, and all the solutions and working examples I could find included check boxes rendered using the built-in Boolean TableCellRenderers, that is a cell could have only a check box. I didn't find any working example where there would be some text alongside that check box in that SAME cell, or more specifically a JCheckBox which allows a check box and a text.


回答1:


When your data/requirements doesn't fit within the default available functionality, you need to look towards providing a customised solution

I'd recommend you start by having a look at 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;
        }

    }

}

At this point, I'm left wondering if JTable is the best solution and if JList might be better

Of course, another option, which might work better with JTable, would be to devise a custom TableModel which could break down the data into separate columns...

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;
        }



    }

}

IMHO, this is a better solution for using JTable



来源:https://stackoverflow.com/questions/47851299/inserting-text-alongside-a-checkbox-in-a-jtable-cell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!