How can I use setters with a JList with a custom renderer to set a cell's contents?

53 views Asked by At

I have a JList of player objects, i.e. JList<Player>, which uses an implementation of ListCellRenderer<Player> as its cell renderer. The cell renderer itself is a JPanel and contains JLabels displaying information about the player. However, I would like to also display information separate to the player that I can edit with a setter.

In the code below, I have written a minimal example of my code. I know I can edit and update information related to the object the list holds, which I have included as a button. However, say I have an additional entry in the JList cell, "Winnings". I want to write a setter for this JLabel, but I have no idea how to do so, or if this is even possible. What is the best way to do this if it is possible?

For what it's worth, this is for a university-related project, and I cannot edit the player object's implementation to include this information.

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

There are 0 answers