Maintaining OO while using listeners in Java
I have code similar to the following:
public class myButton extends JButton()
{
public int data;
public myButton(){
super("asdf");
data = 2;
}
}
public class myPanel extends MouseListener()
{
myButton myButtonVar1;
myButton myButtonVar2;
public myPanel()
{
myButtonVar1 = new myButton();
myPanel.add(myButtonVar1);
myButtonVar1.addMouseListener(this);
myButtonVar2 = new myButton();
myPanel.add(myButtonVar2);
myButtonVar2.addMouseListener(this);
}
//MouseListener Methods are here
void mouseClicked(MouseEvent e)
{
//say this changes the myButton that was clicked data based off
//the other myButton's data
doSomething((myButton)(e.getSource()).data);
}
}
And then I add that panel to a JFrame via setContentPane.
This works alright. The handler has to have access to all of the buttons, because it needs to know myButtonVar1.data and myButtonVar2.data
This setup doesn't sit right with me, but the main problem is that I have to have other buttons in the frame as well, which access the myButtons.
So how could I clean th开发者_运维问答is up such that I could add something a "resetButton" that would reset all of the myButtons contained in myPanel. The route that stands out to me would be to use instanceof to see if the source is a resetButton or myButton, but that seems to be strongly discouraged in everything i've seen.
I hope I'm not too far off here. My goal is to write good code rather than stick with what I have, so let me know if I have done something fundamentally wrong already and should backtrack.
In general, you can fix your problem by preferring composition over inheritance. Your buttons should not be special class buttons. Instead they should be raw JButton
s. You can create a class that returns a JButton
with the preferred settings and also holds the data, but try not to extend the Swing classes.
For your encapsulation issue, don't make data
public. Instead, have a getData()
getter to get the value as needed.
You won't need to use instanceof. Instead, install two different MouseListeners - one for your MyButton
buttons and one for your ResetButton
buttons. This can be done with external classes or a private inner class that implements MouseListener
. All MyButton
-type buttons will have the one type of listener, while the single ResetButton
will have the other.
Classes should start with an uppercase letter (MyButton instead of myButton). This is a convention.
Fields are usually private, and you only have a getter (myButton.data).
instanceof is seldom required. Instead, you could define a base class with a "press" method. Both classes could then implement it.
精彩评论