wait for a jbutton click to continue with program execution java - java

how can I know in main method that one button is click to continue with the execution because the code doesn't work inside the actionperfomed button.
For example this is my main method
public static void main(String args[]) {
jwindows jw = new jwindows ();
//stop until a button inside the jwindows is clicked
// codeExecuteAfterButtonClick
}

The wait and notify methods is Object exist to handle this sort of situation
final JButton button = new JButton('click to continue');
button.setAction(new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
synchronized (button) {
button.notify();
}
}
});
JFrame jf = new JFrame("Window");
jf.getContentPane().add(button, BorderLayout.CENTER);
jf.setDefaultCloseOperation(...);
jf.pack();
jf.setVisible();
synchronized(button) {
try {
button.wait();
} catch (InterruptedException ex) {
System.out.println("Interrupted");
}
}
System.out.println("After button clicked");

Related

Timer works with println but not label using java

I have some labels that become visible when the letter a is pressed.
private void formKeyPressed(java.awt.event.KeyEvent evt) {
// TODO add your handling code here:
if(evt.getKeyCode()==KeyEvent.VK_A){
jLabel7.setVisible(true);
jLabel8.setVisible(true);
jLabel9.setVisible(true);
myBlink();
}
I have Label8 on a timer myBlink()
public void myBlink()
{
new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("begin");
jLabel8.setVisible(false);
jLabel8.setVisible(true);
System.out.println("Timer");
}
}).start();
}
I have placed printlns to see if timer begins and ends and when I press key "a" my output shows begin Timer multiple times but my label does not appear and disappear. What tweak does this code need? What am I missing? Thanks for the extra set of eyes.
This is probably because you call successively setVisible(false) and setVisible(true) which is done too fast to be seen, you should use a variable and modify its value any time the action of the Timer is called as next:
public void myBlink()
{
new Timer(1000, new ActionListener() {
boolean visible = true;
public void actionPerformed(ActionEvent e) {
jLabel8.setVisible(visible = !visible);
}
}).start();
}

Execute Events in an Infinite Loop

public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
JButton src = (JButton) event.getSource(); //get which button is clicked
if(src.equals(GO)) //if GO button is clicked
{
try {
runHack();
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(src.equals(STOP)) //if STOP button is clicked
{
//do nothing
FeedBack.setText(null);
FeedBack.setText("Stopped");
}
}
I have a program where when you click on a button GO, it will execute a method called runHack();
private void runHack() throws AWTException
{
FeedBack.setText(null);
FeedBack.setText("Running(This doesn't print out)");
while(true)//infinite loop
{
FeedBack.setText("This doesn't print out");
}
}
runHack() is method that runs an infinite loop. When I click on the GO button, the program freezes while executing the runHack() method. The String "Running" doesn't displayed on the JLabel FeedBack.
My question is how do you make events still available when the program is in the infinite loop? I want it so that when I press on the STOP button, the program exits out of the infinite loop. Also, I want the JLabel FeedBack to work inside the loop.
you need run this infine toop inside of a new thread .this is how to do using timer .swing timer runs in separate thread.set delay to zero.so it's act as a while(true) loop.
in your code you are blocking EDT because of long lasting task(infinite loop) .the changes you made to textfield not get update because EDT is blocked.
you need to swing timer not java.util.Timer
import import javax.swing.Timer;
declare timer
Timer t;//global declaration;
initialize //
t=new Timer(0, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
FeedBack.setText("This doesn't print out");
}
});
when button click//
JButton src = (JButton) event.getSource(); //get which button is clicked
if(src.equals(GO)) //if GO button is clicked
{
try {
t.start();
} catch (AWTException e) {
e.printStackTrace();
}
}
if(src.equals(STOP)) //if STOP button is clicked
{
//do nothing
t.stop();
FeedBack.setText(null);
FeedBack.setText("Stopped");
}
updating...
a complete example
import java.awt.AWTException;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.Timer;
public class example extends JFrame implements ActionListener{
Timer t;
private final JTextField FeedBack;
private JButton go;
private JButton stop;
int i=0;
public example() {
FeedBack=new JTextField("initial text");
go=new JButton("go");
stop=new JButton("stop");
go.addActionListener(this);
stop.addActionListener(this);
this.setLayout(new GridLayout(1, 3));
this.add(go);
this.add(stop);
this.add(FeedBack);
this.setVisible(true);
t = new Timer(0, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
FeedBack.setText(i+"");
i++;
}
});
}
public void actionPerformed(ActionEvent event) {
JButton src = (JButton) event.getSource();
System.out.println(src);
if (src==go) //if GO button is clicked
{
t.start();
}
if (src==stop) //if STOP button is clicked
{
//stop timer
t.stop();
//FeedBack.setText(null);
FeedBack.setText("Stopped");
}
}
public static void main(String[] args) {
example f = new example();
}
}
output>>
Short answer:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run(){
runHack();
}
}).start();
Just take in account that there are better ways to spawn new Threads like using an Executor. Like someone commented, Threads is a broad topic, you should read the documentation.
[EDIT]
Like #Hovercraft Full Of Eels said is not Thread safe calling in a new Thread modifications of the UI.

