I need to ask a small question because its irritating me.
How do i pass one vale from one frame to another frame in Java?
Below i have written a small script that is supposed to return the value but i dont quite know how to access it in the other frame.
Here is the code that is suppose to return the current value in a JcomboBox as a string into the other frame:
public String getUser(String user)
{
user = (String)jComboBox1.getSelectedItem().toString();
return user;
}
The way i thought it would work is to call a new instance of that class into the other frame (the classes name is editUser) so here is what i thought i would need to do.
public editPass()
{
initComponents();
editUser name = new editUser();
String test = name.getUser();
}
Thanks in advance for any advice.
The problem is that with doing this: editUser name = new editUser() is that you are creating a new instance (besides the fact that class names should start with upper case as per convention). This causes you to loose any data since you are now referencing a new object.
If you need to access data from the previous frame, what you would need to do would be to either:
Create a new object with all the relevant data and pass it to the next frame OR
Pass the current frame to the next frame. This will allow the new frame to be able to reference the previous one.
As a side note, the Card Layout might be relevant to what you are trying to achieve.
EDIT:
As per your comment question:
Assuming you have an editUser frame, say we call it frame1 and you populate all the data you need.
Then, the user presses Next, or something similar which causes him/her to go to the next frame, thus frame1 will either be hidden or non existant any more, depending on your implementation.
Let us call the second frame frame2. Now, in frame2 you need to access details stored in frame1. Doing like so: editUser name = new editUser(); will cause frame2 to create a new instance of frame1, thus meaning that you have created a new frame with empty values. Calling name.getUser() should not yield anything.
When I mentioned create an object with the relevant data I meant that, if you are editing user values, you could create an object which would have for instance all the information which was edited. So it could have fields like userId, originalUserName, newUserName, etc.
One the user presses Next in your frame1, you could create and populate this object and use it to transfer data from one frame to the next. In this case, the object you would be creating would be known as a Data Transfer Object (DTO).
So, the constructor of your second frame would look something like so:
public editPass(UserEditDTO userEditDTO)
{
initComponents();
String test = userEditDTO.getNewUserName(); //gets the new username the user has provided.
}
And in your editUser class, just before creating a new instance of editPass, you would do something like so:
...
UserEditDTO uEDTO = new UserEditDTO();
uEDTO = ... //set all the relevant fields here
new editPass(uEDTO).setVisible(true);
...
Alternatively, you can pass a reference to frame1 instead of a DTO. This approach is simpler. So your constructor for editPass would look like this:
public editPass(editUser editUser)
{
initComponents();
String test = editUser.getUser();
}
With your editUser code looking like so:
...
new editPass(this).setVisible(true);
...
Related
I am making a library where an application can use it to capture a selection of a screen and convert it to an image, like Gyazo.
This library is not the application itself, but only the tool that returns the File or BufferedImage object to the application.
I want the application to be simple as this:
Bootstrap b = new Boostrap(new GifCapturer());
b.beginCapture(); // user selects an area
File file = b.getFile();
But how can I make the application wait till the library returns the object? as you see the beginCapture method should activate the JFrame where the user will select an area to capture.
Do I need to sleep the thread? or use listeners design?
The beginCapture method starts a jframe window, where the user is able to select an area of the screen. Once selected, the library will convert the selected area to an object and set it as a local variable. So when you will use getFile it ill return the captured image. But the thing is, i need to make sure that the image was selected before getFile call gets executed, and wait instead but im not sure how.
Sorry if the question is not detailed, im on phone.
Please let me know if you need more information.
Implement a listener, that is invoked as soon the selection is ready. Put your File file = b.getFile(); code into the listener.
The code of your JFrame would be necessary to give a more detailed answer.
I have decided to use a Listener with a own built listener class, and interface.
Create an interface which you will use to get the data, or that will get know when the listener gets called, like this in my case:
public static void main(String[] args) throws AWTException {
Bootstrap b = new Bootstrap(new GifCapturer());
b.beginCapture(new ScreenCaptureCallback() {
#Override
public void captureEnded(File file) {
System.out.println("done!");
}
});
}
I have a main jFrame HomePage.java and many other classes which extend javax.swing.JInternalFrame. One of the classes (JInternalFrame) is Login.java. Now I check whether the password is correct in Login.java and if the password is correct, I load success.java. Now the problem arises when I have to load the success.java page.
I have a function in the HomePage.java whose purpose is to remove all internal frames and load success.java class. The function is as follows :-
public void LogIn(){
jDesktopPane1.removeAll();
System.out.println("Pos 2");
success frame = new success();
frame.setVisible(true);
jDesktopPane1.add(frame);
setContentPane(jDesktopPane1);
try {
frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}
I call the function in the Login.java page as follows :-
System.out.println("Pos 1 ");
(new HomePage()).LogIn();
The logic does not work. But, I receive the output as
Pos 1
Pos 2
which shows that the program flow was correct. I do not get any error also. Another weird factor is that when I calthe same LogIn() function from the menu in the jFrame itself, I get the desired output. Please solve my dilemma. Any help will surely be appreciated!
This code:
System.out.println("Pos 1 ");
(new HomePage()).LogIn();
Creates a new HomePage object and calls a method on it. Oh you are certainly calling the correct method, and it's going a HomePage instance, but it's not the correct HomePage instance, not the one that's displayed, because you've created a new one.
Short term solution: get a valid reference to the displayed HomePage instance and call your method on it. You could get it by passing it into the class that needs it as a constructor or method parameter, or you could use SwingUtilities.getWindowAncestor(...).
i.e.,
Window window = SwingUtilities.getWindowAncestor(Login.this);
if (window instanceof HomePage) {
HomePage validHomePageRef = (HomePage) window;
validHomePageRef.logIn();
}
Long term solution: don't create spaghetti code with GUI objects changing behaviors of other GUI objects, but instead refactor your code a la MVC or one of its variants, so the GUI can change the model and the other GUI objects can be notified of these changes via listeners and respond if they want.
I'm new to Java programming and am facing a (most likely) easy problem that I don't seem to be able to get across nor understand.
I have three different java files, one where I create an interface (SimulatorGui.java), other where I am creating a panel to use on the jTabbedPanel created in the interface (CollisionPanel.java - CollisionPanel class) and a third one, where I run a code that will create the output needed (Collision.java - Colision class).
In the Collision.java main method, I am doing the following:
public static void main (String[] args) {
//<editor-fold defaultstate="collapsed" desc="Simulation start procedures">
Tally statC = new Tally ("Statistics on collisions");
Collision col = new Collision (100, 50);
col.simulateRuns (100, new MRG32k3a(), statC);
//</editor-fold>
new SimulatorGUI().setVisible(true);
CollisionPanel update = new CollisionPanel();
update.updatepanel();
The first block, will create the desired output. I then want to send that output to the updatepanel! I am not passing any arguments to the method as I am still trying to debug this. updatepanel method is created in the file CollisionPanel as following:
public void updatepanel(){
System.out.println ("debug");
jTextArea1.setText("update\n");
}
What happens then is that when I run the Collision.java file it will output the "debug" text but won't set the text to the jTextArea1 (append doesn't work aswell). I then created a button to try and do so and in that case it works. In CollisionPanel.java:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
updatepanel();
}
This does the trick! I've searched and tried different things but can't seem to understand why this won't work.
Thanks in advance for your help, hope I've made the problem clear!
Okay I think I've eventually got the problem, and it is because of the IDE, you see in your main method you initiate a new CollisionPanel, which is wrong, netbeans has already added and initiated that panel in the SimulatorGUI, so now what you need to do is add a get method in the SimulatorGUI to get the initiated panel, then call the update method on that panel.
So add this to SimulatorGUI:
public CollisionPanel getCollisionPanel1() {
return collisionPanel1;
}
replace your old updatePanel() method with:
void updatepanel(String str) {
System.out.println ("debug");
jTextArea1.setText(str);
// jTextArea1.revalidate();
jLabel1.setText("test");
}
after that change your main too look like this:
SimulatorGUI simulatorGUI = new SimulatorGUI();
simulatorGUI.setVisible(true);
CollisionPanel cp=simulatorGUI.getCollisionPanel1();
cp.updatepanel("Hi");
and dont forget to remove the old updatePanel() method call from your CollisionPanel constructor, because now you can simply call cp.updatePanel("text here"); in your SimulatorGUI class instead of calling it only in the constructor.
I hope this is easy to grasp, if you're unsure let me know
Where do you add your CollisionPanel to the main GUI? I fear that this is your problem, and that you need to do this for your code to work. In fact where do any of your three classes get a reference to the others? For different classes to work in a program, there must be some communication between them. Understand that if you create a CollisionPanel object inside the GUI, and create another CollisionPanel object inside of the main method, calling a method on one object will have no effect on the other since they are two completely distinct entities.
For example, this code:
new SimulatorGUI().setVisible(true);
CollisionPanel update = new CollisionPanel();
update.updatepanel();
It appears that you are in fact calling updatePanel() on a CollisionPanel, but it's not on any CollisionPanel that is visualized in your GUI.
Consider giving SimulatorGUI a method that allows one to pass the CollisionPanel into it so that it can use it. This may in fact be a constructor parameter:
CollisionPanel update = new CollisionPanel();
SimulatorGUI simulatorGUI = new SimulatorGUI(update);
update.updatePanel();
Meaning SimulatorGUI's constructor would have to look something like:
public SimulatorGUI(CollisionPanel update) {
this.update = update;
// add update to GUI somewhere
}
There are three different levels when developping a GUI:
The view: the graphical component
The Model: the code that you run
The controller: checks if are update on the model in order to refresh the view.
So When you first start your program, the view will have the value assigned in the code; for instance say you created your JTextArea with the initial value type here. The view will show the JTextArea with the text type here.
When a change is made to the model, the view is not aware of it, it is job of the controller to check for update on the model and then refresh the view.
So this:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
updatepanel();
}
Will generate an event that say a property has been modify. So the controller will update the view.
Other than that, the change will not appear on the view.
Hope this helps..
I'm trying to create a menu screen, and I want to be able to create it, and any further permutations of it dynamically. I've created a MenuItem helper class to handle the menu items that show up, and it reads the name, image, and set the next state (something that is handled later). What I want to know is, how can I create the specific following Screens (they'll all be some subclass of my Screen class)?
What is the most efficient method to pass specific objects into the menuItems? Do I need to pre-create each possible Screen and then just read back in the serialized form of it, or can I create them dynamically. I'd hoped to be able to do something as simple as reading in a literal string "new SubClass(...)" and act off that, but I don't know how to go about that. Any other suggestions would be great!
If I understand correctly, what you want is a mechanism that reads a String command from a text file, and based on this command, displays a screen.
So, extract the interface of the "display screen" command into an interface. For example:
public interface ScreenDisplayer {
void displayScreen(Screen mainScreen);
}
Then build a Map<String, ScreenDisplayer>:
map.put("screen1", new ScreenDisplayer() {
#Override
void displayScreen(Screen mainScreen) {
// TODO display screen 1
});
// same for all the other commands
And when a "menu item" is clicked, get the DisplayScreen from the map and call it:
String command = selectedMenuItem.getCommand();
ScreenDisplayer displayer = map.get(command);
displayer.displayScreen(mainScreen);
I am creating a java app.
I have one class q2a2 which is a jpanel whose design is shown as follows: -img-
Suppose if an item is selected from the combo-box and "Create Account" button is clicked. One tab is added to the jTabbedPane. every item has a common tab. so what i did is created one class and adding that everytime on button click. The class name is q2a2_add. This is a panel as well. The image for this is as follows...
After having some three items the app looks like
The code for this is:
public void addclass(int a) {
if(jTabbedPane1.getTabCount()<13) { //variable name of TabbedPane
String s=(String) mainCB.getItemAt(a); //mainCB is the variable name of main combobox
int dont=0;
for(int j=0;j<tabname.length;j++){ //just to ensure two accounts should not be same
if(s.equals(tabname[j])){
dont=1;
break;
}
}
if(dont==0){
for(int j=0;j<12;j++) {
if(index[j]==0){
q2a2_add subpanel2=new q2a2_add(this); //calling the second class
jTabbedPane1.add(s,subpanel2); //here adding panel
subpanel2.heading(s); // heading() method is defined in q2a2_add() which rename the jTextField to be same as argument s;
tabname[j]=s;
index[j]=1;
break;
}
}
}
else {
JOptionPane.showConfirmDialog(null, (String) mainCB.getItemAt(a)+" is already created","Information", JOptionPane.PLAIN_MESSAGE);
}
}
else {
JOptionPane.showConfirmDialog(null, "Account Overload. Delete wrong account and then create","Caution", JOptionPane.PLAIN_MESSAGE);
}
}
Now my question is. As seen in the function. everytime same class has been called and added. How can i access the various comboboxes and textboxes in different tabs. I want to store and opearate values entered by the user. Like for example- how to read inputs from Accounts Receivable, Accounts Payable and Office Supplies differently.
Please reply.
I would expose the functionality that you require within your q2a2_add class. For instance, if you want to change the textbox value, add a function inside the q2a2_add class called setTextBoxValue() that takes a String parameter. Inside that function, you can set the textbox value. The same goes for retrieving information from it. The only remaining problem is how to keep track of the different tabs. What I would recommend (which may simplify what you already have) is to create a HashMap which maps String types to q2a2_add types. Then, when you want to add a new tab panel, you can just check if the String exists in the HashMap instead of searching through to check the titles. If it doesn't exist, you can add it to a HashMap stored inside of your outer JPanel class. Then, when you want to access the tabpanels, you can simply access them by string inside the HashMap and get/set their properties as you please.