0

Here is what is going on with my program,

  1. Run the program, first Jframe pops up (Text Editor).
  2. I click the calculator button and a Jframe pops up (Unit Converter) with 1 button and 1 text field.
  3. I type in a number into the first text field ( Fahrenheit to Celsius), click the Fahrenheit to Celsius button but the conversion does not append to the text area in Text Editor.
  4. I close the "Unit Converter" window, click the calculator button again and the text I entered the first time in the "Fahrenheit to Celsius" field is still there. This second time I click the calculator button, the conversion happens and it gets appended to the text area.

I want the data to be appended to the "Text Editor" textArea once I press the "Fahrenheit to Celsius" button.

I have four different classes (this is the way my professor wanted our project set up) :/ Here is my "Main" Class

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Program p = new Program();
        }

}

Next, here is my "Program" class

import javax.swing.JFrame;

public class Program {

    public Program(){

        TextEditor textEditor = new TextEditor();
        textEditor.setVisible(true);
        textEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Calculator calculator = new Calculator();
        calculator.setVisible(false);
        calculator.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

    }
}

And here is my "TextEditor class" I omitted some of the buttons as those are not what causing any issues.

public class TextEditor extends JFrame implements ActionListener{
JTextArea textArea;
JButton calculatorButton;

Calculator c = new Calculator();

public TextEditor(){
    super("TextMe");
    this.setLayout(new BorderLayout());
    loadMenuBar();
    loadToolBar();
    loadTextArea();
    this.pack();
}

private void loadTextArea() {
    // TODO Auto-generated method stub
    textArea = new JTextArea();
    textArea.setPreferredSize(new Dimension(800,600));
    this.add(BorderLayout.CENTER, textArea);
}

private void loadToolBar() {
    // TODO Auto-generated method stub

    JToolBar toolBar;
// CALCULATOR BUTTON
    calculatorButton = new JButton(new    ImageIcon(this.getClass().getResource("/images/calculator.png")));
    calculatorButton.addActionListener(this);

// TOOL BAR
    toolBar = new JToolBar(JToolBar.HORIZONTAL);
toolBar.add(calculatorButton);
    this.add(BorderLayout.PAGE_START, toolBar);
}

@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    if(e.getSource() == calculatorButton){
            loadCalculator ();

        }
    }

private void loadCalculator() {
    // TODO Auto-generated method stub
    {
    c.setVisible(true);
    c.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    this.setLayout(new FlowLayout());

    }
    if(!c.fToC.getText().isEmpty()){
    textArea.setText(String.valueOf(c.fahrenheit));
    }
}

}

Lastly, here is my "Calculator" class. Again, sorry that there is so much code here.

public class Calculator extends JFrame implements ActionListener{
        JButton fToCButton;
    JTextField fToC;
double fahrenheit;

public Calculator(){
            super("Unit Converter");
            this.setLayout(new FlowLayout());

fToC = new JTextField(5);
fToCButton = new JButton("Ferenheit To Celcius");
fToCButton.addActionListener(this);

add(fToCButton, BorderLayout.WEST);
add(fToC);

this.pack();

@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    if(e.getSource() == fToCButton){
    degreeConversion(); 

}

}

    public void degreeConversion() {
    // TODO Auto-generated method stub
    double conversion = Double.parseDouble(fToC.getText());
    fahrenheit = (((conversion -32) * 5) / 9);

    }   
}
smac89
  • 39,374
  • 15
  • 132
  • 179
  • This code doesn't compile. And what exactly is the question? – Christian Hujer Nov 24 '14 at 04:59
  • 1
    Multi-frame applications is typically a bad idea. Read this [discussion thread](http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice) for more info. You are better off using a `JFrame` for your application frame, and JInternalFrame for your internal windows. – hfontanez Nov 24 '14 at 05:12
  • 1) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) 2) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson Nov 24 '14 at 08:49

3 Answers3

1

The Calculator class is independent of TextArea class. The problems I see in your code is the following:

  1. In the Program class there is no need to instantiate Calculator class
  2. In TextArea class do not instantiate Calculator class before hand, it should be instantiated in the loadCalculator method.
  3. Make Calculator to extend JDialog and pass to its constructor the instance of TextArea class and set this dialog box as a modal.
  4. When you are doing the calculation, the value is stored in a double variable. Two things you can do, when the button is pressed and you call degreeConversion at that time, call a method of TextArea class to set the double value to the textArea in the TextArea class, or when the window is closing (add its listener) then call the degreeConversion or TextArea updateValue method.

For point #4 it should be something like the following:

public class TextArea extends JFrame {
    ...
    private JTextArea textArea;
    private void loadCalculator() {
        Calculator c = new Calculator(this)
        c.setVisible(true);
    }

    public void updateValue(String str) {
        textArea.setText(str);
    }
}

public class Calculator extends JDialog() {
    private TextArea parent;
    public Calculator(TextArea parent) {
        super(parent, true); //or something like this to make it dialog I dont remember the exact syntax
        this.parent = parent;
        ...
    }
    ...
    private void degreeConversion() {
        double f = ...
        parent.updateValue(String.valueOf(f));
    }
}
Imran Zahid
  • 25
  • 1
  • 7
0

The problem is with the way you are adding the text area to your frame:

You did this:

this.add(BorderLayout.CENTER, textArea);

instead of the usual:

this.add(textArea, BorderLayout.CENTER);

The code will still compile, but you have just used a deprecated add method to add the component to the content pane. According to the documentation for this add signature

This method changes layout-related information, and therefore, invalidates the component hierarchy. If the container has already been displayed, the hierarchy must be validated thereafter in order to display the added component.

This explains why you it was only the second time around that the text is displayed. Use the correct method signature otherwise make sure to call validate on the frame for the text area to display the new text

Source

smac89
  • 39,374
  • 15
  • 132
  • 179
0

Your problem is here:

private void loadCalculator() {
  c.setVisible(true);
  c.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
  this.setLayout(new FlowLayout());

  if (!c.fToC.getText().isEmpty()) {
     textArea.setText(String.valueOf(c.fahrenheit));
  }
}

You're trying to extract information immediately from the Calculator object on displaying it before the user has had a chance to interact with it.

One way to solve this is to either have your main GUI listen for changes to the Calculator, say by adding its own ActionListener to the calculator's button, or have the Calculator aware of the main GUI and have it push its information into the main GUI's text component when its button is pushed.

Note that the Calculator window should be a dialog window such as a JDialog and not a JFrame.

As an aside, this code in Program.java:

  Calculator calculator = new Calculator();
  calculator.setVisible(false);
  calculator.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

is completely unnecessary as it does nothing of use since it creates a Calculator instance that is never displayed.


For example, if you gave Calculator this method:

public void addActionListener(ActionListener actionListener) {
    fToCButton.addActionListener(actionListener);
}

to allow outside classes to add an ActionListener to its button

And then in your TextEditor program, add the ActionListener:

public TextEditor() { super("TextMe"); this.setLayout(new BorderLayout()); loadMenuBar(); loadToolBar(); loadTextArea(); this.pack();

  c.addActionListener(new ActionListener() {

     @Override
     public void actionPerformed(ActionEvent e) {
        if (!c.fToC.getText().isEmpty()) {
           textArea.setText(String.valueOf(c.fahrenheit));
        }
     }
  });

and get rid of:

private void loadCalculator() {
   c.setVisible(true);
   c.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
   this.setLayout(new FlowLayout());

   // if (!c.fToC.getText().isEmpty()) {
   // textArea.setText(String.valueOf(c.fahrenheit));
   // }
}

The code should work. Note that you shouldn't directly access fields of other classes, and all fields should be private.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373