Invoke method in another source file?

Hello,

I'm new to java programming (and OO in general), I feel that I have a basic understanding of OO design (just to give an idea of where I'm at).

My problem: I can't figure out how to access methods or instance variables in other source files (.java files) within the same package. Here's a couple examples of what I'm trying to do....

ex1.

MainFrame.java

public class MainFrame extends JFrame {

MainFrame mainFrame = new MainFrame();

mainFrame.setVisible(true);

~I have a button on this form that when clicked does this....

MainFrame.this.setVisible(false); *as a side note, I don't understand exactly what this statement means, but it's the only way I could make it hide the frame (so feel free to help me on this too if you don't mind-the confusion is; to hide a label I can just say mylablename.setVisible(false) why do I have to say myframename.this.setVisible when I'm dealing with a Frame?)

NewEstimate estimate = new NewEstimate(); //inst. and show next frame

estimate.setVisible(true);

~NewEstimate is the name of the other java source file (NewEstimate.java)

so after clicking the button my new form loads, and I have another button that when clicked should close my estimate form and show mainFrame again, this is where my problem is....

I want to just dipose this form because I want it instaniated each time so I just want to dispose() this one so...

MainFrame.setVisible(true); //show the main frame again

dispose();

....I get the error MainFrame symbol not found and I have tried all kinds of ways likemypackagename.MainFrame.setVisible(true);

mainFrame.setVisible.setVisible(true);

MainFrame.mainFrame.setVisible(true);

all to no avail thus leading me to believe that one of those is correct but my problem is something else...

I also have the same problem when trying to invoke a method in another source file and the same when trying to evaluate a variable...

if in source1.java I have somewhre String name = mike;

then in source2.jave I have if name equals mike do something, I get the same errors; symbol cannot be resolved.

Thanks for taking the time to help.

Mike

[2260 byte] By [mikenaa] at [2007-10-2 6:09:52]
# 1
I also wanted to add that the code that creates and instance of MainFrame and sets visible to true is public static void main....wasn't sure if that was need to know info...thanks
mikenaa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 2

Hi,

and have you imported java "core" files?

Example:

For JFrame you have to write (at the begining of the .java file)

import javax.swing.JFrame;

or import javax.swing.*;

for the whole package.

L.P.

lukika at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 3

Yes....I didn't mean the code to represent my code verbatim. My forms load fine, it's just when I'm in the second form and want to close it and show the first form again, I get the symbol not found error in the statement mainFrame.setVisible(true);

I have made it work by just creating another instance of MainFrame and then showing it, but I don't want to create a new instance each time, I just want to hide it while the second form is loaded and then show it again when the second form is closed.

*remember, each form is in a seperate source file, the first being MainFrame.java and the second being NewEstimate.java

*this really is just one specific problem I'm having, but really it's causing me all kinds of problems; I can't invoke methods in the other source file, evaluate variables etc. I'm hoping that all these problems are linked to one setting.

Anyway, my project is stalled right now because of this so please help! It's unbelievable that I can't find any tutorials on programs with 2 or more forms having each form in a seperate java file? Is my design the problem here? Should my entire program be in one single .java file? In C++ you just had to reference the other header file to invoke functions or methods, is that what I need to do here? what is the java way of doing this?

Thanks

Mike

mikenaa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 4

Finally, I have figured out a way to make it work. In my above problem I have 2 public classes, each in there own .java file.

public class MainFrame extends JFrame{}

public class NewEstimate extends JFrame{}

I changed the second class to extend MainFrame like:

public class NewEstimate extends MainFrame

....so now I an evaluate variables from MainFrame and can also invoke methods in class MainFrame. However, my next question would be; is this ok/proper way to accomplish what I'm trying to do here. Whether proper or not, what are the potential problems of doing it this way (I don't mean to be a pain, but I like learning and always prefer an understanding/explanation over "no, that's wrong, don't do it that way and don't ask why", because I don't learn that way)

Thanks again

mikenaa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 5

Actually, I spoke to soon, exceptions are being thrown even though the program appears to run fine.

I'm starting to wonder if Java is a poor choice for programs with multiple frames, I can't seem to find any documentation on this and every forum I post to acts like they have no idea what I'm trying to do. Is this where my problem is? Is java a poor choice for software other than web apps?

mikenaa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 6

No, Java works perfectly well for GUI or desktop applications. You just don't know how to use it, that's all. That isn't surprising for a beginner but it's a poor workman who blames his tools.

I would give you some suggestions on how to modify your classes so they can communicate, but you haven't posted any code worth commenting on. So how about posting something? Not a thousand lines of code, just something short but functional.

DrClapa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 7

Thanks for your reply. Here is a test case that resembles what I'm trying to do. Note that I don't want to dipose of Frame1, (my reason is that I only want to initialize it 1 time (when the program is started), so I only want to hide it when it calls Frame2. Then when the user clicks the button on Frame2, dispose of Frame2 and show Frame1 again. The specific error I'm getting in Frame2.java is in the line frame1.setVisible(true) and is frame1 symbol cannot be resolved. That is my MAIN problem (main priority at this point) but I am also having a problem evaluating or referncing variables in Frame1.java from Frame2.java; I'm assuming though that the problems are related.

Frame1.java

******************************************************************************

package thepackage;

import javax.swing.JPanel;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.*;

public class Frame1 extends JFrame {

private JPanel jContentPane = null;

private JButton jButton = null;

public String name = "Bill"; //This is the variable I need to evaluate in

frame2

public Frame1() {

super();

initialize();

}

private void initialize() {

this.setSize(new java.awt.Dimension(300,200));

this.setSize(300, 200);

this.setContentPane(getJContentPane());

this.setTitle("Frame1");

}

public static void main(String[] args) {

Frame1 frame1 = new Frame1();

frame1.setVisible(true);

}

private JPanel getJContentPane() {

if (jContentPane == null) {

jContentPane = new JPanel();

jContentPane.setLayout(null);

jContentPane.add(getJButton(), null);

}

return jContentPane;

}

private JButton getJButton() {

if (jButton == null) {

jButton = new JButton();

jButton.setBounds(new java.awt.Rectangle(58,132,182,26));

jButton.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent e) {

Frame1.this.setVisible(false);

Frame2 frame2 = new Frame2();

frame2.setVisible(true);

}

});

}

return jButton;

}

}

