I have a button in a JFrame, if pressed, it takes us to another frame.
I used this code:
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
SecondForm secondform = new SecondForm();
secondform.setVisible(true);
setVisible(false);
dispose();
}
So the new frame opens and everything is ok. Then i placed another button -in the second frame- in order to go back to the previous frame. I used this code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
MainForm Mform = new MainForm();
Mform.setVisible(true);
setVisible(false);
dispose();
}
The thing is, i don't think this is the right way to do this. What i want is to:
hide the first frame
show the new second one
dispose the second one
show again the first
Is there a way to do that using the first MainForm instance and not creating a new one every time i want to go back.
I monitored my program and every time i go back and forth the frames and as i suspected, the ram being used by it keeps increasing.
Thanks in advance.
EDIT : I have a login system and when the user put the correct credentials a new ManiForm instance is created.
MainForm Mform = new MainForm();
Mform.setVisible(true);
That is the instance i want to use. Ii there a way to make MForm visible again from the secondform?
First of all thanks for the help!
I agree that it is easier not to use more than one JFrames, but can you please tell me which is the better way to do what i asked in the first post?
The answer Robin gave me is very nice but i don't know what to put as an argument there*:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
* new SecondForm().setVisible(true);
}
});
It's from the auto-generated code from NetBeans.
I tried
new SecondForm(super).setVisible(true);
but i still get compile errors. Apparently i must put super.something() but i don't know what. I tried many but no luck.
you shouldn't use more then one frame.
You should have NOTHING in JFrame except defaultExitOperation, size, preferedsize and visible true.
Instead place all buttons and fields into a JPanel and add/remove the JPanel from the JFrame.
If you want another Window open use JDialog.
btw: you can have your MainFrame setVisible false and open a JDialog with your MainFrame as parent. Only if someone writes down the right user + password you make the MainFrame visible.
For swing applications, the standard is to use a STATIC MAIN FRAME, in other words, make your main frame (mframe) static and add methods to pop-up new frames, dialogs, optionPanes, etc. You can even control the visibility of the main frame throw static calls. That's the way you implement a UNIQUE FRAME for your application, even tho you instance other frames for navigation, all child frames can refer to the main frame without the need of passing it as parameter to constructors or creating new instances of it.
The Main Class
`/* to start the application */
public class Main{
public static MainFrame MFRAME;
public static void main(String[] args){
/*use this for thread safe*/
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Main.MFRAME = new MainFrame(/*init parms to constructor*/);
}
});
}
}
`
The Main Frame
`/* to create the main frame */
public class MainFrame extends JFrame{
public MainFrame(/*your constructor parms*/){
/* constructor implementation */
}
public void openOtherFrame(/*your parms*/){
OtherFrame oFrm = new OtherFrame(/*your parms*/);
}
/* other methods implementation */
}
`
The child frame
`/* to open child frames controling the visibility of the main frame*/
public class OtherFrame extends JFrame{
public OtherFrame(/*your constructor parms*/){
/* hide main frame and show this one*/
Main.MFRAME.setVisible(false);
this.setVilible(true);
/* do something else */
/* show main frame and dispose this one*/
Main.MFRAME.setVisible(true);
this.dispose();
}
/* other methods implementation */
}
`
If you pass your MainForm to the SecondForm class (for example using a constructor parameter) the SecondForm instance can make the original MainForm instance visible again instead of creating a new one.
For example
public class SecondForm extends JFrame{
private final MainForm mainForm;
public SecondForm( MainForm form ){
mainForm = form;
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
mainForm.setVisible(true);
setVisible(false);
dispose();
}
}
and in your MainForm class
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
SecondForm secondform = new SecondForm( this );
secondform.setVisible(true);
setVisible(false);
dispose();
}
Related
I am trying to implement mouse listener however I can not seem to get it to work. My code doesnt have any errors, but when I click on the frame I I can not get a message to print out. I have tried extending the class HandleClassOne to viewOne, but that also wouldn't work. Any thoughts?
The main class creates a frame and then creates an instance of viewOne on the frame.
public class main{
protected static JFrame window;
public static void main(String args[]){
window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(400,400);
window.setVisible(true);
new viewOne(window);
}
}
The viewOne class adds a panel and a label to a frame. It also adds a mouse listener to the panel.
public class viewOne {
private static JPanel panel1;
private static JLabel label1;
public viewOne(JFrame frame) {
panel1 = new JPanel();
label1 = new JLabel("View One");
panel1.add(label1);
frame.add(panel1);
panel1.setBackground(Color.red);
frame.validate();
}
public static void mouseAdd() {
HandleClassOne handle = new HandleClassOne();
panel1.addMouseListener(handle);
panel1.addMouseMotionListener(handle);
}
public static void main(String[] args) {
mouseAdd();
}
}
The HandleClassOne class should print out a message when the panel created in viewOne is clicked.
public class HandleClassOne extends main implements MouseListener, MouseMotionListener {
public void mouseClicked(MouseEvent e) {
System.out.println("mouse clicked");
}
}
While you have defined the function mouseAdd(...) I don't see you calling it.
Try (within the constructor)
public viewOne(JFrame frame) {
...
mouseAdd();
...
}
naturally, you'll need to do this after the panel1 is set.
Note that there are other issues, too
You don't invoke presenting the JFrame properly within your main function in your main class. Look up a basic tutorial on Java Swing, where it talks about the event dispatch thread and the requirements to not present within your program's main thread of execution.
You have an additional main function in your viewOne class, which is not how these things are wired up.
You added the mouseAdd() method (which is responsible for registering the mouse listener) inside the main method of viewOne class.
Please keep in mind that main method only gets called whenever you are running it as entry point class for your application. Here you have main class to act as an entry point.
You kept main method in viewOne class as well and it will get called only when you are running it as an individual piece (not along with main class).
To fix the issue here, keep your mouseAdd() method call inside viewOne() constructor as constructor gets called every time whenever object is getting created.
public viewOne(JFrame frame) {
panel1 = new JPanel();
label1 = new JLabel("View One");
panel1.add(label1);
frame.add(panel1);
panel1.setBackground(Color.red);
mouseAdd();
frame.validate();
}
I have this code sample. And I needed to change the background color of the JFrame when run the application.
But when I call the create a object of the class and call it with it's reference variable, the JFrame isn't showing up (I think it is stucked or something) I cannot even see the java icon in my taskbar.
Here's my code (Only the constructor of the class)
package lockme;
import java.awt.Color;
import javax.swing.JFrame;
public class MainWindow extends javax.swing.JFrame {
public MainWindow() {
initComponents();
MainWindow m=new MainWindow();
m.setSize(1368, 768);
m.getContentPane().setBackground(new Color(10, 20, 30));
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
MainWindow m=new MainWindow();
m.getContentPane().setBackground(new Color(100, 40, 20));//This is not working
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainWindow().setVisible(true);
}
});
}
}
`
But it shows the JFrame when I alter the code above like this:
package lockme;
import java.awt.Color;
import javax.swing.JFrame;
public class MainWindow extends javax.swing.JFrame {
public MainWindow() {
initComponents();
//MainWindow m=new MainWindow();
this.setSize(1368, 768);
this.getContentPane().setBackground(new Color(10, 20, 30));
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
//MainWindow m=new MainWindow();
this.getContentPane().setBackground(new Color(100, 40, 20));//This isworking
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainWindow().setVisible(true);
}
});
}
}
Can anyone please tell me what's wrong here?
That's because you get stuck in an infinite loop by creating a new object of MainWindow inside the constructor of MainWindow, essentially trying to create an infinite amount of new Frames.
Since you're already inside the constructor of MainWindow you don't need to instantiate MainWindow again.
Your 2nd code shows the JFrame because this is the actual way it needs to be done.
In your 1st code, MainWindow() itself is a constructor whereas you are again calling another instance of MainWindow inside the same constructor which is completely wrong.
And guess what, you are calling the MainWindow again and again in its own constructor as it will work as infinite loop. That's why you stuck up there.
A constructor in Java is a block of code similar to a method that’s
called when an instance of an object is created.
But you need not to create the instance of the object inside the own constructor of any class.
Edit:
There are several mistakes in your 1st code snippet. Let me clear those for you:
MainWindow m=new MainWindow(); inside the constructor MainWindow(). It is totally illegal as I have mentioned earlier that it turns into an infinite loop.
So, the correct way of doing this is mentioned in your 2nd code snippet.
this.getContentPane().setBackground(new Color(10, 20, 30));
N.B.: By declaring above line inside constructor means it will show that during runtime.
Inside jButton2ActionPerformed(java.awt.event.ActionEvent evt) method, you are calling another object of MainWindow. This will run the code well but will not work as you wanted. Look here you are creating another object of that class. But may be you didn't want this. Now let me clear this by example:
Assume, at first in the constructor you have mentioned RED color in the setBackground() method. And then created another object of MainWindow inside jButton2ActionPerformed() and provided color BLUE as setBackground() . Now you run the program. The program initially runs well showing you the RED background colored Frame. But when you click on the button, guess what will happen. That red colored JFrame will remain as it is and as you are creating another instance of that class on button action, then after clicking on the button another new JFrame will appear having the color BLUE. And after you click the button for infinite no. of time, an infinite no. of new JFrame will be created. May be nobody wants that in any program unless any special case.
What I have:
Two Classes that instantiate two JFrames.
What I am trying to achieve:
One with a button and the other that will become invisible when a action is fired on the button.
Problems:
I do not know how to pursue this. How should I go about coding this?
Class 1
public class test1{
public static void main(String[] args){
JFrame frame = new JFrame("Blinkly Frame");
frame.setSize(100, 100);
frame.setVisible(true);
}
}
Class 2
public class test2{
public static void main(String[] args){
JButton button = new JButton();
//when i will click this button i want to make invisible frame
}
}
Solution:
Create an instance of the class that has a Jframe or extends a JFrame.
First we need the JFrame that will be disappearing.
public class BClass extends JFrame{
// Disappearing frame
public BClass()
{
this.setSize(300,300);//sets frame properties
this.setLocationRelativeTo(null);
}
}
Next we need the Frame that will be holding the buttons. (Documentation added)
public class ACLass {
public static void main(String[] args) {
JFrame frame = new JFrame("Magician"); // instantiates
BClass b = new BClass(); // instantiates class that extends JFrame
b.setVisible(true);//
frame.setSize(300,300);//
frame.setVisible(true);//
frame.setLocationRelativeTo(null);//
JButton disappearButton = new JButton("Disappear"); //Adds button
disappearButton.addActionListener(new ActionListener() { // Adds action -When button is "clicked"
public void actionPerformed(ActionEvent e) { // method called when action fired
b.setVisible(false); //visibility changed
}
});
disappearButton.setBounds(0,0,300,150);
JButton appearButton = new JButton("appear"); //Adds button
appearButton.addActionListener(new ActionListener() { // Adds action -When button is "clicked"
public void actionPerformed(ActionEvent e) { // method called when action fired
b.setVisible(true); //visibility changed
}
});
disappearButton.setBounds(0,100,300,150);
frame.add(disappearButton, BorderLayout.PAGE_START); //adds button to frame
frame.add(appearButton, BorderLayout.PAGE_END); //adds button to frame
//I used border layout however use the a layout manager that works with your components/frame
}
}
Exotic Explanation
I'm going to explain this in terms of a magic show as it provides better understanding.
So first, we have one magician(JFrame) and his wand(JButton) and then we have the helper(the second JFrame) that will disappear and a stage that has been set(all properties defined etc.)
First the magician adds some magic power to his wand(actionListener that handles the button being pushed) that will react when the magician waves it(action fired a.k.a button being pushed).
Next we show the audience the helper(instantiating JFrame to disappear).
As we have shown the audience the helper, we can now show him/her disappearing (Now we can call setVisible through the instance variable of the class).
Finally, the magician waves his wand(firing an action), and the helper gets the signal(actionPerformed method) to disappear. The helper then can call the
b.setVisible(false); //making the frame invisible
General Explanation
https://docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html
Basically, by instantiating an object in another class you can also call the objects methods in that class i.e. setVisible(boolean b).
Other less preferable solutions:
If your disappearing class has does not extend a JFrame but instantiates one..
You would need to create an instance variable
private JFrame j;
Then use getters/setters to access the object which will then allow you to call its methods.
secondClass.getFrame().setVisible(true);//getFrame returns the JFrame
Then add that to the actionPerformed method.
You can also use a static instance variable and statically reference it in the actionPerformed method... (not recommended)
secondClass.frame.setVisible(true);
so I got this in my Main class:
public class Main extends JFrame {
public static void main(String[] args) {
JFrame Launch = new JFrame();
Launch.setSize(800, 400);
Launch.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Launch.setContentPane(new StartView());
Launch.setTitle("De Hartige Hap");
Launch.setVisible(true);
}
}
Now let's say I'm in that Panel ("StartView()")
and onClick on a button, I want to change the frames' contentpane..
How would I do this?
public class StartView extends javax.swing.JPanel {
public StartView() {
initComponents();
}
private void OrderButtonActionPerformed(java.awt.event.ActionEvent evt) {
/*instead of Launch.setContentPane(new StartView());
*it has to be (new otherView())
*/
}
Pass your Launch object to your panel object (i.e. new StartView(launch)). This way, you can create a method changeView() in Launch and you can call this method from your panel (launch.changeView()), you can change your view inside that method.
Also, if I may adivce you, take a look at the ModelViewController pattern. This makes sure you keep the View (your panels) and the Controller (your Frame) seperated so you don't get issues like this.
I have this piece of code:
public class GUI extends JFrame {
private PlaneUI planeui;
public GUI(PlaneUI planeui) {
this.planeui = planeui;
}
//We have put the code that creates the GUI inside a method
public GUI() {
start();
planeui.display();
} ...
This is just a test and I need the method "planeui.display" to work when the program starts, together with the method "start();" which already works.
public final class PlaneUI extends JFrame {
public void display() {
//Creates a new JPanel object
JPanel panelStart = new JPanel();
getContentPane().add(panelStart);
//Changing the default layout from Flowlayout to absolute
panelStart.setLayout(null);
setTitle("Reservationer"); //Sets the window title
setSize(236, 256); //Sets the default size of the window
setLocationRelativeTo(null); //Start location of the window (centered)
setDefaultCloseOperation(EXIT_ON_CLOSE); //Exits the window
}
}
I have imported the needed libraries and I feel like the problem lies in an object that isn't created correctly since I get a nullpointerexception. I tried running this planeUI class in the main method and it worked correctly. I just can't get it to work this way..
In function PlaneUI.display() add one last line setVisible(true) because your adding everything but not displaying anything
you have to add this into your display() method:
setVisible(true);
Otherwise, all you are doing is setting all the aspects of the JFrame and adding the JPanel to it. You have to make it visible afterwards.