Search code examples
javaswingtry-catchmouselistenerthrow

Mouse listener using throw/catch (java)


I have the following code in a file called Test2.java in a package called test2;

package test2;

import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class Test2 {
    public static void main(String[] args) {
        int k = 7;
        while(true) {
            try {
                JFrame mainWindow = new HtmlWindow(k);
            } catch(UnsupportedOperationException numberChosen) {
                JOptionPane.showInternalMessageDialog(null, "information",
                        "You clicked on number " + numberChosen, 
                        JOptionPane.INFORMATION_MESSAGE);
                Integer l = new Integer("0" + numberChosen);
            }
        }
    }
}

I have the following code in a file called HtmlWindow in the same package;

package test2;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;

class HtmlWindow extends JFrame implements MouseListener {
    public HtmlWindow(int k) throws UnsupportedOperationException {
        super("blah");
        setSize(150, 200);
        Container content = getContentPane();
        content.setLayout(new FlowLayout());
        JLabel[] coloredLabel = new JLabel[k];
        String[] labelText = new String[k];
        for(int i=0; i<=k-1; i++) {
            labelText[i] = "<html><img src = "
                + "\"http://images.nycsubway.org/bullets/lines/"
                + (i+1)
                + ".GIF\">"
                + "</html>";
            coloredLabel[i] = new JLabel(labelText[i]);
            coloredLabel[i].setName((i + 1) + " ");
            coloredLabel[i].addMouseListener(this);
            addMouseListener(this);
            content.add(coloredLabel[i]);
        }
        this.setVisible(true);
        while(true) {
        }
    }

@Override
public void mousePressed(MouseEvent me) {
}

@Override
public void mouseReleased(MouseEvent me) {
}

@Override
public void mouseEntered(MouseEvent me) {
}

@Override
public void mouseExited(MouseEvent me) {
}

@Override
public void mouseClicked(MouseEvent me) {
    throw new UnsupportedOperationException(me.getComponent().getName());
}
}

When I run this, a window appears as expected with the number pictures in it, but when I click on any of them the Exception thrown is not caught. Why is this? The pointer should be going around the "while" section in the HTMLWindow constructor, and thus still be within the "try" section, and so should be caught. My guess is that this is because the mouseClicked section is not within the HTMLWindow constructor, the exception is somehow thrown outside of the try block?

If this is not the best way to get information from the GUI back to the original programme, what is? I don't think it's through using "return" because

  • Constructors don't have return types
  • mouseClicked isn't within the Constructor any way

Aside - I don't particularly want the programme to do anything when I move over the numbers etc, just click on them. So why do I need the mousePressed blocks and so on? The programme won't compile without them. Is it okay to just leave them blank like that?


Solution

  • The pointer should be going around the "while" section in the HTMLWindow constructor, and thus still be within the "try" section, and so should be caught.

    It's still within the try block - but clearly that while loop isn't going to throw the exception, is it?

    You appear to be assuming that:

    • The UI is going to be running on a different thread
    • Any exception thrown on the UI thread is somehow going to be marshalled to the thread containing the constructor

    I don't know about the first bullet, but the second definitely isn't correct. (And a tight while(true) loop is never the right solution...)

    If this is not the best way to get information from the GUI back to the original programme, what is?

    It's not really clear what you're trying to achieve, but generally GUIs are "event-oriented" - so perhaps you should be thinking of a way of making the GUI expose some sort of listener that your other code can hook into.

    Aside - I don't particularly want the programme to do anything when I move over the numbers etc, just click on them. So why do I need the mousePressed blocks and so on? The programme won't compile without them. Is it okay to just leave them blank like that?

    Instead of implementing MouseListener directly, use one of the adapter classes (e.g. MouseAdapter), which implements the relevant interface, providing no-op implementations for you. But obviously you can't make your window extend MouseAdapter and JFrame - you should have two separate classes here.