Dispose frame after start frame Java Swing - java

I'm new to Stackoverflow. I have a problem in java/swing with project to school.
The project is a testing service. I want to run an additional window before running the main program that checks the connection to the server. After checking the connection it should start the main window of the program and disappear. If I manually click startProgramButton it's all right. However, if the program is connected to the server at startup, the main window of the program is started, but this window does not disappear.
public class PreForm extends javax.swing.JFrame {
/**
* Creates new form PreForm
*/
MainForm form1;
Settings form2;
public PreForm() {
initComponents();
checkConnection();
}
private void settingsButtonActionPerformed(java.awt.event.ActionEvent evt) {
errorLabel.setText("");
form2 = new Settings();
form2.setVisible(true);
}
private void runProgramButtonActionPerformed(java.awt.event.ActionEvent evt) {
checkConnection();
}
private void checkConnection() {
if (hostAvailabilityCheck()) {
runMainProgram();
} else
errorLabel.setText("<html>Error connect to server!<br>"
+ "Check connect settings and try again!</html>");
}
private boolean hostAvailabilityCheck() {
try (Socket s = new Socket(SettingsFile.getAddress(), Integer.parseInt(SettingsFile.getPort()))) {
return true;
} catch (IOException ex) {
/* ignore */
}
return false;
}
private void runMainProgram() {
this.setVisible(false);
form1 = new MainForm();
form1.setVisible(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new PreForm().setVisible(true);
}
});
}
So, after running the program, the checkConnection method is executed. Then the runMainProgram method is executed. And that's where this.setVisible (false) code comes in, which should hide the window, but it stays. But only if the checkConnection method is started in the constructor. If you run it manually through the startProgramButton, this window is hidden.

Related

Why does my JFrame move to the background after closing modal JDialog

