main class:
public class tuna {
public static void main(String[] args) {
JFrame frame1 = new JFrame();
frame1.setVisible(true);
frame1.add(new apple());
frame1.setSize(200 , 240);
}
}
2nd class
public class apple extends JPanel{
JTextArea ta = new JTextArea();
Border blackline = BorderFactory.createLineBorder(Color.black);
apple(){
setBorder(blackline);
System.out.println("apple");
ta.setText("hello");
ta.setEditable(false);
add(ta);
add(new doctor());
repaint();
revalidate();
}
}
3rd class
public class doctor extends JPanel implements ActionListener{
public JButton butt = new JButton("change");
Border blackline = BorderFactory.createLineBorder(Color.black);
public doctor(){
setBorder(blackline);
add(butt);
}
@Override
public void actionPerformed(ActionEvent e){
if(e.getSource() == butt)
{
System.out.println("she");
}
}
}
Why everytime the button is pressed it wont print "she" in the console. I need my program to change the text inside the text area every time the button is pressed. for example when I pressed the button it should append "world" in the text area please help me!
Think about this, who is responsible for updating the JTextArea
, apple
or doctor
?
If you answered apple
then you're right, apple
should maintain control over the component and control access to it.
In extension, doctor
has no reason to know or care about apple
or what it can do, it just needs the ability to provide notification to interested parties that some condition has changed, it should not care what other classes do with that information, as it's beyond the scope of its general responsibility.
This is a classic example of an Observer Pattern, where one (or more) interested parties observe changes to another and take action upon them.
Now, the question is, how to best achieve this? There are a number of solutions, you could roll your own listener interface
, you could use a pre-existing listener, like ChangeListener
or you could use the inbuilt functionality provided by the components. Which you choose will depend on your requirements, to keep it simple, I'm using the last one...
When you create an instance of doctor
, you can add a PropertyChangeListener
to it...
doctor doc = new doctor();
doc.addPropertyChangeListener("change", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Object newValue = evt.getNewValue();
if (newValue instanceof String) {
ta.setText(newValue.toString());
} else if (newValue == null) {
ta.setText(null);
}
}
});
add(doc);
In your butt
ActionListener
, you would trigger a PropertyChangeEvent
...
@Override
public void actionPerformed(ActionEvent e){
if(e.getSource() == butt)
{
// If you want to, you could pass the "old" value
firePropertyChange("change", null, "she");
}
}
As one possible example...