I want to show a "Please wait" JFrame while my program copies some files.
Context : I have a first JFrame that allows a user to pick files and then clicks on a button to trigger the copy. This is when I want to display the "Please wait" JFrame and make it disappears when everything is done.
I have succeeded to make this JFrame appeared and disappeared but it is always blank.
The code for the "Please Wait" JFrame :
public class Loader implements Runnable {
JFrame loadingFrame = new JFrame();
#Override
public void run() {
// Parameters for size and position
loadingFrame.setSize(180,100);
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel("Please wait ...", SwingConstants.CENTER), "Center");
loadingFrame.add(panel);
loadingFrame.setLocationRelativeTo(null);
loadingFrame.setVisible(true);
//((JComponent) loadingFrame.getContentPane()).revalidate();
//loadingFrame.repaint();
}
public void destroy() {
loadingFrame.setVisible(false);
loadingFrame.dispose();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Loader());
}
}
As you can see, I tried "repaint()" and "revalidate()" but it didn't work.
I call the Loader class in this function :
public void analyzeAndCopy(){
// Show loading Frame
Loader loader = new Loader();
loader.run();
[... copy code...]
// Hide loading Frame
loader.destroy();
}
The Please Wait JFrame appears blank, and stays (as wanted) while files are being copied and disappears after, but it stays blank all the way. :/
I think it may be related to Thread, I tried to create a 2nd thread to call the JFrame, it didn't work. I'm running out of ideas...
Any help will be much appreciated ! :)
Thanks
try to replace
loader.run();
with
new Thread(loader).start();
and add a line to method run:
loadingFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
and you can use JDialog instead of JFrame
Related
I have created an SSCCE to show my problem
public class TopTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(512, 512);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
This program should create a window that is always on top, however if I run this and then click on another window behind it, the JFrame is sent behind it.
I think the problem is that you have another window that is always on top.So when you click on that this windows loose the focus and goes back.
One easy way if it is a task which needs this window to be on top and Focusable is to frequently check with a Thread maybe:
if(!frame.isFocused()) frame.setFocused(true);
Just something to help....
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.
I am trying to develop a JFrame which has two buttons that would let me to call the main method of other classes. The first try was to put it directly into the actionPerformed of each button, this will cause the JFrame of the other class to open but showing only the title of it and not showing any contents of the JPanel additionally freezing the program (can't even press close button, have to go into task manager or eclipse to kill it). The second try was adding a method call in actionPerformed, and adding the method will this time call the main method of other class however the same result (freeze of program).
For testing purposes I have placed the call to main method of other class, straight in this class main method which has proven to me that the frame of other class has successfully appeared, including all its JPanel contents, functionality etc.
I know I could make some kind of infinite loop in my main method to wait until a boolean is set to true, but then I though there must be some less-expensive way to get it working. So here I am asking this question to you guys.
Here is the code of the 2nd try;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Chat {
public static void main (String[] args) {
JFrame window = new JFrame("Chat Selection");
//Set the default operation when user closes the window (frame)
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set the size of the window
window.setSize(600, 400);
//Do not allow resizing of the window
window.setResizable(false);
//Set the position of the window to be in middle of the screen when program is started
window.setLocationRelativeTo(null);
//Call the setUpWindow method for setting up all the components needed in the window
window = setUpWindow(window);
//Set the window to be visible
window.setVisible(true);
}
private static JFrame setUpWindow(JFrame window) {
//Create an instance of the JPanel object
JPanel panel = new JPanel();
//Set the panel's layout manager to null
panel.setLayout(null);
//Set the bounds of the window
panel.setBounds(0, 0, 600, 400);
JButton client = new JButton("Run Client");
JButton server = new JButton("Run Server");
JLabel author = new JLabel("By xxx");
client.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//run client main
runClient();
}
});
server.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//run server main
}
});
panel.add(client);
client.setBounds(10,20,250,200);
panel.add(server);
server.setBounds(270,20,250,200);
panel.add(author);
author.setBounds(230, 350, 200, 25);
window.add(panel);
return window;
}
private static void runClient() {
String[] args1={"10"};
ClientMain.main(args1);
}
}
Only one main method is allowed per application. Honestly I am not sure what you are trying to do or think is supposed to happen when you call main on other classes. When you call main on other classes all you are doing is calling a method that happens to be called main and passing args to it. Your freezing is probably because you are not using Swing correctly:
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
The problem you're having is that Java Swing is single threaded. When you're running the main function of the other class, however you do it, the GUI won't be able to keep running until it returns. Try spawning off a new thread that calls the second main method.
private static void runClient() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
String[] args1={"10"};
ClientMain.main(args1);
}
});
}
EDIT: Updated, as per #Radiodef's suggestion. Missed at the top when you said this second class had to display things on the GUI. Definitely want to go with the invokeLater then.
I'm trying to add components to a JDialog after it has been created and displayed. Nothing I try makes the changes actually update to the screen, and I've read and applied every question I could find related to this.
This example code creates a modal JDialog showing the word "test". I cannot get it to display "test2". Almost exactly the same code but with a JFrame instead of a JDialog behaves as I expect, so I don't understand. I'm new to Java and especially to swing.
import javax.swing.*;
public class DialogTester {
public static void main(String[] args) {
new DialogTester();
}
public DialogTester() {
JFrame jframe = new JFrame();
jframe.setVisible(true);
JDialog jdialog = new JDialog(jframe,true);
JPanel jpanel = new JPanel();
jpanel.add(new JLabel("test"));
jdialog.add(jpanel);
jdialog.setVisible(true);
jpanel.add(new JLabel("test2"));
jpanel.revalidate();
jdialog.getContentPane().validate();
jdialog.pack();
}
}
I also tried calling
jdialog.repaint();
which did nothing.
You created a modal dialog. So, as soon as you call setVisible(true), the following instructions wait for the dialog to be closed to be executed.
Put the code adding a label before the dialog is made visible, or put it in an event handler called after the dialog is shown, for example, when you click on a button in this dialog.
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();
}