I am relatively new to Java and I am using IntelliJ's GUI Form wizard to create a form that uses a main() method to create the Form.
I can get the Form to create, and have added a listener to the submit button, but I am not sure about how to get the form values back out into the rest of the application.
Because the form uses main, I can only pass in Strings, and it doesn't return anything so I can't get a reference to the frame so I can't create a method to pass in a reference to the object to populate.
Because the form uses main, I can only pass in Strings, and it doesn't return anything so I can't get a reference to the frame so I can't create a method to pass in a reference to the object to populate
You should go back to the basics of OOP. The GUI designers really hide this from you, and it takes much refactoring to get them functionally clean.
You can create any instance of your class. And run that via main()
For example.
public class Gui {
private JFrame frame;
private JTextField textField;
public Gui(String title) {
frame = new JFrame(title);
}
public void run() {
// display Frame, add panels, etc
}
public String getDataFromGui() {
return textField.getText(); // for example
}
// other methods
public static void main(String[] args) {
Gui g = new Gui("Hello World!");
g.run();
}
}
Added a project to showcase this. [Link here]
In order to get data back to the first frame we would need to use the same memory reference.
Simplifying the explanation:
Imagine you have a bucket.
The first frame tells the second frame in what bucket to place the data.
The Second Frame doesn't know the data yet but knows in which bucket to place it.
The User adds the data and clicks Ok button.
The Second Frame takes the data and places them in the bucket.
Back in the first frame we take the data from the bucket.
In the project, the Bucket is the instance of DataObject, which is passed to the SecondForm and upon clicking its button we add the value to that bucket.
Finally, a WindowFocusListener to update the field when we get back to the first frame.
Code is self-explanatory.
With functional programming, the code can be improved further. Checkout this branch .
Related
I am trying to implement a feature in a project that I am working on but I am having dificulties. The project allows the user to create 3 different objects that all share the same super class. Each object is part of an arrayList and is represented by an ImageIcon inside of a JLabel. I would like to be able to click a specific JLabel and open a message dialog with a toString() method that returns information about the coresponding object.
So far, I have a (poorly implemented) system in place that will allow the user to click any ImageIcon but it will only display information about the most recently created object. I am aware why this code only displays the information it does but I do not know how create the code that I need.
If anyone can help I would be very grateful. If anything is poorly explained or needs elaborating on, please ask. I have attached my current code below, Thank you.
Code explanation: The 'count' variable is used to count the number of objects created (I cannot have more that 9). I know that the current code will just display the 'count-1' object created (which is the newest one). I'm just un aware of what I need to do to find the specific object relating to the lable that is clicked.
label[count].addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e)
{
JOptionPane.showMessageDialog(null, myAppliances.get(count-1).toString());
}});
Each object is part of an arrayList and is represented by an ImageIcon inside of a JLabel.
That gives a good hint to it. How about doing following
Class MyObjectLabel extends JLabel something like below:
public MyObjectLabel extends JLabel
{
private YourObjectThatisInList localCopyOfObject;
public MyObjectLabel (YourObjectThatisInList object)
{
super(createIconForTheObject(object));
this.localCopyOfObject=object
}
//add getter setter method for localCopyOfObject
}
2) Now add listener to this class.
3) On event fired of this new Label class, call the getter for localCopyOfObject and display the toString for your localCopyOfObject stored in MyObjectLabel.
Please note that createIconForTheObject, is just a placeholeder method I showed. You can use your own method to create icon
Thanks
I want a java gui event to, when activated, call a class for processing. I am having an issue because I need to use an object "Settings" that is created earlier in the code and have it for the rest of the program. Basically when types in textfield and presses enter, this event starts and calls a class to handle the user's input. I have looked at other forum answers and their solutions involve creating "new" objects, which is not what I am trying to do. Display.TaskInput needs the "Settings" object to work. This is the event:
public class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
//The text below calls a task that needs to use the settings object
//This object presets the task object for easier user input.
//Yes, this is wrong, but you can see what I am trying to do.
Display.TaskInput(settings);
//The rest of this is just for testing. It works when the above line
//is removed.
label.setText("This worked also");
label2.setText("This worked also");
panel1.add(label2);
add(panel1);
panel1.setVisible(true);
}
}
This is where the Settings Object is created. It is preset by a database. When the user enters a task, the task will have several presets ready so that the user does not have to manually enter them. This is the start of the program:
public static void main(String[] args) {
//object is created and loaded with data
Settings settings = new Settings();
DatabaseConnectSettingsSelect.Connect(settings);
//this is where the gui is initiated.
FrameStart.main(args);
//Once the gui starts working, this class will become unnecessary
Display.StartScreen(settings);
}
This is the main in the GUI class FrameStart:
public static void main(String[] args) {
FrameStart ex = new FrameStart();
ex.setVisible(true);
}
Everything would be fine if I didn't need to use a premade object. Most of the solutions could solve that, but I need to import an object created in another class. If you need more code to look at I happily provide it; this is just where the problem area is that I have run into.
To sum things up, I need to place an already created object into an event class or directly into the TaskInput class. Is there a better way than what I am doing? This program has about 15 classes and the way I am currently doing things works well, its just that I don't know how to place a created object into the ActionEvent code. Once again, I have looked at other forum answers and their solutions involve creating "new" objects which is not what I am trying to do.
I have a JFrame with buttons and when I click one of the buttons an integer decreases by 1. I am trying to show the integer in another JFrame but when I reference it I get an error saying non static variable cannot be referenced in a static context. How can I make this a non static variable?
Here is the code from when a button is clicked.
private void DietPepsiBTNActionPerformed(java.awt.event.ActionEvent evt) {
MessageLBL.setText("Enjoy your Diet Pepsi!");
credit -= 1.00;
stCredit = Double.toString(credit);
CreditAMT.setText("$" + stCredit);
Refresh();
dietPepsi -= 1;
Provide some kind accessor in the master frame (to allow other components to read the value) (something like getValue() for example).
When ever the value is changed, fire some kind of event. You could cheat and use a PropertyChange event which would require you not to add any additional code, or you could fire something like a change event that notifies the other frame that the value has changed.
The second frame would then use the getValue method to read the value.
This would require the second frame to have a reference to the master (so it can get the value).
Better yet, just create a model, allow the model to fire events and share the model.
Have a look at Observer Pattern for more details
Brendon's answer is close. Ideally what you do what he suggests, create a separate object and pass it in to each frame. The frames then share the objects. Since the frames themselves will have references to the object, you don't need any kind of global reference.
YourModel model = new YourModel();
Frame1 frame1 = new Frame1(yourModel);
Frame2 frame2 = new Frame2(yourModel);
Additionally, you implement the PropertyChangeListener idiom to where each frame subscribes to the property changes in YourModel.
That way, when Frame1 makes changes to YourModel, Frame2 will be notified of them and can keep itself up to date automatically.
Then the game becomes a matter wiring together objects and their listeners. After that, it's almost magic how it all works together.
Ref: http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html
Make a third object and pass a reference to both jframes. This shared object can store any properties that you need
I've been working on a Java Swing project where I need to retrieve the object/instance that created a panel in order to call a simple save method particular to that instance.
You have a JFrame with a JTabbedPane that has tabs created by instancing a class which builds a JPanel and adds it to the JTabbedPane, I need to find the specific instance from the selected JPanel/tab on the JTabbedPane to then call it's save method.
Any ideas?
Thanks for your time!
public class frame extends JFrame implements ActionListener{
Builds a frame dubbed "frame" that is static.
Builds a static JTabbedPane dubbed "pane"and adds it to the frame.
Creates a button that creates a new instance of sheet.
public void actionPerformed(MAGIC!){
See if a button on the panel has been pressed and uses the currently selected tab to locate the correct instance of sheet to run it's save method.
}
}
public class sheet extends JPanel{
In constructor makes a JPanel and adds it to "pane"
Describes a save method that outputs a variable unique to the instance.
}
I figured out all I needed to do was store new tab objects in an ArrayList derp. Thanks for your attempts though guys!
Rather than just connecting back to the original creator, my approach to this was to create / use an interface that expicitly supports saving. I created something for this in TUS, my sourceforge project
http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/filepersist/
Check out Persistable and Persistable2. Of course anything can be a Persistable, but the abstraction let's you get away from explicit ties back to the creator class
You can add a field in the new JPanels that point to the instance of the creator. I don't think there is any such method to point back to parent class in the API.
--EDIT--
You may want to check
http://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html
getSelectedIndex() may be what you are looking for.
I am trying to program a java application that consists of several windows using JFrame.
Each JFrame contains a JTextField and buton to go to the next JFrame.
I need to retrieve all the information entered by the user at the end.
I created an event click on the buton to save to a public class all the data that the user introduce in the JTextField. I named that public class myData, which has a static attributes.
The problem is that I can not access this class from the button listener function.
I get an error: cannot refer to an non final variable inside an inner class defined in a different method.
My goal is to be able to share the class myData between different methods of a different class.
E.g. I have a class named myClass1 and myClass2, so I want to share the myData attribute between myClass1 methods and myClass2 methods.
Please anyone can someone help me? or propose another way to do this!
Thanks in advance !
All of the calls about MVC etc. are valid, but this isn't that hard.
What you want to do is in your Main, you can create your Data (Model) class, the class that holds all of your information.
So, you can do something like this:
public class F1 ... {
private final Data myData;
public F1(Data theData) {
myData = theData;
}
....
}
public class Main {
Data myData;
public static void main(String args[]) {
Main m = new Main();
m.setMyData(new Data());
F1 f = new F1(m.getMyData());
...
}
}
Then, later, when F1 calls F2, simply do the same thing -- create F2 with the Data passed in earlier by the constructor. That way, as each Frame runs its course, they're all working on the same instance of Data. When all is done, the single instance of Data is left within the Main class for you to do with what you will.
There are better ways to reorganize your entire program, but this should give you ideas on how to get over the hump you're having right now.
Addenda:
There are several things you can do.
When your get the ActionEvent, it contains a source. That source is the component that generated the event (most likely a Button in this case). If you know where the button is located in the hierarchy of things, you get to your Frame directly. In the pastebin example, you have Frame -> Panel -> Button. So, if you have the Button, you cat get to the Frame.
public void actionPerformed(ActionEvent e) {
JButton sourceButton = (JButton)e.getSource();
F1 f1 = (F1)sourceButton.getParent().getParent();
Data myData = f1.getMyData();
data.setField(...);
}
Again, this is not the recommended ways of doing things. The tutorials have decent examples of using MVC and property change listeners and the whole kit. But this should get you to where you want to go.
Sorry, but your design needs alot of work. I'm going to recommend you read up on MVC. it may seem like alot to chew on right now but it will help you immensely in the long run. On a side note, dont nest your data class definition(s), and remember to always distinguish between classes and objects.
Your overall design of swapping JFrame's seems a bit iffy to me. Why not instead use either dialogs such as a JDialog or JOptionPane or even better a CardLayout to swap views. Also I urge you not to use static fields for any of this as this can cause significant problems in the future and makes your code less compliant with good object oriented principles. With regards to information sharing, about all I can say is that it's all about one class having the proper reference to the other class. For more specific advice you'll likely need to show us more information and code.
Edit
Also, you know of course that you can get a reference to the JButton that stimulated the ActionListener by calling getSource() on the ActionEvent object passed into the actionPerformed method. This may allow you to get a reference to the class that holds the JButton if necessary.