java - 为 JTable 中的不同单元格添加不同的 JComboBox

标签 java swing jtable jcombobox tablecelleditor

假设我有一个代表 Person 的对象。 每个人都有一个名字和一系列爱好。

现在,我想为我拥有的人员列表创建一个包含 2 列的表。 第一列将显示该人的姓名,第二列将在组合框中显示爱好列表。

问题是,我迭代我的人员列表以填充表。 所以我没有办法在一开始就知道“第 1 行将有组合框 X,第 2 行将有组合框 Y 等等”。我只会在运行时知道这些事情。

有什么想法吗?

最佳答案

单元格编辑由CellEditor提供。这基本上意味着每一列都将具有相同的单元格编辑器。有很多方法可以解决这个问题,但让我们保持简单。

假设爱好列表是有限的,并且该列表对于所有人来说都是相同的,那么创建一个基于 JComboBoxCellEditor 并应用将是一件简单的事情放到 table 上

首先查看 Concepts: Editors and RenderersUsing Other Editors

combo box editor

import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;

public class Hobbies {

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

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

                List<Person> people = new ArrayList<>(25);
                people.add(new Person("Mellisa"));
                people.add(new Person("Annabell"));
                people.add(new Person("Margarita"));
                people.add(new Person("Steve"));
                people.add(new Person("Christel"));

                DefaultCellEditor editor = new DefaultCellEditor(new JComboBox(createHobbiesComboBoxModel()));

                PersonTableModel model = new PersonTableModel(people);
                JTable table = new JTable(model);
                table.getColumnModel().getColumn(1).setCellEditor(editor);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }

    public ComboBoxModel createHobbiesComboBoxModel() {
        String[] hobbies = {"3D Printing",
            "A vintage scrapbook",
            "Amateur radio[1]",
            "Baton twirling",
            "Cleaning",
            "Computer programming",
            "Cooking",
            "Coloring",
            "Cosplaying",
            "Creative writing",
            "Crocheting",
            "Cryptography",
            "Dance",
            "Digital arts",
            "Drama",
            "Drawing",
            "Drinking Coffee",
            "Eating",
            "Electronics",
            "Embroidery",
            "Foreign language learning",
            "Gaming (tabletop games and role-playing games)",
            "Gambling",
            "Genealogy",
            "Homebrewing"};
        return new DefaultComboBoxModel(hobbies);
    }

    public class PersonTableModel extends AbstractTableModel {

        private List<Person> people;

        public PersonTableModel(List<Person> person) {
            people = new ArrayList<>(person);
        }

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

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

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 1;
        }

        @Override
        public String getColumnName(int columnIndex) {
            String value = null;
            switch (columnIndex) {
                case 0:
                    value = "Name";
                    break;
                case 1:
                    value = "Hobby";
                    break;
            }
            return value;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            if (columnIndex == 1) {
                Person person = people.get(rowIndex);
                person.setHobby(aValue == null ? null : aValue.toString());
                fireTableCellUpdated(rowIndex, columnIndex);
            }
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Object value = null;
            Person person = people.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    value = person.getName();
                    break;
                case 1:
                    value = person.getHobby();
                    break;
            }
            return value;
        }

    }

    public class Person {

        private String name;
        private String hobby;

        public Person(String name) {
            this.name = name;
        }

        public void setHobby(String hobby) {
            this.hobby = hobby;
        }

        public String getName() {
            return name;
        }

        public String getHobby() {
            return hobby;
        }

    }

}

关于java - 为 JTable 中的不同单元格添加不同的 JComboBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25377813/

相关文章:

java - 日志 spring Bean 实例化

java设置表格中特定单元格的颜色

java - JPanel 中的 JTable 大小合适

java - 春狐 : Short type is considered as $int32

java - java中如何将字符串复制到系统剪贴板?

java - 在类中存储对象类型的最佳实践

java - 如何用JLabel创建定时器?

java - CarPark 不是抽象的,不会重写抽象方法(需要帮助)

java - 行添加两次 jtable

java - 如何将 jcombobox 添加到 netbeans 中的 jtable 列