-1

I have a GUI with about 26 different labels, but would like to be able to execute the same code for all of them when clicked, so I figured I would use a MouseListener and mouseClicked method to execute the code. The problem I'm having is that when I click on any of the labels, I get this error:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JRootPane cannot be cast to javax.swing.JLabel
at dealornodeal.ui.DealOrNoDealUI.mouseClicked(DealOrNoDealUI.java:628)
at java.awt.Component.processMouseEvent(Component.java:6528)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3322)
at java.awt.Component.processEvent(Component.java:6290)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4881)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4542)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:751)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:702)
at java.awt.EventQueue$3.run(EventQueue.java:696)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:724)
at java.awt.EventQueue$4.run(EventQueue.java:722)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:721)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

I can see that the mouseClicked() method is returning a JRootPane component instead of a JLabel component, and a JRootPane apparently can't be cast to a JLabel. My question is, how to I get the JLabel component when using the mouseClicked() method, instead of a JRootPane?

Here is my code where I'm adding a MouseListener to all the JLabels and then trying to execute code on mouseClicked():

public DealOrNoDealUI() {
    initComponents();
    this.setLocationRelativeTo(null);
    this.components = this.getComponents();

    for(Component component : this.components){
        component.addMouseListener(this);
    }
}

public void mouseClicked(MouseEvent e) {
    Component clickedComponent = e.getComponent();
    JLabel clickedLabel = (JLabel) clickedComponent;

    if(this.game.getPlayer().getPlayerCase() == null){
        for(Case gameCase : this.game.getCases()){
            if(gameCase.getCaseNumber() == Integer.parseInt(clickedLabel.getText())){
                this.game.getPlayer().setPlayerCase(gameCase);
            }
        }
    }
}

I'm using a null layout for the GUI.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
James F
  • 94
  • 12
  • *"I have a GUI with about 26 different labels, but would like to be able to execute the same code for all of them when clicked, so I figured I would use a MouseListener and mouseClicked method to execute the code."* First of all, use 26 (possibly undecorated) buttons with a single `ActionListener`. Buttons can be focused, and can accept keyboard entry as well as mouse clicks. – Andrew Thompson May 11 '15 at 04:34
  • *"I'm using a null layout for the GUI."* Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson May 11 '15 at 04:35

1 Answers1

3

for(Component component : this.components){ this is the root of your problems and I assume you're adding your "labels" to a JFrame, which would account for the class cast exception.

A JFrame (and most top level Swing containers) contains a JRootPane, which contains the contentPane, mennuBar and glassPane...

Rootpane

Basically, you've picked up the JRootPane (been the only actual direct child of the JFrame) and added your MouseListener to it.

Without knowning how you're establishing the UI, it's impossible to make an accurate suggest, but in most times, you would either have a factory method which created the labels, which is used to do the basic initialisation and configuration, returning the instance of the JLabel

protected JLabel makeLabel(String text) {
    JLabel label = new JLabel(text);
    label.addMouseListener(someInstanceOfAMouseListener);
    return label;
}

Then you could just call this method and have the label, basically, auto generated.

Another alternative, is to place all your labels into an array or list and use a for-loop to manage them

private JLabel[] listOfLabels;
//...
listOfLabels = new JLabel[count];
for (int index = 0; index < count; index++) {
    listOfLabels[index] = new JLabel(...);
    listOfLabels[index].addMouseListener(someInstanceOfAMouseListener);
}

Or a combination thereof...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I already have the labels created using a GUI builder, as I needed them to be placed in exact positions, but I can't figure out how to add them to the array of JLabels, as iterating over all the components and filtering out the JLabels doesn't seem to work. – James F May 11 '15 at 04:30
  • Well, then you're going to have to add the `MouseListener` to each one individually. You can create an array using something like `JLabel listOfLabels[] = new JLabel[]{label1, label2, ...};` – MadProgrammer May 11 '15 at 04:31