Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Clicking on components and letting them know

Status
Not open for further replies.

Chrissirhc

Programmer
May 20, 2000
926
GB
Hello I have problem which I'm not too sure how to solve.

I have a JPanel. Within this JPanel I have x JComponents. Where x is abritrary number. Anyway I have implemented mouseMotionListener so I can handle events in the JComponent when I do something in them say for instance click on one of the circles inside it it goes red. If I click on another circle within that same JComponent the last clicked one goes back to black and the present becomes red. However if I click on another circle in a different JComponent there will be two red ones. One in each JComponent.
I would like for the JPanel to know when a different JComponent is clicked on but as the mouseListener is in the JComponent class it won't know which JComponent has been clicked on. My JComponents are in a vector in the JPanel.

Chris
 
> I would like for the JPanel to know when a different JComponent is clicked
> I'm not too sure how to solve.

There are many ways to do it.

> My JComponents are in a vector in the JPanel

You can't have a vector in a JPanel, I guess you mean a subclassed JPanel? I will call it MyPanel.

Give it a member function something like this:
public void onCircleClick( MyComponent o){
// do what ever you need to with 'o' or even other
// components in the Vector
}

Then pass the MyPanel reference to each MyComponent instance by providing it as a constructor argument and call the MyPanel.onCirclClick() member in the mouseListener event handler, i.e.:

class MyComponent extends JComponent{
private MyPanel _owner = null;
public MyComponent( MyPanel owner){
_owner = owner;
// what ever else you need to do in the constructor
}

public mouseEvent( MouseEvent e){
// do whatever this component does
_owner.onCircleClick(this);
}
}

Hope this helps
-pete
 
yes MyClass extends JPanel

I didn't really want to do it like that pass a i.e pass reference to the JComponent everytime a new one is made I should have made that clear from beggining. I think that is meant to be bad for encapsulation. It would mean that I would have to call method in the Music sheet class to deal with it being clicked.
I think that I may be able to add mouse listener to the JPanel and then when I click I can use getComponent to see which component is clicked on. Hopefully this won't interfere with the mouse listener on the JComponent. If you have any other ideas I'd be grateful

Thanks
Chris
 
I tried doing the adding the mouse Listener to the JPanel however I think that the JComponent has taken mouse listener off the stack so JPanel never sees it. How do I put it back on the stack.
 
> I think that is meant to be bad for encapsulation.

I disagree, and, you asked how it could be done but did not mention any criteria. As I previously stated there are many ways. Perhaps what you mean to state is that having 'MyComponent' need to know a method of 'MyPanel' violates 'autonomy'. That is true.

When you design a new class, especially a UI component class, it is certainly reasonable that it needs to inform other classes when events of interest occur. That concept does NOT contradict encapsulation nor autonomy.

Java has a ready-to-use notification technique since 1.0, the interfaces Observer and Observable. You could have your JComponent derivation implement Observable and your JPanel derivation implement Observer. This technique does not violate 'autonomy' since the 'observing' class is not know to 'MyComponent', only that the 'observing' class implements the 'Observer' interface.

One other technique (my favorite) is to design your own interface that goes with 'MyComponent' so that you don't have to deal with the 'generalized' methods of 'Observer/Observable', i.e.:

interface IMyComponentObserver{
abstract public void onCircleClick( MyComponent o);
}

Good luck
-pete
 
Observable is a class not an interface so my JComponent can't implement it. The only way I could see using it was creating an instance of it within the JComponent, and passing it from the JPanel to it when creating the JComponent object.
I don't know how to create an interface the way you are saying. My java knowledge is quite basic. I ended up passing the reference down from the JPanel. I have never heard of autonomy is this bad?.

Chris
 
Chris,

> Observable is a class not an interface

You are so right! My apologies.

> I don't know how to create an interface the way you are saying.

Well you do since I gave you the code. Perhaps you mean you don't know how to implement it?

class MyPanel extends JPanel implements IMyComponentObserver{
// the rest of your class
public void onCircleClick( MyComponent o){
// do what you want in here
}

}

Hope this helps
-pete
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top