Frame2.java

**********************************************************************************

package thepackage;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JLabel;

public class Frame2 extends JFrame {

private JPanel jContentPane = null;

private JButton jButton = null;

private JLabel jLabel = null;

public Frame2() {

super();

initialize();

showFrame(); //set the label text to the string in variable "name"

}

private void initialize() {

this.setSize(300, 200);

this.setContentPane(getJContentPane());

this.setTitle("Frame2");

}

private JPanel getJContentPane() {

if (jContentPane == null) {

jLabel = new JLabel();

jLabel.setBounds(new java.awt.Rectangle(53,40,131,16));

jLabel.setText("");

jContentPane = new JPanel();

jContentPane.setLayout(null);

jContentPane.add(getJButton(), null);

jContentPane.add(jLabel, null);

}

return jContentPane;

}

private JButton getJButton() {

if (jButton == null) {

jButton = new JButton();

jButton.setBounds(new java.awt.Rectangle(49,117,136,35));

jButton.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent e) {

frame1.setVisible(true);

dispose();

}

});

}

return jButton;

}

private void showName(){

jLabel.setText(name); -> gives error Component.name is not

visible

}

}

mikenaa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 8

Update....ok - I think I got the variable problem fixed. I used a setter method in frame1 to set the variable "name" and I wrote a getName method to return the string that is stored in "name". I can call the getName method from frame2 without error. (Is this the proper way to do this?)

problem with diposing of frame2 and showing the hidden frame1 still exists.

Thanks once again

mikenaa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 9

here's an off the wall implementation to think about!

