I have a swing JFrame and in a some place of the code i need to display a JOptionPane for the user to select:
if yes - I need ht JFrame to run again and exit the existing one
if no - this is solved I just need to exit.
here is a JFrame code:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainFrame frame = new MainFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
and here is the JOptionPane code which i created:
int ok = JOptionPane.showConfirmDialog(null, "would you like to enable USB in your device?", "USB", JOptionPane.YES_NO_OPTION);
if (ok==JOptionPane.YES_OPTION){
Thread t = new Thread(){
public void run(){
String[] args = { };
MainFrame f = new MainFrame();
f.main(args);
}
}.start();
}
else if(ok==JOptionPane.NO_OPTION){
System.exit(ok);
}
I created the thread and it is opening another JFrame but not closing the existing one!
Thanks for any help :)
Related
Here is the code of my program. Problem is that whenever i close the main GUI
My new thread also exits. Which by definition should not because it is not a daemon thread. I am working in eclipse and any help would be appreciated.
public class HomeScreen extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JTable table;
private JTextField textField_1;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
HomeScreen frame = new HomeScreen();
frame.setVisible(true);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while(true){
System.out.println("Hello");//This should print "Hello" forever but this thread exits after i close main GUI
}
}
});
t.start();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
Thank you all. I got the trick just added a statement to run thread infinitely
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
I have a JPanel with multiple components in it - like a few JLabels, JTextBoxes, JComboBoxes, JCheckBoxes etc.
I want to display a pop up help window if the user hovers over these components for say 3 secs.
So far I added a MouseListener to one of my Components and it does display the required pop up and help. However I can't achieve it after 3 sec delay. As soon as the user moves the mouse to through that area of the component the pop up displays. This is very annoying as the components are almost unusable. I have tried using MouseMotionListener and having the below code in mouseMoved(MouseEvent e) method. Gives the same effect.
Any suggestion on how can I achieve the mouse hover effect - to display the pop up only after 3 sec delay?
Sample Code:(Mouse Entered method)
private JTextField _textHost = new JTextField();
this._textHost().addMouseListener(this);
#Override
public void mouseEntered(MouseEvent e) {
if(e.getSource() == this._textHost())
{
int reply = JOptionPane.showConfirmDialog(this, "Do you want to see the related help document?", "Show Help?", JOptionPane.YES_NO_OPTION);
if(reply == JOptionPane.YES_OPTION)
{
//Opens a browser with appropriate link.
this.get_configPanel().get_GUIApp().openBrowser("http://google.com");
}
}
}
Use a Timer in mouseEntered(). Here's a working example:
public class Test {
private JFrame frame;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Test test = new Test();
test.createUI();
}
});
}
private void createUI() {
frame = new JFrame();
JLabel label = new JLabel("Test");
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent me) {
startTimer();
}
});
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
private void startTimer() {
TimerTask task = new TimerTask() {
#Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JOptionPane.showMessageDialog(frame, "Test");
}
});
}
};
Timer timer = new Timer(true);
timer.schedule(task, 3000);
}
}
JFrames not displaying properly in loop.
Code:-
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class SwingDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
final JFrame jfrm= new JFrame("A Simple Swing Application");
final JFrame jfrm2= new JFrame("A Simple Swing Application 2");
jfrm.setSize(275,100);
jfrm.setLocation(100,100);
jfrm2.setLocation(50,50);
jfrm2.setSize(275,100);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Swing means powerful GUIs.");
jfrm.add(jlab);
JButton button0= new JButton("loop");
jfrm.add(button0);
jfrm.setLayout(new FlowLayout());
JLabel jlab2 = new JLabel("Swing means powerful GUIs again");
jfrm2.add(jlab2);
//jfrm2.setVisible(true);
jfrm.setVisible(true);
button0.addActionListener(new ActionListener() {
private boolean confirmAction;
#Override
public void actionPerformed(ActionEvent e) {
confirmAction = true;
if (confirmAction) {
try {
while(true)
{
jfrm.setVisible(false);
jfrm2.setVisible(true);
try{
Thread.sleep(15000);
}
catch(InterruptedException ie)
{
System.out.println("nothing");
}
jfrm2.setVisible(false);
jfrm.setVisible(true);
}
} catch (Throwable t) {
t.printStackTrace(System.out);
}
}
}
});
}
});
}
}
If the problem is that they are not updating correctly (this is my only thought since you didn't explain the issue), you should try to include these methods in the loop:
validate();
repaint();
If your issue is different, please inform us.
The method
#Override
public void actionPerformed(ActionEvent e) {
...
}
is executed in the EDT. Once you have implemented an infinite loop inside EDT it will stop processing any farther events and your GUI will stop responding.
A possible solution may be to start a timer and on every timer tick post relevant events to EDT, using SwingUtilities.invokeLater() or invokeAndWait():
Replace the contents of actionPerformed(ActionEvent e) with the following:
Timer timer = new Timer(15000, new ActionListener() {
boolean flip = false;
#Override
public void actionPerformed(ActionEvent actionEvent) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
jfrm.setVisible(flip);
jfrm2.setVisible(!flip);
flip =! flip;
}
});
}
});
timer.start();
I'm trying to close a JFileChooser. Could you, please, let me know why the cancelSelection method in the following snippet doesn't make it disappear after 5 seconds:
public static void main(String [] args){
JFrame frame = new JFrame();
frame.setVisible(true);
final JFileChooser fchooser = new JFileChooser();
fchooser.showOpenDialog(frame);
try {Thread.sleep(5000);} catch (Exception e){}
fchooser.cancelSelection();
}
Any help is much appreciated.
You should use a Swing Timer to do this since updates to the GUI should be done on the Event Dispatch Thread (EDT).
You need to start the Timer BEFORE you invoke the showOpenDialog() method.
The call to showOpenDialog() will not return until a selection is made or the dialog is canceled. If you want to close the dialog after a timeout, you will have to do the timing in another thread.
I agree that you should use a Swing Timer, but if you want more logic when to disable/dismiss the dialog (for example a progressbar that should close when no more data is available), either implement a SwingWorker or use the following:
public static void main(String... args) {
JFrame frame = new JFrame();
frame.setVisible(true);
final JFileChooser fchooser = new JFileChooser();
new Thread() {
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// This is run in EDT
fchooser.cancelSelection();
}
});
}
} .start();
fchooser.showOpenDialog(frame);
}
I'm in the process of creating a GUI in Netbeans 6.1 for my senior design project but i've run into an annoying snag. Temporary Windows like my login PopUp and others wont disappear when i tell it. I've been researching how to solve this for about 2 months on an off. I've even mad a separate thread for my Pop Up but it still wont work....the only way it will disappear if i literally dont mess with any of the other GUI components....my sample code should help describe my anger...dont mind the shadow code, it was for testing purposes, which obviously didnt help.
//This method is called once a user presses the "first" login button on the main GUI
public synchronized void loginPopUpThread() {
doHelloWorld = new Thread(){
#Override
public synchronized void run()
{
try
{
loginPopUpFrame.pack();
loginPopUpFrame.setVisible(true);
System.out.println("waitin");
doHelloWorld.wait();
System.out.println("Not Sleepin..");
loginPopUpFrame.pack();
loginPopUpFrame.setVisible(false);
}
catch (InterruptedException e)
{
}
}
};
doHelloWorld.start();
//This is called when the "second" loginB is pressed and the password is correct...
public synchronized void notifyPopUp() {
synchronized(doHelloWorld) {
doHelloWorld.notifyAll();
System.out.println("Notified");
}
}
I've also tried Swing Utilities but maybe i implemented it wrong as it's my first time using them. It essentially does the same thing as the code above except the window freezes when it gets to wait, which the above code doesnt do:
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public synchronized void run() {
try
{
loginPopUpFrame.pack();
loginPopUpFrame.setVisible(true);
System.out.println("waitin");
wait();
System.out.println("Not Sleepin.");
loginPopUpFrame.pack();
loginPopUpFrame.setVisible(false);
}
catch (InterruptedException e)
{
}
}
});
PLEASE HELP ME!!!
Rules of thumb:
Don't manipulate GUI components in arbitrary threads; always arrange to manipulate them in the event thread
Never wait or sleep inside the event thread (so, never inside code sent to invokeLater())
So the answer to how you solve this problem is "some other way"...
Standing back from the problem a bit, what is it you're actually trying to do? If you just want a login dialog to wait for the user to enter user name and password, is there a reason not to just use a modal JDialog (after all, that's what it's there for...).
If you really do want some arbitrary thread to wait for a signal to close the window/manipulate the GUI, then you need to do the waiting in the other thread, and then make that thread call SwingUtilities.invokeLater() with the actual GUI manipulation code.
P.S. There are actually some GUI manipulation methods that it is safe to call from other threads, e.g. calls that are "just setting a label" are often safe. But which calls are safe isn't terribly well-defined, so it's best just to avoid the issue in practice.
The Swing components should only be manipulated by the swing event dispatch thread.
class SwingUtilites has methods to submit tasks to the dispatch thread.
It is difficult to diagnose your problem. I'm not sure what you're trying to do with the wait methods, but I recommend leaving wait/notify alone.
This code has two frames - when you create a second frame, the first is hidden until you close it.
public class SwapFrames {
private JFrame frame;
private JFrame createMainFrame() {
JButton openOtherFrameButton = new JButton(
"Show other frame");
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(openOtherFrameButton);
frame.pack();
openOtherFrameButton
.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
onClickOpenOtherFrame();
}
});
return frame;
}
private void onClickOpenOtherFrame() {
frame.setVisible(false);
JFrame otherFrame = new JFrame();
otherFrame
.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
otherFrame.setContentPane(new JLabel(
"Close this to make other frame reappear."));
otherFrame.pack();
otherFrame.setVisible(true);
otherFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
frame.setVisible(true);
}
});
}
public static void main(String[] args) {
JFrame frame = new SwapFrames().createMainFrame();
frame.setVisible(true);
}
}
Because I don't see any evidence of them in your code, I'm going to suggest you read up on using event listeners rather than trying to "wait" for code to finish.
It isn't entirely clear what you're trying to achieve, but you might be better off with a modal dialog:
public class DialogDemo {
public JFrame createApplicationFrame() {
JButton openDialogButton = new JButton("Open Dialog");
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container container = frame.getContentPane();
container.setLayout(new FlowLayout());
container.add(openDialogButton);
frame.pack();
openDialogButton
.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
onOpenDialog(frame);
}
});
return frame;
}
private void onOpenDialog(JFrame frame) {
JDialog dialog = createDialog(frame);
dialog.setVisible(true);
}
private JDialog createDialog(JFrame parent) {
JButton closeDialogButton = new JButton("Close");
boolean modal = true;
final JDialog dialog = new JDialog(parent, modal);
dialog
.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
Container container = dialog.getContentPane();
container.add(closeDialogButton);
dialog.pack();
dialog.setLocationRelativeTo(parent);
closeDialogButton
.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
});
return dialog;
}
public static void main(String[] args) {
new DialogDemo().createApplicationFrame().setVisible(
true);
}
}
How about doing simply:
//This method is called once a user presses the "first" login button on the main GUI
public void loginPopUpThread() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
loginPopUpFrame.pack();
loginPopUpFrame.setVisible(true);
}
};
}
//This is called when the "second" loginB is pressed and the password is correct...
public void notifyPopUp() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
loginPopUpFrame.setVisible(false);
}
};
}
What you really want to be using is a modal JDialog.
Note, bits of this are left out. It's your homework/project.
public void actionPerformed(ActionEvent e)
{
// User clicked the login button
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
LoginDialog ld = new LoginDialog();
// Will block
ld.setVisible(true);
}
});
}
public class LoginDialog extends JDialog
{
public LoginDialog()
{
super((Frame)null, "Login Dialog", true);
// create buttons/labels/components, add listeners, etc
}
public void actionPerformed(ActionEvent e)
{
// user probably clicked login
// valid their info
if(validUser)
{
// This will release the modality of the JDialog and free up the rest of the app
setVisible(false);
dispose();
}
else
{
// bad user ! scold them angrily, a frowny face will do
}
}
}