Search code examples
javaswingjtextfield

How to pass JTextField from JFrame into another JFrame?


I have two JFrame (JFrame1 and JFrame2) with two JTextField1 and JTextField2. My question is when I write "Hello world " on JTextField2 from Jframe2 and then click on OK button, I see "Hello world " on JTextField1 on Jframe1 class.

How can I do this? I'm sorry if this is a newbie question but I'm learning..

Here is my code:

JFrame2:

private JFrame1 jf1;
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {                                     
    jf1.setjTextField1(this.jTextField2);
} 

Solution

  • You could use an Observer Pattern or Producer/Consumer Pattern to solve the problem.

    The basic idea is, you have something that generates a value and something that either wants to be notified or consume the generated value.

    One of the other prinicples you should take the time to learn is also Code to interface (not implementation). This sounds stranger then it is, but the the idea is to reduce the unnecessary exposure of your objects (to unintended/controlled modifications) and decouple your code, so you can change the underlying implementation without affecting any other code which relies on it

    Given the nature of your problem, an observer pattern might be more suitable. Most of Swing's listener's are based on the same principle.

    We start by defining the contract that the "generator" will use to provide notification of changes...

    public interface TextGeneratorObserver {
    
        public void textGenerated(String text);
    }
    

    Pretty simple. This means we can safely provide an instance of any object that implements this interface to the generator and know that it won't do anything to our object, because the only thing it knows about is the textGenerated method.

    Next, we need something that generates the output we are waiting for...

    public class GeneratorPane extends JPanel {
    
        private TextGeneratorObserver observer;
        private JTextField field;
        private JButton button;
    
        public GeneratorPane(TextGeneratorObserver observer) {
            this.observer = observer;
    
            field = new JTextField(10);
            button = new JButton("OK");
    
            ActionListener listener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    observer.textGenerated(field.getText());
                }
            };
    
            button.addActionListener(listener);
            field.addActionListener(listener);
    
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(2, 2, 2, 2);
    
            add(field, gbc);
            add(button, gbc);
        }
    
    }
    

    This is just a simple JPanel, but it requires you to pass a instance of TextGeneratorObserver to it. When the button (or field) triggers the ActionListener, the ActionListener calls the textGenerated to notify the observer that the text has been generated or changed

    Now, we need someone to observer it...

    public class ObserverPanel extends JPanel implements TextGeneratorObserver {
    
        private JLabel label;
    
        public ObserverPanel() {
            label = new JLabel("...");
            add(label);
        }
    
        @Override
        public void textGenerated(String text) {
            label.setText(text);
        }
    
    }
    

    This is a simple JPanel which implements the TextGeneratorObserver interface and updates it's JLabel with the new text

    Then, we just need to plumb it together

    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    ObserverPanel op = new ObserverPanel();
                    op.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));
                    GeneratorPane pp = new GeneratorPane(op);
                    pp.setBorder(new CompoundBorder(new LineBorder(Color.GREEN), new EmptyBorder(10, 10, 10, 10)));
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridLayout(2, 1));
                    frame.add(pp);
                    frame.add(op);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    

    Observer