I created a JFrame with buttons, labels and texts and I want to show it two times when I execute the main program, so I did like that:
import java.net.SocketException;
public class Main {
public static void main(String[] args) throws SocketException {
new MyFrame("client1");
new MyFrame("client2");
}
}
The result: I get two frames: one with the component of the other one inside, and one empty.
How to resolve this issue?
You are using static instance fields with your MyFrame for your components
A component can only reside within a single container, the moment you create your second frame, the static components are removed from the first container before been added to the second.
The solution, don't do this, ever...
I assume you are using static because you want to access these fields from another class, in that case, you should appropriate getters in the MyFrame class and pass a reference of it to those classes that need it.
Alternatively, you could establish a series of observers who monitor for changes and take appropriate action, this helps to decouple the code.
Personally, if you need to modify the MyFrame instances in some way, I'd provide setter methods that update your components instead, as I don't like exposing UI elements without good reason, to much opportunity for others to mess with them in appropriately
Related
I have a class that creates a JFrame. When the JFrame is created it has a start button. When the start button is clicked, it runs two threads until the stop button is clicked. The two threads are in another class file. From the class that contains the threads, how can I access the JFrame instance in order to change value that are displayed?
In order to acheive this you have to pass the reference of JFrame using this keyword.
To have access to a private instance within another class, I think you should use agetter.
Example:
//JFrame declaration
private JFrame frame;
//Getter
public JFrame getFrame() {
return frame;
}
As noted by one answer, you can pass in a reference of the GUI or view into any class that needs it, for instance by passing the GUI class into the other class's constructor parameter, and using the parameter to set a field, but having said that, there are caveats:
Always be sure to make Swing state changes on the Swing event thread (the EDT). Since you're using background threading, this means that you will either
use a SwingWorker as your background thread, and notify the GUI of changes via the publish/process method pair, or
your SwingWorker can notify observers of change via PropertyChangeListeners and "bound" properties, or
if using a standard Thread/Runnable, you will need to be sure to queue Swing calls onto the EDT using SwingUtilities.invokeLater(someRunnable)
Even better is to use a Model-View-Control type structure, but even if you do this, the model should be changed on the EDT for the same reasons above.
As a side recommendation in general I try to avoid making classes that extend JFrame as that unnecessarily restricts my code to creating just JFrames.
Note that this help is very general, but if you need more specific help, then you will want to post more specific information regarding your problem and your pertinent code.
sorry guys, but I got confused after many hours sitting ang writting the code.
Situation:
I have two JFrames. These are different Java classes - one of them is the FirstGUI, from which we can call the other JFrame called SecondGUI. OK - that's clear.
I also have one class called Processor in which i have specific methods like "connectToPort" or "disconnectFromPort".
Also, in the FirstGUI (which has the main method) I'm creating SecondGUI object (and set setVisible to false) and Processor object with FirstGUI and SecondGUI as parameters.
Problem:
From the FirstGUI in I want to call out SecondGUI (by setVisible to true) - OK, done. But what about calling out the created at the beginning Processor object from the SecondGUI JFrame? It's important to call the SAME object, because Processor methods can for example set text in the FirstGUI JFrame.JTextPane component, and add items to JComboBox of the SecondGUI.
I don't know how to solve this, I'm always getting NullPointerException.
EDIT:
I want to add that I can't pass the Processor object as an argument while creating SecondGUI, because Second GUI is created earlier and it is an argument while creating Processor... That's the problem.
When constructing the second GUI (child), the initiating class (FirstGUI) can pass self in constructor, and also retain the reference to the constructed object. Now both GUIs have the reference to each other:
class F1 extends JFrame {
F2 child;
void createF2() {
child = new F2(this);
child.setVisible(true);
}
}
class F2 extends JFrame {
final F1 parent;
F2(F1 parent) { this.parent = parent; };
}
If you've searched out your problem or for similar problems on this site, you'll know that the most common recommendation is not to use multiple JFrames, that it is suggestive of a bad design. Better to either swap views with a CardLayout or use JDialogs of the appropriate modality.
As for your question, having one class pass information dynamically to another class, there are two main options depending on program structure.
If one class is in a modal JDialog, then the first class can pull information from the second modal class by calling appropriate getter methods after the second window is no longer visible.
If one class is displayed non-modally, then you'll want to use some type of listener such as a PropertyChangeListener to have the listening class be notified by the observed class when state changes occur.
Edit
Regarding:
From the FirstGUI in I want to call out SecondGUI (by setVisible to true) - OK, done. But what about calling out the created at the beginning Processor object from the SecondGUI JFrame? It's important to call the SAME object, because Processor methods can for example set text in the FirstGUI JFrame.JTextPane component, and add items to JComboBox of the SecondGUI.
Audrius gives you an answer for that. 1+ up-vote given to his answer.
I don't know how to solve this, I'm always getting NullPointerException.
If you get a NPE, should carefully inspect the line that throws the NPE to see which variable is null and then trace back in your code to see why. If your still stuck on a NPE and need our help, then you'll want to show pertinent code and give us more detail on the problem including noting which variable is null and why you think that it shouldn't be null.
EDIT: I want to add that I can't pass the Processor object as an argument while creating SecondGUI, because Second GUI is created earlier and it is an argument while creating Processor... That's the problem.
This is a non-issue. Since the dependent window is displayed dynamically, you can always pass a reference just prior to displaying it using a setter method.
I have a JFrame that houses my many JPanels that represent different parts of my application in which you can do certain calculations.
I have a JDialog that is created in my Main.java class (extends the JFrame) and is designed to be used as an output window (i.e. whatever calculations are performed in different JPanel classes, the result should be appended to this output windows JTextArea).
My question is, how do I access this JDialog from my other classes? I don't want to instanciate another Jdialog but use the existing window... I have getters and setters for the JDialog but I am a little lost on how to get the connection between the instance of my OutputWindow class in the Main java file and the other JPanels that house the different parts of my application.
Appreciate the help.
If what you want is just provide access to an inner class from classes defined elsewhere, as long as it is public and static you should be able to it.
If you are going to have just the one instance throughout all your project you should use the Singleton pattern to properly ensure this.
I'm just trying to figure some things out in my head about getting information to and from swing components from other classes.
I have a main class that uses a few classes to build a swing gui. How do I go about writing information to these components from another class. As far as I understand I need to use an arraylist to store references to these components but I'm not exactly sure how to do this, can someone please help me out?
I would suggest that you try to separate the model from the view. Don't store data relevant for the application logic in the actual GUI components.
Storing references to the components in an array list, and then access the data via the array list and various getText methods just seems like a bad idea to me.
Store the values in an object representing some model, and let the GUI reflect the state of the model.
This is one way of accessing another class's methods:
public class MyFrame extends JFrame implements ActionListener
{
private final MyBusinessClass bc = new MyBusnessClass();
#Override public void actionPerformed(ActionEvent e) {
this.bc.someBusinessMethod();
}
}
I was just curious where i should place the main function in a Java Swing program. It seems as If it's just way too short too create a brand new class for.
I would not recommend putting the main method inside of any of your Swing components. It doesn't fit well inside a Swing component because it has nothing to do with the components themselves.
Just create a main method in a separate class. It is alright that it is short.
Mushing the logic for running your program into the display logic seems like too much coupling.
I would not put it in the View class. If you're using MVC, and Swing is the View, then main belongs with Controller. That's the class responsible for starting the app, instantiating the View, and collaborating with Model objects to fulfill the use cases.
The Controller should implement the Listener interfaces, because it responds to Swing events as they occur.
I would not have your View extend JFrame. Make the working bits of Swing extend JPanel. When the Controller instantiates the View, it should create a JFrame, add in the JPanels it needs, register itself as the Listener for all Swing events, and make the JFrame visible. At that point your app is up, running, and ready to go.
Put it into your main JFrame class
public class MyFrame extends JFrame {
public static void main(String args[]) {
new MyFrame();
}
MyFrame() {
// ...
}
}
You can put it in any class. It makes sense to put it in the class that represents your main dialog in your app. There is no need to create a class just for main.