0

I am having trouble updating one of my JPanel based on a JList click found in another panel. I have tried using the code I found here:

repaint JPanel with every click at JList

but I still have issues. I have pasted my code below:

import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class SelectionFrame extends JFrame {
    private BufferedImage backgroundImage;  
    private JList<Object> superClassList;
    private JPanel contentPane;
    private CharacterListPanel clp;
    private CharacterDetailsPanel cdp;
    private CardLayout card = new CardLayout();

    protected SelectionFrame() {
        // Create the background image
        try {
            backgroundImage = ImageIO.read(new File(GUIConfig.DEFAULT_GAME_BACKGROUND));
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Set the title to the default
        setTitle(GUIConfig.DEFAULT_GAME_TITLE);

        // Set the frame background
        contentPane = new JPanel(){ 

            public void paintComponent(Graphics g) {
                Image img = Toolkit.getDefaultToolkit().getImage(Gui.class.getResource("/others/background_1.png"));  
                g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);  
               }  
        };

        contentPane.setBackground(new Color(238, 238, 238));
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);

        // Add Character List Panel to JFrame
        clp = new CharacterListPanel();
        cdp = new CharacterDetailsPanel();

        add(clp, BorderLayout.LINE_START);
        add(cdp, BorderLayout.LINE_END);

        // Grab its list and store it in super class list
        superClassList = clp.getCharacterList();

        // List for change in list
        superClassList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (!e.getValueIsAdjusting()) {
                    String selectedVal = superClassList.getSelectedValue().toString();
                    System.out.println(selectedVal);
                    cdp.setName(selectedVal);
                    repaint();
                }
            }
        });

        // Set the size of the frame to the default, center frame, hide top level and do not allow resizing
        setSize(GUIConfig.DEFAULT_SELECTION_MENU_WIDTH, GUIConfig.DEFAULT_SELECTION_MENU_HEIGHT);
        setLocation(GUIConfig.HALF_DIMENSION_WIDTH - (int) this.getSize().getWidth()/2, GUIConfig.HALF_DIMENSION_HEIGHT - (int) this.getSize().getHeight()/2);
        setUndecorated(true);
        setResizable(false);
        pack();

        // Show frame
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    // This sub class is used to display the list of playable characters. it will include the character name and character icon
    class CharacterListPanel extends JPanel {
        private JList<Object> characterList;

        protected CharacterListPanel() {
            // Create list to hold name and icon for characters
            characterList = new JList<Object>();

            // Set list details
            characterList.setBorder(new LineBorder(Color.BLACK));
            characterList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

            // Map of characters
            Map<Object, ImageIcon> characters = new HashMap<Object, ImageIcon>();

            // Loop through default character names and retrieve character icon file paths
            for(int i = 0; i < GUIConfig.DEFAULT_CHARACTER_NAMES.size(); i+=1) {
                ImageIcon img = new ImageIcon(GUIConfig.DEFAULT_CHARACTER_SYMBOLS.get(GUIConfig.DEFAULT_CHARACTER_NAMES.get(i)));
                characters.put(GUIConfig.DEFAULT_CHARACTER_NAMES.get(i), img);
            }

            // Add items to the list
            characterList.setListData(GUIConfig.DEFAULT_CHARACTER_NAMES.toArray());
            characterList.setCellRenderer(new IconListRenderer(characters));

            // Add list to JPanel
            add(characterList);

            // Remove grey background of JPanel
            setOpaque(false);
        }

        protected JList<Object> getCharacterList() {
            return characterList;
        }
    }

    // This sub class is used to display the character details card based on what the user has selected in the list
    class CharacterDetailsPanel extends JPanel {
        private String name = null;

        protected CharacterDetailsPanel() {
            System.out.println(getName());
            if(getName() == null || getName().isEmpty()){
                try {
                    BufferedImage img = ImageIO.read(new File(GUIConfig.DEFAULT_CHARACTER_DETAILS.get("Default")));
                    JLabel picLabel = new JLabel(new ImageIcon(img));
                    add(picLabel);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    BufferedImage img = ImageIO.read(new File(GUIConfig.DEFAULT_CHARACTER_DETAILS.get(getName())));
                    JLabel picLabel = new JLabel(new ImageIcon(img));
                    add(picLabel);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


            // Remove grey background of JPanel
            setOpaque(false);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public static void main(String[] args) {
        SelectionFrame sf = new SelectionFrame();
    }
}

In my current iteration above the code is not like that in the link. The reason for this is that I tried code there; I literally copied and pasted and worked my way through it, and nothing happened. I think this is because in his case it's a list added directly to the frame and a panel. In my case its a list in a panel and another panel added to the JFrame. So like I said the code above abandon the sample found in the link. Instead what I tried to do was create the panels add them to the frame, and edit the panel I wanted changed every time a click happened by changing its name value; the name value is used to get the proper file.

Community
  • 1
  • 1
soccerman stan
  • 121
  • 1
  • 11
  • 1
    Please read http://stackoverflow.com/help/mcve to understand how to create a minimal code example. Just copy/pasting your current code doesn't make for a good question. – Duncan Jones Mar 06 '15 at 16:22
  • @Duncan *"Just copy/pasting your current code doesn't make for a good question."* Especially given the supplied code will not compile cleanly due to missing classes, and would not run the same for missing images. OP: One way to get image(s) for an example is to **hot link** to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). – Andrew Thompson Mar 06 '15 at 23:42
  • 1
    BTW - for changing the panels, use a [`CardLayout`](http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html) as shown in [this answer](http://stackoverflow.com/a/5786005/418556). – Andrew Thompson Mar 06 '15 at 23:45

1 Answers1

0

Calling repaint() has no effect in your situation because the name set in CharacterDetailsPanel is evaluated during construction of CharacterDetailsPanel so your else branch can never be executed. Instead you could store the JLabel where you set the image as a member and update the image when calling setName.

tomse
  • 501
  • 2
  • 7