import javax.swing.*;

import java.awt.event.*;

public class FrameManager {

JFrame[] frames;//not used yet

//MyHandler handler; not used yet

JFrame frame1;

JFrame frame2;

public FrameManager() {

init();

}

private void init(){

frame1 = getFrameOne();

frame2 = getFrameTwo();

frame1.setVisible(true);

}

private JFrame getFrameOne(){

JFrame frame = new JFrame();

frame.setSize(new java.awt.Dimension(300,200));

frame.setSize(300, 200);

frame.setTitle("Frame1");

frame.getContentPane().setLayout(null);

JButton button = new JButton(getButtonOneAction());

button.setBounds(new java.awt.Rectangle(58,132,182,26));

frame.getContentPane().add(button);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

return frame;

}

private Action getButtonOneAction(){

Action a = new AbstractAction(){

public void actionPerformed(ActionEvent ae){

if(frame1!=null)

frame1.setVisible(false);

if(frame2!=null)

frame2.setVisible(true);

}

};

return a;

}

private JFrame getFrameTwo(){

JFrame frame = new JFrame();

frame.setSize(new java.awt.Dimension(300,200));

frame.setSize(300, 200);

frame.setTitle("Frame2");

frame.getContentPane().setLayout(null);

JButton button = new JButton(getButtonTwoAction());

button.setBounds(new java.awt.Rectangle(53,40,131,16));

frame.getContentPane().add(button);

frame.getContentPane().add(new JLabel(""));

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

return frame;

}

private Action getButtonTwoAction(){

Action a = new AbstractAction(){

public void actionPerformed(ActionEvent ae){

if(frame2!=null)

frame2.setVisible(false);

if(frame1!=null)

frame1.setVisible(true);

}

};

return a;

}

public static void main(String[] args) {

new FrameManager();

}

}

walken16a at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 10

Thanks for your reply....I like the idea you have given me but I don't know if it's quite whan I need....

Each of my frames are in their own .java file, this is just a simple example, the code that creates the actual frames are a few hundred lines long, thus putting them in their own file.

If I am interpreting your example correctly, I would put all of the frame instaniating code form both frames in ONE .javafile/class?

mikenaa at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 11

> Thanks for your reply....I like the idea you have

> given me but I don't know if it's quite whan I

> need....

>

> Each of my frames are in their own .java file, this

> is just a simple example, the code that creates the

> actual frames are a few hundred lines long, thus

> putting them in their own file.

>

> If I am interpreting your example correctly, I would

> put all of the frame instaniating code form both

> frames in ONE .javafile/class?

no, not necessarily, i just wanted to make a point.

some folks automatically always extend JFrame.

just wanted to show another point of view.

that wasn't really even the point.

the point was that you could have a handler class.

you can still use your two frame classes, just invoke your

application through the frame manager class which could

have references to all of your frames. these references could

be in an array or collection.

in this manager class, you could create the instances of your frames

Frame1 f1 = new Frame1();

with yoru existing classes.

you could also have a handler class that takes all processing away from you "presentation layer"

that's what the stuff was at the top that said "not used yet"

there are so many options and some of them don't involve

putting all your listeners and handling all your events in the gui presentation layer

the gui shouldn't have to know anything about what goes on in the processing.

walker

walken16a at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 12
don't worry about the choice you made to use java.java will handle this very well. the code i gave might seem extremebut that's to let you know that you have lots of options and to think outside the normal scope (WITHIN REASON)walken
walken16a at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 13

in other words

you could have a manager class that starts the application and manages the frames. this class would know how many frames you have and whether they were visible

the manager class could create a handler class that would handle all the events.

the manager class would create the frames and you could either call a method in the handler class that returns an Action or Listener

or

you could use addActionListener method and send the handler as a param.

when i want to separate my listeners (multiple listeners) then i sometime use the first method

then the handler knows about the frames through the manager maybe,

but the frame is stupid and doesn't have to worry about anything else but presenting a UI to the user.

