首页 > 解决方案 > 如何使用带有自定义渲染器的 JList 的 setter 来设置单元格的内容?

问题描述

我有一个播放器对象的 JList,即JList<Player>,它使用 的实现ListCellRenderer<Player>作为其单元格渲染器。单元格渲染器本身是一个 JPanel,并包含显示有关播放器信息的 JLabels。但是,我还想显示与我可以使用设置器编辑的播放器分开的信息。

在下面的代码中,我编写了我的代码的最小示例。我知道我可以编辑和更新与列表包含的对象相关的信息,我已将其作为按钮包含在内。但是,假设我在 JList 单元格中有一个附加条目“Winnings”。我想为这个 JLabel 写一个 setter,但我不知道该怎么做,或者这是否可能。如果可能的话,最好的方法是什么?

对于它的价值,这是一个与大学相关的项目,我无法编辑播放器对象的实现以包含此信息。

public class Example {

    JList<Player> list;
    DefaultListModel<Player> model;

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

    public Example() {
        JFrame frame = new JFrame();
        JPanel mainPanel = new JPanel(new BorderLayout());

        model = new DefaultListModel<>();
        list = new JList<>(model);
        list.setCellRenderer(new Renderer());

        Player player = new Player("Harry", 5);
        model.addElement(player);

        JButton setNameButton = new JButton("Set player name to Ron");
        setNameButton.addActionListener(e -> {
            player.setName("Ron");
            list.revalidate();
            list.repaint();
        });

        mainPanel.add(new JScrollPane(list), BorderLayout.WEST);
        mainPanel.add(setNameButton, BorderLayout.CENTER);

        frame.add(mainPanel);
        frame.setSize(300, 400);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public class Player {
        String name;
        int points;

        public Player(String name, int points) {
            this.name = name;
            this.points = points;
        }

        public int getPoints() { return points; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    }

    public class Renderer extends JPanel implements ListCellRenderer<Player>
    {
        private JLabel playerName = new JLabel("");
        private JLabel points = new JLabel("");
        private JLabel winnings = new JLabel("Winnings: ");

        public Renderer()
        {
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            add(playerName);
            add(points);
            add(winnings);
        }

        @Override
        public Component getListCellRendererComponent(JList<? extends Player> list, Player player, int index,
                boolean isSelected, boolean cellHasFocus) {
            playerName.setText("Name: " + player.getName());
            points.setText("Points: " + Integer.toString(player.getPoints()));

            return this;        
        }

        public void setWinnings(String string) {
            // I want to be able to write a setter for winnings, i.e.
            // winnings.setText("New winnings: " string);
        }
    }
}

标签: javaswingjlistsetterlistcellrenderer

解决方案


推荐阅读