ActionListener in java performs action on the second click

I am programming my first complex application in Java, Swing. When I have added ActionListener to my JButton.
ActionListener changeButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e){
if(startButton.getText() == "Spustit") {
startButton.setText("STOP");
} else {
startButton.setText("Spustit");
}
}
}
I am adding ActionListener to the button itself
private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
startButton.addActionListener(changeButton);
}
Can you tell me where I coded ActionListener badly?
Thanks to all!
You have coded the ActionListener good enough to be working, at least, for the action listener itself. The problem is that you are adding the action listener after an event (your second sample), thus your action listener will get called the second time you will click it.
A solution is very simple:
JButton button = new JButton();
button.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//...
}
});
Now the action listener should activate on the first click if you directly add a new ActionListener to the button, not after an action is performed
Why are you adding the actionlistener in actionPerformed? I think you should do something like this:
public static void main(String[] args) {
final JButton startButton = new JButton("Spustit");
ActionListener changeButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (startButton.getText() == "Spustit") {
startButton.setText("STOP");
} else {
startButton.setText("Spustit");
}
}
};
startButton.addActionListener(changeButton);
// Add it to your panel where you want int
}

how to close window instead of a JFrame

Somehow I cannot access & close a JFrame with.dispose(), and it gives me a nullPointerException. Neither do I want to do a System.exit(0). How do I access the JFrame directly, is there a workaround to close the JFrame?
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
frame = new ScannerUI();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
... (further down, and I cannot access the JFrame already, gives me a nullpointerexception)
btnBack.setBounds(400, 270, 80, 40);
panel.add(btnBack);
btnBack.setText ("BACK");
btnBack.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//ScannerUI.DISPOSE_ON_CLOSE();
//frame.dispose();
//this.dispose();
//frame.setVisible(false);
//System.out.println ("dsakjf;dsalkhfsa;lklf");
//System.exit(0);
//JFrame test = ScannerUI.frame;
//test.dispose();
// p = false;
System.out.println ("asdfasfas");
System.exit(frame.dispose());
}
});
You could use the SwingUtilities method, getWindowAncestor, to help you get the window that holds the button and then call dispose on it:
btnBack.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
AbstractButton button = (AbstractButton) e.getSource();
Window window = SwingUtilities.getWindowAncestor(button);
window.dispose();
}
});
Another option is to get the enclosing object of the current class (if it is the JFrame). You can get this from within your anonymous inner class by using the class name, a period, followed by this, or for you: ScannerUI.this:
btnBack.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
ScannerUI.this.dispose();
}
});
You can also check out Closing an Application and use the ExitAction. This is a more generic solution that will simulate a user clicking the "X" on the window. In this case any WindowsListeners you have added to the frame will be invoked first before the window is closed.
May not be applicable in this case, but just something to think about.

Why wont my JFrame hide?

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
}
}
}

Categories

Resources