-1

I have a little bit of a problem here with MouseListeners. I am trying to add multiple JLabels to a JFrame and that works perfectly fine. The problem is that I also want to add MouseListeners to each of the JLabels. But it doesn't want to work this way, because it is complaining about the variable not being final. Can anyone help me with this?

It is complaining at the part inside the mouseEntered and the mouseExited functions. In eclipse the variable button there gets highlighted and it says the variable needs to be a final variable.

The code:

public class OperatingScreen {

public String ride;

public static JFrame frame = new JFrame();
private static JPanel panel = new JPanel();
private static JPanel button_panel = new JPanel();
private static JLabel bg = new JLabel();


public OperatingScreen(String ride){
    this.ride = ride;

    frame.setTitle("Operating: " + ride);
    panel.setLayout(null);

    frame.add(panel);
    frame.pack();
    frame.setResizable(false);
    frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
    frame.setVisible(true);
    bg.setIcon(createImageIcon("/background_operating.png", "background"));
    bg.setBounds(1280, 720, 0, 0);
    frame.add(bg);

    //buttons.setBounds(100, 500, 1080, 40);
    frame.setSize(1280, 720);

    SocketHandler.initializeride(ride);
}


public void Initialize(String init){
    String buttons2 = init.split("\\*")[1];
    String[] buttons = buttons2.split("\\|");

    for(int i = 2; i < buttons.length; i++){

        String text = buttons[i].split("\\>")[0];
        String color = buttons[i].split("\\>")[1].substring(0, 1).toUpperCase() + buttons[i].split("\\>")[1].substring(1);;

        JLabel button = new JLabel();
        button.setIcon(createImageIcon("/Button" + color + ".png", "blue"));
        button.setText(text);
        button.setForeground(Color.BLACK);
        button.setFont(button.getFont().deriveFont(17.0f));
        button.setBorder(LineBorder.createBlackLineBorder());
        button_panel.add(button);
        button.addMouseListener(new MouseListener(){

            public void mouseClicked(MouseEvent arg0) {}
            public void mouseEntered(MouseEvent arg0) {
                //button.setIcon(createImageIcon("/Button" + color + ".png", "choose"));
            }
            public void mouseExited(MouseEvent arg0) {
                //button.setIcon(createImageIcon("/Button" + color + ".png", "choose"));
            }
            public void mousePressed(MouseEvent arg0) {}
            public void mouseReleased(MouseEvent arg0) {}
        });

        JOptionPane.showMessageDialog(HomeScreen.frame, text + "    " + color);
    }

    JScrollPane jop = new JScrollPane(button_panel, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    jop.setBounds(100, 500, 1080, 60);
    jop.setBorder(null);

    panel.add(jop);
    jop.setOpaque(false);
    jop.getViewport().setOpaque(false);

    panel.setSize(1280, 720);
    panel.setOpaque(false);
    button_panel.setOpaque(false);
}





protected ImageIcon createImageIcon(String path,
        String description) {
        URL imgURL = getClass().getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
}
}
  • 2
    So, why don't you just make them final? – Seelenvirtuose May 05 '15 at 17:58
  • @Seelenvirtuose I did try this, but then the JLabels dissapeared from the frame. They were just gone. – Ciaran Lichtenberg May 05 '15 at 18:00
  • 2
    By making a variable final? No, that can't be. – Seelenvirtuose May 05 '15 at 18:01
  • @Seelenvirtuose I will try it again, but it last time it really didn't work... – Ciaran Lichtenberg May 05 '15 at 18:03
  • @CiaranLichtenberg Can you include in your question the code you've tried ? – NiziL May 05 '15 at 18:04
  • Additionally: You obviuosly get a compiler error. But you neither told us the exact error nor did you tell us the exact line where you have that error. This makes your question a bad one. It is only our experience that we can directly spot the mistake. – Seelenvirtuose May 05 '15 at 18:04
  • @Seelenvirtuose Okay this is strange, I commented out those two problem lines inside the functions and they still don't appear on the frame. – Ciaran Lichtenberg May 05 '15 at 18:05
  • If "last time it really didn't work" (whatever that means), it was not because a variable was final. This is impossible. – Seelenvirtuose May 05 '15 at 18:05
  • @Seelenvirtuose I looked if I could see a compiler error, but I don't see any error? – Ciaran Lichtenberg May 05 '15 at 18:06
  • possible duplicate of [Why are only final variables accessible in anonymous class?](http://stackoverflow.com/questions/4732544/why-are-only-final-variables-accessible-in-anonymous-class) – Seelenvirtuose May 05 '15 at 18:07
  • @Nizil I have updated my post to the entire code I have in this class. – Ciaran Lichtenberg May 05 '15 at 18:08
  • How could you not "see any error"? In your question you said "it is complaining about the variable not being final". Whatever you meant with "it", what do you think that message is? Come on. You have to tell us your exact problems, not those vague explanations. – Seelenvirtuose May 05 '15 at 18:08
  • @CiaranLichtenberg Seelenvirtuose was speaking about compiler errors you get when uncommenting the "two problems lines" :) – NiziL May 05 '15 at 18:09
  • @Seelenvirtuose I'm sorry that i'm maybe a bit vague in my explanation, but I'm really trying to understand what the problem is. My question has changed a bit right now, because I found out that the final is indeed not the problem. I am going to try some things myself now to see if I can solve it. What I do not know now is why it isn't giving me any compiler error, while the JLabels do not show up in the frame. Edit: I changed my code in the post, so you can see the entire class now. – Ciaran Lichtenberg May 05 '15 at 18:13

3 Answers3

0

What you are doing here

button.addMouseListener(new MouseListener(){

            public void mouseClicked(MouseEvent arg0) {}
...

is creating an anonymous class. It has the same restriction, as local classes do: they can't access local variables, if they are not final or effectively final. However, it can freely access to the enclosing class variables.

So, to access a variable (as I may see, it's color) you need either to make it class variable, not local one (local variable is the variable you've created in a loop body, it's for in your code, it is "visible" only inside this loop and is destroyed when you leave it) or to make it final as you are proposed to do.

Changing it like this should make it work:

final String color = buttons[i].split("\\>")[1].substring(0, 1).toUpperCase() + buttons[i].split("\\>")[1].substring(1);

    final JLabel button = new JLabel();

P.S. String color = buttons[i].split("\\>")[1].substring(0, 1).toUpperCase() + buttons[i].split("\\>")[1].substring(1);; - I think, one ; should be enough.

Mugi4ok
  • 285
  • 2
  • 5
  • 15
0

It looks like you are trying to handle mouseEntered and mouseExited to change the Icon on the label.

Instead of using a JLabel you can use a JButton and take advantage of the default rollover functionality. You can make the button look like a label:

JButton button = new JButton(...);
button.setRolloverEnabled(true);
button.setRolloverIcon(...);
button.setBorderPainted( false );
button.setContentAreaFilled(false);
button.setFocusPainted(false);
camickr
  • 321,443
  • 19
  • 166
  • 288
0

Okay thank you all for commenting and answering. I found out what the problem is, now I just have to try and solve it. The problem was that the buttons were added, but they are not on top of the screen. For some reason the background is hiding the JLabels underneath.