Results 1 to 8 of 8
  1. #1
    Psyclone is offline Member
    Join Date
    Jan 2010
    Posts
    81
    Rep Power
    0

    Default Help with Listener and final

    I have an array that I'm having trouble with. The array named newList has data I'm trying to access. Everything is fine when I use it within the method until I try to use it with a Listener.

    I get an error "local variable newList is accessed from within inner class; needs to be declared final."

    If I try to make the local variable final...

    Java Code:
    final PlayerProperties[] newList = new PlayerProperties[8];
    newList = game.getPlayerList();
    ...then I get an error on the following line when I try to get the array stating "can't assign a value to a final variable newList."

    NetBeans offers about 20 possible solutions to Surround with... or Introduce with... and I have no clue what those mean or whether I should be doing it or not.

    Is there a way for me to get around this issue?

    I highlighted the lines of code that seem to be the issue. The line of code in green work fine, but the line in red is the one causing my dilemna.

    I plan on accessing this array several times throughout my code in a similar manner and need to find a way to handle this.

    Java Code:
    newList = game.getPlayerList();
    Java Code:
    public class LobbyGUI {
    
        static int playerNumber = 1;
    
        private static void createAndShowLobbyGUI(GameArray game) {
    [COLOR="Blue"][B]        PlayerProperties[] newList = new PlayerProperties[8];
            newList = game.getPlayerList();[/B][/COLOR]
    
            //Create and set up the window.
            JFrame lobbyFrame = new JFrame("Welcome to ...");
            lobbyFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            lobbyFrame.setLayout(null);
            lobbyFrame.setSize(1280, 768);
            lobbyFrame.setVisible(true);
    
            // Panels
            final JPanel lobbyPlayersInLobbyPanelTop = new JPanel();
            final JPanel lobbyPlayersInLobbyPanelLeft = new JPanel();
            final JPanel lobbyPlayersInLobbyPanelCenter = new JPanel();
            final JPanel lobbyPlayersInLobbyPanelRight = new JPanel();
            final JPanel lobbyPlayersInLobbyPanelBottom = new JPanel();
    
            // Labels
            final JLabel lobbyOpponentNameLabel = new JLabel("", JLabel.CENTER);
            final JLabel lobbyPlayerNameLabel = new JLabel("Psyclone", JLabel.CENTER);
            final JLabel lobbyPlayersInLobbyLabel = new JLabel("Players in Lobby", JLabel.CENTER);
            ...
    
            // Buttons
            ...
    
            // Radio Buttons
            ...
    
            // Text Area
            ...
    
            //Text Field
            ...
    
        // LEFT PANEL (Lobby)
            lobbyFrame.add(lobbyPlayersInLobbyPanelLeft);
            lobbyPlayersInLobbyPanelLeft.setLayout(null);
            lobbyPlayersInLobbyPanelLeft.setOpaque(true);
            lobbyPlayersInLobbyPanelLeft.setBackground(new Color(0, 0, 0));
            lobbyPlayersInLobbyPanelLeft.setPreferredSize(new Dimension(160, 648));
            size = lobbyPlayersInLobbyPanelLeft.getPreferredSize();
            lobbyPlayersInLobbyPanelLeft.setBounds(0, 120, size.width, size.height);
    
            // Players In Lobby Label
            lobbyPlayersInLobbyLabel.setLayout(null);
            lobbyPlayersInLobbyLabel.setOpaque(false);
            lobbyPlayersInLobbyLabel.setBackground(new Color(0, 0, 0));
            lobbyPlayersInLobbyLabel.setPreferredSize(new Dimension(160, 30));
            size = lobbyPlayersInLobbyLabel.getPreferredSize();
            lobbyPlayersInLobbyLabel.setBounds(0, 0, size.width, size.height);
            lobbyPlayersInLobbyLabel.setFont(new Font("Tahoma", Font.BOLD, 18));
            lobbyPlayersInLobbyLabel.setForeground(Color.red);
            lobbyPlayersInLobbyPanelLeft.add(lobbyPlayersInLobbyLabel);
    
            // Lobby List
            String[] lobbyPlayersInLobby = {"Player1", "Player2", "Player3", "Player4", "Player5"};
            JList lobbyPlayersInLobbyList = new JList(lobbyPlayersInLobby);
            lobbyPlayersInLobbyList.setLayout(null);
            lobbyPlayersInLobbyList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
            lobbyPlayersInLobbyList.setBackground(new Color(221, 215, 173));
            lobbyPlayersInLobbyList.setPreferredSize(new Dimension(140, 438));
            size = lobbyPlayersInLobbyList.getPreferredSize();
            lobbyPlayersInLobbyList.setBounds(10,30, size.width, size.height);
            lobbyPlayersInLobbyList.setFont(new Font("Tahoma", Font.PLAIN, 16));
            lobbyPlayersInLobbyList.setForeground(Color.black);
            lobbyPlayersInLobbyPanelLeft.add(lobbyPlayersInLobbyList);
    
            // Lobby List (Listener)
                    ListSelectionListener listSelectionListener = new ListSelectionListener() {
                    public void valueChanged(ListSelectionEvent listSelectionEvent) {
                        boolean adjust = listSelectionEvent.getValueIsAdjusting();
                        if (!adjust)
                            {
                            JList list = (JList) listSelectionEvent.getSource();
                            String name = (String) list.getSelectedValue();
                            lobbyOpponentNameLabel.setText(name);
                            if(name.equalsIgnoreCase(lobbyPlayerNameLabel.getText()))
                                {
                                // IF player chooses his own name from list
                                System.out.println("List - same as player's name)");
                                lobbyChallengeButton.setEnabled(false);
                                }
                            else
                                {
                                System.out.println("List - opponent's name");
                                lobbyChallengeButton.setEnabled(true);
                                [B][COLOR="Red"]lobbyPlayerWon.setText(""+newList[playerNumber].getPlayerName());[/COLOR][/B]
                                }
                            }
                        }
                    };
                    lobbyPlayersInLobbyList.addListSelectionListener(listSelectionListener);
    
        ...
    
        // RIGHT PANEL (Lobby)
            lobbyFrame.add(lobbyPlayersInLobbyPanelRight);
            lobbyPlayersInLobbyPanelRight.setLayout(null);
            lobbyPlayersInLobbyPanelRight.setOpaque(true);
            lobbyPlayersInLobbyPanelRight.setBackground(new Color(0, 0, 0));
            lobbyPlayersInLobbyPanelRight.setPreferredSize(new Dimension(160, 648));
            size = lobbyPlayersInLobbyPanelRight.getPreferredSize();
            lobbyPlayersInLobbyPanelRight.setBounds(1120, 120, size.width, size.height);
    
            // Player's Name Label
            lobbyPlayerNameLabel.setLayout(null);
            lobbyPlayerNameLabel.setOpaque(true);
            lobbyPlayerNameLabel.setBackground(new Color(0, 0, 0));
            lobbyPlayerNameLabel.setPreferredSize(new Dimension(160, 30));
            size = lobbyPlayerNameLabel.getPreferredSize();
            lobbyPlayerNameLabel.setBounds(0, 468, size.width, size.height);
            lobbyPlayerNameLabel.setFont(new Font("Veranda", Font.BOLD, 20));
            lobbyPlayerNameLabel.setForeground(Color.yellow);
            [COLOR="Green"][B]lobbyPlayerNameLabel.setText(newList[playerNumber].getPlayerName());[/B][/COLOR]
            lobbyPlayersInLobbyPanelRight.add(lobbyPlayerNameLabel);
    
        ...
    
        }
    
        public static void main(String[] args) throws FileNotFoundException, BiffException, IOException, WriteException {
    
            Random randomGenerator = new Random();
            int randomMap = randomGenerator.nextInt(695)+1;
    
            final GameArray game = new GameArray();
    
            game.buildMapArray(randomMap);
            game.buildMasterArray();
            game.buildSilverAndGoldArrays(1,2);
            game.buildPlayerArray();
    
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowLobbyGUI(game);
                }
            });
    
        }
    }

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,086
    Rep Power
    20

    Default

    An inner class, like the listener you're creating, needs to know that external (to itself) variables it uses are not going to change their references. Now, taking the local variable you have, if it's not declared final it could be changed (as you have in your snippet in fact) to reference a different array...which would completely throw the runtime, and hence is flagged as a compiler error.

    I probably haven't explained that terribly well...:)

    Anyway, try this:

    final PlayerProperties[] newList = game.getPlayerList();

    Another thing is, you have a hell of a lot of stuff going on inside there. You probably ought to think about breaking it down a bit. For the listener, have it call a method that does the work, rather than having all the work splurged inside that inner class...

    Also, create a gui class of some sort that actually does all this, and manages the front end. An instance of this will do the creation stuff and manage all the listener work as well. Helps to tidy things up a bit.

  3. #3
    Psyclone is offline Member
    Join Date
    Jan 2010
    Posts
    81
    Rep Power
    0

    Default Question about Listeners example from Sun

    In the following code, how does the Action Listener method know which action it is listening for? To clarify, in the example below, if I added a 2nd combo box to the pane, how would I create a different Action Listener for it?

    Java Code:
    package components;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    /*
     * ComboBoxDemo.java uses these additional files:
     *   images/Bird.gif
     *   images/Cat.gif
     *   images/Dog.gif
     *   images/Rabbit.gif
     *   images/Pig.gif
     */
    public class ComboBoxDemo extends JPanel
                              implements ActionListener {
        JLabel picture;
    
        public ComboBoxDemo() {
            super(new BorderLayout());
    
            String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" };
    
            //Create the combo box, select the item at index 4.
            //Indices start at 0, so 4 specifies the pig.
            JComboBox petList = new JComboBox(petStrings);
            petList.setSelectedIndex(4);
            petList.addActionListener(this);
    
            //Set up the picture.
            picture = new JLabel();
            picture.setFont(picture.getFont().deriveFont(Font.ITALIC));
            picture.setHorizontalAlignment(JLabel.CENTER);
            updateLabel(petStrings[petList.getSelectedIndex()]);
            picture.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
    
            //The preferred size is hard-coded to be the width of the
            //widest image and the height of the tallest image + the border.
            //A real program would compute this.
            picture.setPreferredSize(new Dimension(177, 122+10));
    
            //Lay out the demo.
            add(petList, BorderLayout.PAGE_START);
            add(picture, BorderLayout.PAGE_END);
            setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
        }
    
        /** Listens to the combo box. */
    [COLOR="Red"][B]    public void actionPerformed(ActionEvent e) {
            JComboBox cb = (JComboBox)e.getSource();
            String petName = (String)cb.getSelectedItem();
            updateLabel(petName);
        }[/B][/COLOR]
    
        protected void updateLabel(String name) {
            ImageIcon icon = createImageIcon("images/" + name + ".gif");
            picture.setIcon(icon);
            picture.setToolTipText("A drawing of a " + name.toLowerCase());
            if (icon != null) {
                picture.setText(null);
            } else {
                picture.setText("Image not found");
            }
        }
    
        /** Returns an ImageIcon, or null if the path was invalid. */
        protected static ImageIcon createImageIcon(String path) {
            java.net.URL imgURL = ComboBoxDemo.class.getResource(path);
            if (imgURL != null) {
                return new ImageIcon(imgURL);
            } else {
                System.err.println("Couldn't find file: " + path);
                return null;
            }
        }
    
        /**
         * Create the GUI and show it.  For thread safety,
         * this method should be invoked from the
         * event-dispatching thread.
         */
        private static void createAndShowGUI() {
            //Create and set up the window.
            JFrame frame = new JFrame("ComboBoxDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            //Create and set up the content pane.
            JComponent newContentPane = new ComboBoxDemo();
            newContentPane.setOpaque(true); //content panes must be opaque
            frame.setContentPane(newContentPane);
    
            //Display the window.
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,086
    Rep Power
    20

    Default

    You'd need to figure out which was the source, comparing the source object with your combo boxes, for example.

    However, the way you've written it above, with an inner class, is the normal way of doing these things. That way you have one listener for each thing you're listening on.

  5. #5
    Psyclone is offline Member
    Join Date
    Jan 2010
    Posts
    81
    Rep Power
    0

    Default

    I'm so confused. First of all, I couldn't get...

    Java Code:
    final PlayerProperties[] newList = game.getPlayerList();
    ...to work.

    Another thing is, you have a hell of a lot of stuff going on inside there. You probably ought to think about breaking it down a bit. For the listener, have it call a method that does the work, rather than having all the work splurged inside that inner class...

    However, the way you've written it above, with an inner class, is the normal way of doing these things. That way you have one listener for each thing you're listening on.
    You lost me here. It sounds like you're contradicting yourself to me. I know this is not the case... I just don't understand what you mean.

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Psyclone View Post
    I'm so confused.
    You lost me here. It sounds like you're contradicting yourself to me. I know this is not the case... I just don't understand what you mean.
    What he means is to add a method call in the anonymous listener's method and call your code in this method. For instance with an action listener:

    Java Code:
    import java.awt.event.*;
    import javax.swing.*;
    
    public class FuSwing1 {
      private JPanel mainPanel = new JPanel();
    
      public FuSwing1() {
        JButton button = new JButton("Press Me");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            buttonActionPerformed(e);  // action listener's actionPerformed calls the method.
          }
        });
      }
    
      // this method is in the main class
      private void buttonActionPerformed(ActionEvent e) {
        // .... all the code that you want to run when button is pressed goes here
      }

  7. #7
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,086
    Rep Power
    20

    Default

    Yep.
    It makes it a lot easier to maintain if the code that actually handles the event is in its own method.

    Though it would, of course, in real life have a meaningful name...:)

  8. #8
    Psyclone is offline Member
    Join Date
    Jan 2010
    Posts
    81
    Rep Power
    0

Similar Threads

  1. Tab Listener
    By teckno101 in forum AWT / Swing
    Replies: 2
    Last Post: 09-29-2009, 09:40 PM
  2. [SOLVED] is final class members are also final ?
    By haoberoi in forum New To Java
    Replies: 4
    Last Post: 11-10-2008, 03:01 PM
  3. Regarding Listener
    By adeeb in forum AWT / Swing
    Replies: 2
    Last Post: 06-20-2008, 11:07 PM
  4. Regarding Listener
    By adeeb in forum AWT / Swing
    Replies: 2
    Last Post: 06-10-2008, 02:00 AM
  5. Listener for SWT event
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 01-08-2008, 09:04 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •