0

I have been trying to pass the info of my JTextField that is in a JDialog into my JFrame. Both the JDialog and JFrame are in separate classes. I have tried to store the JTextField into a JLable using the .setText and .getText and then passing the JLable into the JFrame but with no luck.

I know there are many similar questions but I have tried many different approaches but still no luck. I am relatively new to Java and do not know all the in's and out's. Any help is very appreciated!

My code for the JFrame:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JPanel;

public class StockApp extends JFrame implements PropertyChangeListener {

    private JPanel main = new JPanel();
    private JPanel north = new JPanel();
    private JPanel center = new JPanel();
    private JPanel south = new JPanel();
    private JButton buyStock = new JButton("Buy Stock");
    private JButton sellStock = new JButton("Sell Stock");
    public TestTest variables = new TestTest();
    private JLabel stockNameNorth = new JLabel("Stock Name");
    private JLabel stockPriceNorth = new JLabel("Stock Price");
    String stockName = variables.getStockName();
    String stockPrice = variables.getStockPrice();

    public StockApp() {
        setTitle("StockApp");
        getContentPane().setBackground(Color.white);
        setSize(400,400);
        setLocation(500,200);
        setVisible(true);
        main.setLayout(new BorderLayout());
        north.setLayout(new FlowLayout());
        center.setLayout(new FlowLayout());
        south.setLayout(new FlowLayout());
        stockNameNorth.setText(stockName);
        stockPriceNorth.setText(stockPrice);
        add(main);
        north.add(stockNameNorth);
        north.add(stockPriceNorth);
        south.add(buyStock);
        south.add(sellStock);
        main.add(north, BorderLayout.NORTH);
        main.add(center, BorderLayout.CENTER);
        main.add(south, BorderLayout.SOUTH);
    }
}

And Dialog:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestTest extends JDialog implements ActionListener {

private JPanel main = new JPanel();
    private JPanel north = new JPanel();
    private JPanel center = new JPanel();
    private  JPanel south = new JPanel();
    private JLabel stockNameLabel = new JLabel("Stock name: ");
    private JLabel stockPriceLabel = new JLabel("Stock price(£): ");
    private JTextField stockNameIn = new JTextField(5);
    private JTextField stockPriceIn = new JTextField(5);
    private JButton buttonOK = new JButton("OK");
    public JLabel stockPrice = new JLabel();
    public JLabel stockName = new JLabel();

    public TestTest() {
        getContentPane().setBackground(Color.white);
        setSize(400,400);
        setLocation(500,200);
        setModal(false);
        setVisible(true);
        getRootPane().setDefaultButton(buttonOK);
        main.setLayout(new BorderLayout());
        north.setLayout(new FlowLayout());
        center.setLayout(new FlowLayout());
        south.setLayout(new FlowLayout());
        add(main);
        north.add(stockNameLabel);
        north.add(stockNameIn);
        center.add(stockPriceLabel);
        center.add(stockPriceIn);
        south.add(buttonOK);
        main.add(north, BorderLayout.NORTH);
        main.add(center, BorderLayout.CENTER);
        main.add(south, BorderLayout.SOUTH);
        buttonOK.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == buttonOK){
            stockName.setText(stockNameIn.getText());
            stockPrice.setText(stockPriceIn.getText());
            dispose();
            new StockApp();
            }
        }
    public String getStockName() {
        return stockNameIn.getText();
    }
    public String getStockPrice() {
        return stockPriceIn.getText();
    }
}    

I am trying to pass the stockName and stockPrice variables from the JDialog into the JFrame. I then want the name and price to display at the top of the JFrame.

STaefi
  • 4,297
  • 1
  • 25
  • 43
Tony
  • 13
  • 1
  • a) create and show the dialog. b) use getters to retreive values c) create the frame and set these values? – Jan Mar 06 '18 at 12:59
  • Hi, I tried that and got the following error. Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException – Tony Mar 06 '18 at 13:19
  • There is no main method, to start your program, so everybody who is willing to help has to write his own. Then there are much too many elements, not needed to demonstrate your problem. Reduce your problem to the core minimum to reproduce it. – user unknown Mar 06 '18 at 22:40

1 Answers1

-1

For demonstration, what the problem is, we need less Fields and Buttons.

So far, no component of StockApp needs to be accessed from different methods, so there is no need to make them visible outside of the ctor.

More explanations in the code.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;

public class StockApp extends JFrame {

    public StockApp() {
        // move those unreferenced panels here, so we don't have to reason about them:
        JPanel main = new JPanel();
        JPanel north = new JPanel();
        JPanel center = new JPanel();
        JPanel south = new JPanel();
        // add price later, when name works
        JButton buyStock = new JButton("Buy Stock");
        JLabel stockNameNorth = new JLabel("Stock Name");

        // critical change: Make the label, which you like to update,
        // accessible by whom it should be updated:
        TestTest variables = new TestTest (stockNameNorth);

        setTitle ("StockApp");
        getContentPane().setBackground(Color.white);
        setSize (600,400);
        setLocation (500,200);
        setVisible (true);
        // make the close-frame action terminate the program:
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

        main.setLayout (new BorderLayout());
        north.setLayout (new FlowLayout());
        center.setLayout (new FlowLayout());
        south.setLayout (new FlowLayout());
        add (main);
        north.add (stockNameNorth);
        south.add (buyStock);
        main.add (north, BorderLayout.NORTH);
        main.add (center, BorderLayout.CENTER);
        main.add (south, BorderLayout.SOUTH);
    }

    // Main method to start the damn thing
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new StockApp ();
            }
        });
    }
}

// no need to make this class public in a short test:   
class TestTest extends JDialog implements ActionListener {

    // this are elements, visible outside the construction phase,
    // we need to have access to from more than one method.
    // Make this important distinction visible to the reader: 
    JLabel name;
    JTextField stockNameIn = new JTextField (5);
    JButton buttonOK = new JButton ("OK");

    // add the JLabel to update to the ctor, so that it can't be forgotten
   // to be set
    public TestTest (JLabel pname) {
        // we copy the reference to the label, to have access to it in 
        // the actionPerformed method.
        name = pname;
        JPanel main = new JPanel();
        JPanel north = new JPanel();
        JPanel center = new JPanel();
        JPanel south = new JPanel();
        JLabel stockNameLabel = new JLabel ("Stock name: ");
        getContentPane().setBackground(Color.white);
        // different size/location than frame, so that they don't hide
        // each other completly
        setSize (400,600);
        setLocation (700,300);
        setModal (false);
        setVisible (true);
        getRootPane().setDefaultButton(buttonOK);
        main.setLayout (new BorderLayout());
        north.setLayout (new FlowLayout());
        center.setLayout (new FlowLayout());
        south.setLayout (new FlowLayout());
        add (main);
        north.add (stockNameLabel);
        north.add (stockNameIn);
        south.add (buttonOK);
        main.add (north, BorderLayout.NORTH);
        main.add (center, BorderLayout.CENTER);
        main.add (south, BorderLayout.SOUTH);
        buttonOK.addActionListener(this);
    }

    // here we need access to the button - was it the OK-Button, clicked?    
    // and the textfield stockNameIn, to read the text 
    // and the name field from the frame, to set the text 
    public void actionPerformed(ActionEvent e) {
        if (e.getSource () == buttonOK) {
            name.setText (stockNameIn.getText());
            dispose();
        }
    }
}
user unknown
  • 35,537
  • 11
  • 75
  • 121
  • I recommend you to move `setVisible()` calls after you've added all components to the "main" component. You might find some "race conditions" which could cause weird painting bugs... And also to avoid [extending JFrame](https://stackoverflow.com/questions/22003802/extends-jframe-vs-creating-it-inside-the-program) for the rest I guess I have no clue... – Frakcool Mar 06 '18 at 23:38
  • @Frakcool: This is a demo how to pass a value from one Component to the other, not a full blown Swing-Tutorial. There is nearly nothing, which couldn't be improved, but you have to be somewhat to the point and not clutter the topic with noise. Painting bugs is not the topic here. – user unknown Mar 06 '18 at 23:44
  • While this is a demo, it *should* follow the rules, so we don't have another post about a "painting bug" later related this this code. I'm not trying to clutter the topic with noise but rather provide a higher quality answer. That's it. You may add those edits to your answer or at least I'm leaving my 2 cents here for OP to read what could be improved in your current code. – Frakcool Mar 06 '18 at 23:47
  • @Frakcool: So what rules are you referring to? This demo, does it work or not? Your question is off topic. It's well minded, but has the smell of cargo-cult-programming. While in some circumstances, delaying the 'setVisible' might be helpful, here it isn't, until you can demonstrate it. If there is an issue with 'setVisible', why isn't there a hint in the Javadocs? Either authoritative source, or empiric demonstration. – user unknown Mar 07 '18 at 00:51
  • [Java Docs](https://docs.oracle.com/javase/tutorial/uiswing/components/frame.html) show the steps, where `setVisible` is done last. *"Your question is off topic"* What question? I'm not sure what *"cargo-cult-programming"* term means. Anyway I'm don't plan do be discussing with a close-minded person who get mad for one comment in his answer. Excuse me if I offended you. It wasn't my intention. As I said, I was just trying to make a point that your code could be improved. That's it. – Frakcool Mar 07 '18 at 00:55
  • a) I'm not offended. b) I'm open minded. Please be open minded too and not offended. Your suggestion is off-topic, is that better? c) I'm not getting mad. I'm just asking for the evidence. Please stay on topic and don't get personal insulting. The statements in each Java program are sequential by nature and the order might be important or not. My preposition is: In this case, it is not. From an observation in the Javadocs you can't conclude, that the order is important, or would you claim that 2. couldn't be moved behind 3. or 4.? – user unknown Mar 07 '18 at 01:12
  • This has worked perfectely. I didn't realise it was so simple! Thank you very much for your answer!! – Tony Mar 07 '18 at 10:02