walken

walken16a at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 14
and, you can have a separate handler class for each frame if it's really required, the handler class should only know the bare minimum about the frame in order to do it's job.let each class be responsible for it's intended purpose.walken
walken16a at 2007-7-16 13:10:34 > top of Java-index,Java Essentials,Java Programming...
# 15

I just don't "get" it. I'm not disagreeing with you or discrediting your solution but I just don't understand why all that is necessary just to show a hidden frame, which essentially is all I'm trying to do here. I like the idea of a frame manager class but I just have two frames, one of which, frame2 I can create a new instance each time and dipose of it when I'm done. With frame1 I just want 1 instance of so I'll hide it when working with frame2 and show it when frame2 is done doing it's job. Perhaps I'm going about it all wrong, I don't necessarily need frame1 to be hidden; I just don't want the user to be able to work on frame1 while frame2 is open but I would PREFER frame1 to be hidden so there will be less frames open on the screen. To sum it up, if there's not a much simpler way to achieve this effect then I'll just be stuck with living frame1 visible all the time.

Thanks again

mikenaa at 2007-7-20 18:49:49 > top of Java-index,Java Essentials,Java Programming...
# 16

> I just don't "get" it. I'm not disagreeing with you

> or discrediting your solution but I just don't

> understand why all that is necessary just to show a

> hidden frame, which essentially is all I'm trying to

> do here. I like the idea of a frame manager class but

> I just have two frames, one of which, frame2 I can

> create a new instance each time and dipose of it when

> I'm done. With frame1 I just want 1 instance of so

> I'll hide it when working with frame2 and show it

> when frame2 is done doing it's job. Perhaps I'm going

> about it all wrong, I don't necessarily need frame1

> to be hidden; I just don't want the user to be able

> to work on frame1 while frame2 is open but I would

> PREFER frame1 to be hidden so there will be less

> frames open on the screen. To sum it up, if there's

> not a much simpler way to achieve this effect then

> I'll just be stuck with living frame1 visible all the

> time.

>

> Thanks again

well, in truth, you really don't have to go through all of that.

you can block events to a frame if you need to

you can also use modal dialogs

bottom line is, if frame1 has refrerence to frame2 then you can do what you want by calling setVisible(false) in the action listener.

maybe i talk too much, but i still don't think you should worry about

your choice of languages. Just wanted to demonstrate some possibilities.

kind regards

Walken16

walken16a at 2007-7-20 18:49:49 > top of Java-index,Java Essentials,Java Programming...
# 17

Yes...I really appreciate you explaining the options; that means a lot to me. I always like to hear everybody's opinion/explanation on a solution.

But what you said about referencing.... how do that? I think that's what I'm looking for? How do I reference frame1 in frame2 so I can just set frame1 visible from within frame2?

Thanks

mikenaa at 2007-7-20 18:49:49 > top of Java-index,Java Essentials,Java Programming...
# 18

I think with the constraints given that this is the best i can do

public class Frame1 extends JFrame {

private Frame2 frame2;

private JPanel jContentPane = null;

private JButton jButton = null;

public String name = "Bill"; //This is the variable I need to evaluate in frame2

public Frame1() {

super();

initialize();

}

private void initialize() {

this.setSize(new java.awt.Dimension(300,200));

this.setSize(300, 200);

this.setContentPane(getJContentPane());

this.setTitle("Frame1");

}

public static void main(String[] args) {

Frame1 frame1 = new Frame1();

frame1.setVisible(true);

}

private JPanel getJContentPane() {

if (jContentPane == null) {

jContentPane = new JPanel();

jContentPane.setLayout(null);

jContentPane.add(getJButton(), null);

}

return jContentPane;

}

private JButton getJButton() {

if (jButton == null) {

jButton = new JButton();

jButton.setBounds(new java.awt.Rectangle(58,132,182,26));

jButton.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent e) {

Frame1.this.setVisible(false);

if(frame2==null)

frame2 = new Frame2(Frame1.this);

frame2.setVisible(true);

}

});

}

