How can I handle when I change the screen - java

I try build the 2 Class: LoginScreen Class and MainScreen Class
When I run program it will show the login screen first then I use username and password to login the Mainscreen are pop-up but the login screen doesn't disappear.I am not sure how to handle it correctly.
Because the method I use is
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (OK.equals(cmd)) { //Process the password.
char[] input = passwordField.getPassword();
if (isPasswordCorrect(input)) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrameExample.main(null);
}
});
} else {
JOptionPane.showMessageDialog(controllingFrame,
"Invalid password. Try again.",
"Error Message",
JOptionPane.ERROR_MESSAGE);
}
//Zero out the possible password, for security.
Arrays.fill(input, '0');
passwordField.selectAll();
resetFocus();
} else { //The user has asked for help.
JOptionPane.showMessageDialog(controllingFrame,
"You can get the password by searching this example's\n"
+ "source code for the string \"correctPassword\".\n"
+ "Or look at the section How to Use Password Fields in\n"
+ "the components section of The Java Tutorial.");
}
}
I know this is the stupid code and wrong way to implement it but can you guide me to make the appropriate one.

I guess this method is a method of your first screen, which must be a JDialog or a JFrame. Just call setVisible(false) to hide the frame (you may also call dispose() if the dialog won't be used anymore).
Also, you shouldn't call the main method on JFrameExample. A main method is normally used to start a new application. Just do what the main method does from your action listener (probably new JFrameExample().setVisible(true)).
Finally, an event listener is always invoked in the event dispatch thread (EDT), so there is no point in using SwingUtilities.invokeLater from an event listener.
To recap, here's how the code should look like:
if (isPasswordCorrect(input)) {
setVisible(false); // or dispose();
JFrame mainFrame = new JFrameExample();
mainFrame.setVisible(true);
}

Related

Java: How to wait for the listener to execute the next line?

I have a problem because I have the next code in my main class:
SelectCalculatorWindow selectCalculatorWindow = new SelectCalculatorWindow();
CalcWindow calcWindow;
if (selectCalculatorWindow.getOption() == SelectCalculatorWindow.BASIC_OPTION) {
calcWindow = new CalcWindow(0);
} else if (selectCalculatorWindow.getOption() == SelectCalculatorWindow.PSEUDOSCIENTIFIC_OPTION) {
calcWindow = new CalcWindow(1);
}
And, in other class (SelectCalculatorWindow), I have this:
public SelectCalculatorWindow() {
initComponents();
instantiateListener();
}
private void instantiateListener() {
acceptBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(basicCalculatorRbtn.isSelected()) {
setOption(BASIC_OPTION);
} else if (pseudoscientificCalculatorRbtn.isSelected()) {
setOption(PSEUDOSCIENTIFIC_OPTION);
}
setVisible(false);
}
});
}
So, I want that condition sentences that I wrote in the main class execute only if user click the button, and I don't know how to do it
You haven't posted a valid minimal reproducible example program yet, and so I can only guess, but having said that, my guess is that SelectCalculatorWindow creates and displays a JFrame which is a non-modal application window, which is not what you want. Instead you will want to display a modal child-window, or dialog, such as a modal JDialog. When you use this, it pauses application code flow in the calling code until the dialog has been dealt with, and so allows your program to pause waiting for the user to make their selection, and then resume the code once the selection has been made.
A JOptionPane is an example of a type of modal dialog, but using a JDialog, you can create windows as varied and flexible as a JFrame, but with the advantages noted above.

On closing the main Swing window, the other thread on the EventQueue gets not created

