Search code examples
javajpanelawtjbuttonjtextarea

How to Access textarea from another class?


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!


Solution

  • 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...