Edit: Updated question including a MRE and an answer can be found here.
I'm pretty lost after stumbling across this issue and finding no way to resolve it myself.
Description:
I have an application which has a Java Swing GUI. All the communication to the GUI is done via custom Events, mostly created by the main program, which are then processed by a Controller to control the GUI.
One event I have will trigger the Controller to open a custom Modal JDialog which acts just as a "please wait while the stuff in the background is being processed". So after the background task is finished, an Event will trigger the Dialog to dispose, to make the main GUI frame accessible again.
The issue:
When the Dialog is disposed, the main Frame will magically be set to the background. Not minimized, not completely in the background of all open windows, but actually in the background of the last open window. I'm completely lost on how and why this happens.
The important parts of the Controller class look vaguely like this:
class Controller {
private ModalWaitDialog dialog;
private JFrame frame;
private void createMainFrame() {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
// create frame
frame = new JFrame();
// make the frame visible
frame.setVisible(true);
}
});
}
private void showWaitPopup(String msg) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
modalWaitDialog = new ModalWaitDialog(frame, message);
modalWaitDialog.showDialog();
}
});
}
// after this was executed, my frame will be set in the background
private void endWaitPopup() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
if (modalWaitDialog != null) {
modalWaitDialog.dispose();
modalWaitDialog = null;
}
}
});
}
}
I know this is not a MCVE, but maybe somebody knows how and why this happens.
Edit:
I added a WindowFocusListener to the Frame and added some print statements to the endWaitPopup, and called invokeAndWait to further see what is happening. The following is the result:
private void endWaitPopup() {
System.out.println("In EndWaitPopup");
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
System.out.println("EndWaitPopup... run started");
// implement as if it could be called if no wait popup is available
if (modalWaitDialog != null) {
System.out.println("Disposing the modal dialog");
modalWaitDialog.dispose();
modalWaitDialog = null;
}
System.out.println("End of EndWaitPopup");
}
});
} catch (InvocationTargetException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Output:
In EndWaitPopup
+++Focus of Frame lost+++
EndWaitPopup... run started
Disposing the modal dialog
End of EndWaitPopup

How force the program wait a Task and show Progress Bar to user?

I use Swing Application Framework in my program. And I have some long-time work. I use org.jdesktop.application.Task for it. Another programmer wrote two Tasks before I took this project (I can not ask him about the programm). When Tasks are executing user sees progress bar without showing percent complete, but what shows "Wait" message and user can not click to a main window while Task does not ended. It is fine! But I could not find place where ProgressBars was created. May be it is described in some xml-file or property-file?
Also I wrote another Tasks and when they run, progress bar which I created is not displayed or displayed incorrectly. I read about ProgressBar and ProgressMonitor, but it does not help me.
Programm continue to run after someTask.execute(), but I want to it displays ProgressBar, ProgressMonitor or something else and user can not click the main window and window will display correctly. Now window has black "blocks" when user change it.
May be I need use org.jdesktop.application.TaskMonitor. I try to use it as here https://kenai.com/projects/bsaf/sources/main/content/other/bsaf_nb/src/examples/StatusBar.java?rev=235 , but my main window is displayed incorrectly and my ProgressBar is not displayed.
I need to when Task is running program waits it, but user can see ProgressBar, can cancel the operation and can not click to the main window. How can I do it?
Here my code:
public class A{
#Action(name = "ActionName", block = Task.BlockingScope.APPLICATION)
public RequestInfoTask requestInfo() {
RequestInfoTask task = new RequestInfoTask(Application.getInstance());
isSuccessedGetInfo=false;
task.addTaskListener(new TaskListener.Adapter<List<InfoDTO>, Void>() {
#Override
public void succeeded(TaskEvent<List<InfoDTO>> listTaskEvent) {
isSuccessedGetResources=true;
}
});
//Here I want to the program shows ProgressMonitor and user can not click to the main window.
//But small window with message "Progress..." is displayed for several seconds and disappear.
ProgressMonitor monitor = new ProgressMonitor(getMainView(), "Wait! Wait!", "I am working!", 0, 100);
int progress = 0;
monitor.setProgress(progress);
while(!task.isDone()){
monitor.setProgress(progress+=5);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
monitor.setProgress(100);
//This code must run after "task" finishes.
if(isSuccessedGetInfo){
MyTask2 task2 = new MyTask2(Application.getInstance());
isSuccessedTask2=false;
task2.addTaskListener(new TaskListener.Adapter<Map<?,?>, Void>(){
#Override
public void succeeded(TaskEvent<Map<String, ICredential>> arg0) {
isSuccessedTask2=true;
}
});
//Do something with results of task2.
}
return task;
}
}
public class RequestInfoTask extends Task<List<InfoDTO>, Void> {
public RequestInfoTask(Application application) {
super(application);
}
#Override
protected List<InfoDTO> doInBackground() throws Exception {
List<InfoDTO> result = someLongerLastingMethod();
return result;
}
}
Part of your problem sounds like it comes from not using the EDT correctly. Any long running task needs to be started in it's own thread to keep the GUI responsive and repainting.
Ideally you'd be following a MVC pattern. In that case you place your Progress Bar in the view, your flag (that indicates whether the task should be running still) in the control, and your long running task in in the Model.
From that point, if your model checks periodically if it should stop (Probably at good stopping points), you can reset everything.
Here's an example with MVC:
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
public class ProgressBarDemo{
public static class View extends JPanel{
Controller control;
public JProgressBar progressBar = new JProgressBar(0, 100);
JButton button = new JButton("Start Long Running Task");
public View(Controller controlIn){
super();
this.control = controlIn;
setLayout(new BorderLayout());
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
//Toggle between running or not
if(control.isRunning){
control.isRunning = false;
button.setText("Canceling...");
button.setEnabled(false);
} else{
control.isRunning = true;
button.setText("Cancel Long Running Task");
control.startTask();
}
}});
progressBar.setStringPainted(true);
add(progressBar);
add(button, BorderLayout.SOUTH);
}
}
//Communications gateway
public static class Controller{
View view = new View(this);
boolean isRunning = false;
public void updateProgress(final int progress){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
view.progressBar.setValue(progress);
}});
}
public void reset(){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
isRunning = false;
view.button.setText("Start Long Running Task");
view.progressBar.setValue(0);
view.button.setEnabled(true);
}});
}
public void startTask(){
LongRunningClass task = new LongRunningClass(this);
new Thread(task).start();
}
}
public static class LongRunningClass implements Runnable{
Controller control;
public LongRunningClass(Controller reference){
this.control = reference;
}
#Override
public void run() {
try {
for(int i = 0; i < 11; i++){
//Monitor the is running flag to see if it should still run
if(control.isRunning == false){
control.reset();
break;
}
control.updateProgress(i * 10);
Thread.sleep(3000);
}
control.reset();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
// Create and set up the window.
JFrame frame = new JFrame("LabelDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add content to the window.
frame.add(new Controller().view);
// Display the window.
frame.pack();
frame.setVisible(true);
}
}

Java Threading Issue with run()

I have 2 classes defined below:
public class TextsManager extends Thread {
LinkedList<String> lstOfPendingStr = new LinkedList<String>();
boolean stopLoop = false;
JTextArea txtArea;
public void run()
{
while (!stopLoop)
{
while (!lstOfPendingStr.isEmpty())
{
String tmp = lstOfPendingStr.getFirst();
this.txtArea.append(tmp);
lstOfPendingStr.removeFirst();
}
try {
Thread.sleep(0); // note: I had to force this code
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void AddNewStr(String newStr)
{
this.lstOfPendingStr.add(newStr);
}
}
And
public class ClientApp {
private JFrame frame;
private JTextField textField;
private JTextArea textArea;
static private TextsManager txtManager;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ClientApp window = new ClientApp();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ClientApp() {
initialize();
/*
* Client app
*/
txtManager = new TextsManager(textArea);
txtManager.start();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
textArea = new JTextArea();
textField = new JTextField();
textField.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
txtManager.AddNewStr(textField.getText() + "\n");
textField.setText("");
}
}
});
}
}
The program will read User Input from textField, pass it into TextsManager.lstOfPendingStr. Then, on each loop inside TextsManager.run(), it will check for existed members in lstOfPendingStr and output them via txtArea.
The problem is that if I removed the code Thread.sleep(0) inside run(), the run() then apparently stopped working. Despite lstOfPendingStr had been successfully updated with new elements, codes inside the loop while(!lstOfPendingStr.isEmpty()) would not ever to be called.
I put hard codes such as System.out.println or Thread.sleep(0) (as in the provided code) inside the while(!stopLoop), then it worked fine.
Although, I managed to solve the problem by forcing the thread to sleep for a few miliseconds, I want to know the reason behind this issue.
I appreciate your wisdom.
Regard :)
You have a couple of problems.
You are calling methods on lstOfPendingStr from two threads, but initialized it with LinkedList, which is not thread-safe. You should use a thread safe class, LinkedBlockingQueue seems the best options as far as I understood from your code.
Inside the thread you are calling JTextArea#append(). As all AWT/Swing methods, you can not call them from arbitrary threads, but only from the AWT thread. Wrap the call inside an invokeLater block.
The fact that sleep appears to make your code work is just a sign of the concurrency problems.