I write Java SE 8 desktop application. It's got a Swing UI.
Platform:
Eclipse IDE
Windows 10 OS
Now when I close the main window, by pressing on the "X" on the top-right-corner, I have a listener to listen for such event.
The listener right here:
private void listenerForClosingResources(){
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
if(e.getID() == WindowEvent.WINDOW_CLOSING){
CountDownLatch continueOn = new CountDownLatch(1);
saveUnsavedTmpProject(continueOn);
try {
continueOn.await();
}
catch(InterruptedException ee) {
ee.printStackTrace();
}
}
}
});
}
So, I use the listener to identify the window closing event, and when that happens I ask the user whether or not to save the project (it's data on DB).
This method (saveUnsavedTmpProject(continueOn);) leads to the other window which supposed to take the name under which to save the project.
Now the CountDownLatch forces the main window to stay up, up till when the user confirms/rejects saving the project on the other panel.
The other class method which creates the window, leading to saving the project, is right here:
public static void getInstance(CountDownLatch continueOn, String openProjectName) {
if(frame == null) {
synchronized(SaveAsPane.class) {
if(frame == null) {
carryOn = continueOn;
if(!openProjectName.isEmpty()){
openProject = openProjectName;
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new SaveAsPane();
frame.setVisible(true);
frame.setLocationRelativeTo(MainGUI.getMainGUI());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
}
Now, when I run the app, I don't get inside the run() method (and no window pops-up). But that only happens when I access this method only from the mentioned above listener. Which has the CountDownLatch, and it appears that it stops the execution of the new thread.
The latch gets counted-down when the user confirms/denies saving the project, so that the execution flow continues on.
Yet, I create the additional thread on the EventQueue.
How come that the thread gets stopped?
The Java group on facebook.com pointed me to the right direction.
The solution is this:
redefine what the close button (X) does on the main GUI.
And here it comes:
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
And now when I click the main GUI window's close button, the close does not lead to closing the window. Meaning that I don't need any longer the CountDownLatch class, which was stopping the main window from closing up (and waiting till the user counts-down on the other class).
In the end, I made the app to work in the way I like.

Delay processing until GUI input

Following is the code to input proxy settings from user.
public static void setProxy()
{
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new proxy().setVisible(true);
}
});
// Control should halt here till user gives input as it assigns value to the variables
String host = prox;
String port = prt;
System.out.println("Using proxy: " + host + ":" + port);
You're not doing it correctly. The main method of a GUI application should do only one thing: start the GUI. The rest of the logic will be triggered by events fired by the user interacting with the GUI.
So, assuming your GUI displays a frame containing 2 text fields to enter the host and the port and a button to proceed, you should have, in your GUI, an action listener on the button:
proceedButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String host = hostTextField.getText();
String port = portTextField.getText();
doSomethingWithHostAndPort(host, port);
}
});
If doSomethingWithHostAndPort() does domething long, then it should do it in a separate thread, to avoid freezing the GUI.
You need to provide more information if you want a precise answer. But I'm going to make a few assumptions, you have a button which is pressed after information is entered, that button has an on click event attached to it, that is where you add your variable assignments and start the processing.

Show popup at the start if file is missing

