runtime ClassCastException

1) I have a class MyWindow that extends JFrame

2) To MyWindow, I add a MyPanel that extends JPanel

3) MyPanel calls addMouseListener(new MyListener() ) in its constructor.

5) In the MyListener class, I have the following method:

class MyListenerextends MouseAdapter

{

publicvoid mouseEntered(MouseEvent event)

{

...

...

/**EXCEPTION**/ MyWindow window = (MyWindow) (event.getComponent().getParent() );

...

}

}

When I roll my mouse into the window, I get a ClassCastException. Why? event.getComponent() returns a Component, and the Component's getParent() method returns a Container, and this is the inheritance hierarchy of JFrame:

Object

-Component

--Container

-Window

Frame

JFrame

Why isn't the Container a MyWindow object?

[1130 byte] By [7studa] at [2007-10-3 9:12:35]
# 1
I think the Container returned by getParent() must be the JFrame's content pane. But if I tack on successive calls to getParent(), I still can't find the JFrame. Is there an easy way to get a JPanel's enclosing JFrame?
7studa at 2007-7-15 4:24:51 > top of Java-index,Java Essentials,New To Java...
# 2

> Why isn't the Container a MyWindow object?

Because that isn't the way that the components are layed out.

The component hierarchy (which isn't related to inheritance hierarchy) in your case looks like this:

MyPanel

javax.swing.JPanel

javax.swing.JLayeredPane

javax.swing.JRootPane

MyWindow

The "graph" shows that MyWindow isn't the parent of MyPanel.

Kaj

kajbja at 2007-7-15 4:24:51 > top of Java-index,Java Essentials,New To Java...
# 3

> I think the Container returned by getParent() must be

> the JFrame's content pane. But if I tack on

> successive calls to getParent(), I still can't find

> the JFrame. Is there an easy way to get a JPanel's

> enclosing JFrame?

Why do you need to get hold of the frame?

kajbja at 2007-7-15 4:24:51 > top of Java-index,Java Essentials,New To Java...
# 4

Ok, 4 calls to getParent() found the JFrame (I stopped at 3 before). I don't understand the JPanel in the *component* hierarchy? There's a JPanel that contains MyPanel? Why not a JFrame containing MyFrame? And, where is the content pane? After all that is what we add components to.

> Why do you need to get hold of the frame?

To dispose() it. Alternatively, I could move MyPanel and MyListener into MyFrame and declare them as private inner classes. I just started coding it as separate classes, so I was trying to use the event object to get the JFrame.

7studa at 2007-7-15 4:24:51 > top of Java-index,Java Essentials,New To Java...
# 5

> And, where is the content pane? After all

> that is what we add components to.

Guess what. The content pane is a JPanel.

>

> > Why do you need to get hold of the frame?

>

> To dispose() it. Alternatively, I could move MyPanel

> and MyListener into MyFrame and declare them as

> private inner classes. I just started coding it as

> separate classes, so I was trying to use the event

> object to get the JFrame.

Make the frame implement an interface. Make the panel take that interface as argument, and call dispose on the interface.

Kaj

kajbja at 2007-7-15 4:24:51 > top of Java-index,Java Essentials,New To Java...
# 6

> > And, where is the content pane? After all

> > that is what we add components to.

>

> Guess what. The content pane is a JPanel.

>

Wow. I can't find anything in the whole wide world that mentions that. But I can confirm it with some code:

JFrame window = new JFrame("title");

Container cpane = window.getContentPane();

Class objType = cpane.getClass();

System.out.println(objType.getName()) //javax.swing.JPanel

For future seekers, my component hierarchy is:

MyWindow

|

JRootPane

|

JLayeredPane

|

contentPane (JPanel)

|

MyPanel

That's why it took four calls to getParent() to arrive at MyWindow:MyWindow window =

(MyWindow) event.getComponent().getParent().getParent().getParent().getParent();

>

> Make the frame implement an interface. Make the panel

> take that interface as argument, and call dispose on

> the interface.

>

> Kaj

You mean pass the frame to the panel constructor and in the panel pass the frame to the MyListener constructor? The disposing happens in mouseEntered(). What does the interface do?

7studa at 2007-7-15 4:24:51 > top of Java-index,Java Essentials,New To Java...
# 7

> You mean pass the frame to the panel constructor and

> in the panel pass the frame to the MyListener

> constructor? The disposing happens in

> mouseEntered(). What does the interface do?

It reduces the coupling.

A better choice is atually to read about MVC. It explains how to split your code so that it becomes more modular.

Kaj

kajbja at 2007-7-15 4:24:51 > top of Java-index,Java Essentials,New To Java...