closing jframes current window and not the entire application

i need to close my applications current window without switching off the entire application my code is as follows to set a window visible but it closes all the windows whatever are currently open when i click on the right upper corner red cross button
private void lb_helpMouseClicked(java.awt.event.MouseEvent evt) {
new Reports().setVisible(true);
}
private void lb_certMouseClicked(java.awt.event.MouseEvent evt) {
new ChooseCert().setVisible(true);
}
private void lb_reportMouseClicked(java.awt.event.MouseEvent evt) {
new Reports().setVisible(true);
}
public void closeWindow() {
WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
setVisible(false);
dispose();
}
public void closeApplication() {
System.exit(0);
}
After that just call the appropriate methods.

NetBeans Platform do nothing on close

I am buliding an NetBeans Platform application. When the user clicks on the X of the main window I want the application to do nothing and show a password JDialog. If the password is correct close the app, else do not close the app. How do I do this? I've created a Listener class that will show the password JDialog, but how do I stop the application from closing? Similar to JFrame's setDefaultCloseOperation, and setting it to do nothing on close.
public class Listener extends WindowAdapter {
private Frame frame;
#Override
public void windowActivated(WindowEvent event) {
frame = WindowManager.getDefault().getMainWindow();
frame.setSize(946, 768);
}
#Override
public void windowClosing(WindowEvent event) {
ShutDownMainWindowJDialog shutDownMainWindowJDialog;
shutDownMainWindowJDialog = new ShutDownMainWindowJDialog(null, true);
shutDownMainWindowJDialog.exeShutDownMainWindowJDialog();
shutDownMainWindowJDialog.setLocationRelativeTo(frame);
shutDownMainWindowJDialog.setVisible(true);
}
}
public class Installer extends ModuleInstall {
#Override
public void restored() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Frame frame = WindowManager.getDefault().getMainWindow();
frame.addWindowListener(new Listener());
}
});
}
}
It is easy. So create module with installer and overwrite method closing (may by), then show your dialog and return false (not close app). Jirka
So this is conclusion:
add to your module installer/activator
package master;
import org.openide.modules.ModuleInstall;
/**
* Manages a module's lifecycle. Remember that an installer is optional and
* often not needed at all.
*/
public class Installer extends ModuleInstall {
#Override
public void close() {
//your module shutdown
}
#Override
public boolean closing() {
// this is place for your Dialog() and return:
//
// true if you want to enable close the app
// other return false
/*
if you force shutdown app try LifecycleManager.getDefault().exit();
System.exit(0) is very dummy, because it does not respect betweenmodule dependencyis
}
}
Jirka
In your windowClosing() get the password from the user and dispose() the frame if it is correct.
public class PasswordToClose extends WindowAdapter {
private JFrame frame;
public PasswordToClose(JFrame frame) {
this.frame = frame;
}
public static void main(String[] args) {
JFrame frame = new JFrame("Password to close");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new PasswordToClose(frame));
frame.setSize(200, 200);
frame.setVisible(true);
}
#Override
public void windowClosing(WindowEvent evt) {
String password = JOptionPane.showInputDialog(frame, "Enter password");
if ("secret".equals(password)) {
frame.dispose();
}
}
}

Categories

Resources