return jButton;

}

}

public class Frame2 extends JFrame {

private JPanel jContentPane = null;

private JButton jButton = null;

private JLabel jLabel = null;

private Frame1 frame1;

public Frame2(Frame1 frame1) {

super();

this.frame1 = frame1;

initialize();

//showFrame(); //set the label text to the string in variable "name"

}

private void initialize() {

this.setSize(300, 200);

this.setContentPane(getJContentPane());

this.setTitle("Frame2");

}

private JPanel getJContentPane() {

if (jContentPane == null) {

jLabel = new JLabel();

jLabel.setBounds(new java.awt.Rectangle(53,40,131,16));

jLabel.setText("");

jContentPane = new JPanel();

jContentPane.setLayout(null);

jContentPane.add(getJButton(), null);

jContentPane.add(jLabel, null);

}

return jContentPane;

}

private JButton getJButton() {

if (jButton == null) {

jButton = new JButton();

jButton.setBounds(new java.awt.Rectangle(49,117,136,35));

jButton.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent e) {

frame1.setVisible(true);

Frame2.this.setVisible(false);

}

});

}

return jButton;

}

private void showName(){

//jLabel.setText(name);// -> gives error Component.name is not visible

}

}

walken16a at 2007-7-20 18:49:49 > top of Java-index,Java Essentials,Java Programming...
# 19

Ah man, if you only knew how good it feels to finally get this working. Thank you very much - that was exactly what I was trying to achieve.

If you don't mind though, and explanation on the constructor you made would be great; mainly the lines

public Frame2(Frame1 frame1)

this.frame1=frame1;

....those are the two lines that I don't really understand what is happening exactly

public Frame2(Frame1 frame1) {

super();

this.frame1 = frame1;

initialize();

}

mikenaa at 2007-7-20 18:49:49 > top of Java-index,Java Essentials,Java Programming...
# 20

okay,

here is your method in Frame2 that creates the listener for the button in Frame2

notice that it needs a reference to Frame1 namely frame 1

private JButton getJButton() {

if (jButton == null) {

jButton = new JButton();

jButton.setBounds(new java.awt.Rectangle(49,117,136,35));

jButton.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent e) {

frame1.setVisible(true);

Frame2.this.setVisible(false);

}

});

}

return jButton;

}

The field frame1 was declared as a class variable so that the inner class listener could see it

public class Frame2 extends JFrame {

private JPanel jContentPane = null;

private JButton jButton = null;

private JLabel jLabel = null;

private Frame1 frame1;//frame1 reference

now, we know that the Frame2 is created in the listener for the button on Frame1, and Frame2 needs a reference to Frame1 so we add a parameter to the constructor of Frame2

public Frame2(Frame1 frame1) {

super();

this.frame1 = frame1;

initialize();

}

this code takes the parameter and assigns it to the class variable frame1

so when we create the Frame2, we are forced to send the reference to Frame1 in the constructor

here is the Frame1 code that creates the Frame2

jButton.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent e) {

Frame1.this.setVisible(false);

if(frame2==null)

frame2 = new Frame2(Frame1.this);

frame2.setVisible(true);

}

});

so all the pieces should fit together.

this will work for you but somewhere in the future when you are working on large applications, i hope you consider the alternative solution given.

it probably doesn't matter now as this application seems quite small.

I've worked on an application for three years now that amounts to over

178,000 lines of code. sometimes it becomes pretty messy.

remember, you might need to set the default close operation on Frame1

so that the application ends when you close the main frame.

sincerely

Walken16

walken16a at 2007-7-20 18:49:49 > top of Java-index,Java Essentials,Java Programming...
# 21
Ok, great; that clears things up for me a bit. I will definitely consider the alternative solution you gave earlier, it seems more OO and "correct" per say.I appreciate all your help.ThanksMike
mikenaa at 2007-7-20 18:49:49 > top of Java-index,Java Essentials,Java Programming...