I am creating a small GUI java application that it will store some user credentials in a file.
If the file is missing or has the wrong properties then I want a pop to get brought up that will inform the user to register his credentials (so a new file can be created with the proper ones).
I have nailed down the logic of when the file is incorrect and/or missing but what I can't figure out (due to my inexperience with JFrame) is where exactly in the code to check if the user needs to enter his credentials so he can be prompted.
Let's say that the function showWarning() is the one that will check and display the popup if needed and this is my main JFrame function (this was generated from Netbeans mostly):
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
}
});
}
Do I put the showWarning() function inside the main function? If yes, do I put it right after new GUI().setVisible(true);? What is the proper way of doing this?
EDIT: I am stumbling to the same problem I did before. This is my showWarning() that I drafted quickly for testing purposes:
public void showWarning(){
File propertiesFile = new File("config.properties");
if (propertiesFile.exists() && propertiesExist(propertiesFile)) {
JOptionPane.showMessageDialog(rootPane, "Creds are ok");
} else {
JOptionPane.showMessageDialog(rootPane, "Creds are not ok");
}
}
The problem that I am having is that I can't make this method static in order to use it without an object because of the rootPane which is a non-static object. The problem that this caused is that I can't just write:
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
showWarning();
}
});
}
I can't use showWarning() like that since it's a non-static method.
Do I need to have the GUI object in a variable properly or is there a way to make the showWarning() a static method?
If you want the check to run right when the program starts, you would want to put your function call after the main JFrame gui is set visible. See edited code below. Of course, I'm using the ambiguous showWarning() function here, but you should talor that line of code to your need. If calling a function, then right the function, but if wanting to call a new popup jframe you will need to do more lines of code there.
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
LoginForm login = new LoginForm();
login.setVisible(true);
}
});
}
Now here you would want to change the variables accordingly. The LoginForm is a Jframe already created.
You probably want your popup dialog to be modal, so the program does not continue until the user has handled and fixed the problem. To do this, do not use a JFrame but a JDialog for your popup dialog and make it modal. Then you can simply put the showWarning() call everywhere you want. I think I would put it inside the main.
Use JDialog for creating the pop up.
And either you add the showWarning() method call in main like this :
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
showWarning();
}
});
}
or better you can invoke the method showWarning() when the user credentials have to be enetered in the file. If checked just before it, it would be optimal.

Modal dialogs in IE gets hidden behind IE if user clicks on IE pane

I have to write an applet that brings up a password dialog. The problem is that dialog is set to be always on top but when user clicks on IE window dialog gets hidden behind IE window nevertheless. And since dialog is modal and holds all IE threads IE pane does not refresh and dialog window is still painted on top of IE (but not refreshed). This behaviour confuses users (they see dialog on top of IE but it looks like it has hanged since it is not refreshe).
So I need a way to keep that dialog on top of everything. But any other solution to this problem would be nice.
Here's the code:
PassDialog dialog = new PassDialog(parent);
/* do some non gui related initialization */
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
Resolution: As #shemnon noted I should make a window instead of (null, Frame, Applet) parent of modal dialog. So good way to initlialize parent was:
parent = javax.swing.SwingUtilities.getWindowAncestor(theApplet);
What argument are you using for the parent?
You may have better luck if you use the parent of the Applet.
javax.swing.SwingUtilities.getWindowAncestor(theApplet)
Using the getWindowAncestor will skip the applet parents (getRoot(component) will return applets). In at least some versions of Java there was a Frame that was equivalent to the IE window. YMMV.
Make a background Thread that calls toFront on the Dialog every 2 seconds.
Code that we use (I hope I got everything):
class TestClass {
protected void toFrontTimer(JFrame frame) {
try {
bringToFrontTimer = new java.util.Timer();
bringToFrontTask = new BringToFrontTask(frame);
bringToFrontTimer.schedule( bringToFrontTask, 300, 300);
} catch (Throwable t) {
t.printStackTrace();
}
}
class BringToFrontTask extends TimerTask {
private Frame frame;
public BringToFrontTask(Frame frame) {
this.frame = frame;
}
public void run()
{
if(count < 2) {
frame.toFront();
} else {
cancel();
}
count ++;
}
private int count = 0;
}
public void cleanup() {
if(bringToFrontTask != null) {
bringToFrontTask.cancel();
bringToFrontTask = null;
}
if(bringToFrontTimer != null) {
bringToFrontTimer = null;
}
}
java.util.Timer bringToFrontTimer = null;
java.util.TimerTask bringToFrontTask = null;
}
This is a shot in the dark as I'm not familiar with applets, but you could take a look at IE's built-in window.showModalDialog method. It's fairly easy to use. Maybe a combination of this and Noah's suggestion?
You might try launching a modal from JavaScript using the JavaScript integration (see http://www.raditha.com/java/mayscript.php for an example).
The JavaScript you would need would be something like:
function getPassword() {
return prompt("Enter Password");
}
And the Java would be:
password = jso.call("getPassword", new String[0]);
Unfortunately that means giving up all hope of having a nice looking modal. Good luck!

Categories