In this program, we are supposed to click a button that says "Start" and then the animation will start running across the screen. After we click "Start," the button then changes to a "Pause" button where if you click it, it stops the animation and a "Resume" button appears. I am not sure how to get all three of those actions into one button. Here is the code I have so far:
JButton button = new JButton("Start");
button.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Timer t = new Timer(100, new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
shape.translate(x, y);
label.repaint();
}
});
t.start();
}
});
I know this isn't right. When I run the program, the animation is idle until I hit "Start" which is correct, but then every time I hit the button again, the animation speeds up which is not correct. How do I go about adding different actions to the button?
For instance after the animation is running, I want the "Pause" button to stop the Timer when it is clicked, then to resume the Timer when I hit "Resume." The code I have now creates a new Timer object every time I click it, but this seems to be the only way I get it to work. If I put anything outside the ActionListener, I get a scope error. Any suggestions?
I know this isn't right. When I run the program, the animation is idle until I hit "Start" which is correct, but then every time I hit the button again, the animation speeds up which is not correct.
This is because you're creating multiple new Timers each time you press the button. You should have a single reference to the Timer and be making decisions about what to do based on it's current state
//...
private Timer timer;
//...
JButton button = new JButton("Start");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (timer == null) {
timer = new Timer(100, new ActionListener() {
public void actionPerformed(ActionEvent event) {
shape.translate(x, y);
label.repaint();
}
});
timer.start();
button.setText("Pause");
} else if (timer.isRunning()) {
timer.stop();
button.setText("Resume");
} else {
timer.start();
button.setText("Pause");
}
}
});
but then every time I hit the button again, the animation speeds up which is not correct.
Don't keep creating a Timer in the ActionListener. Every time you click the button you start a new Timer.
Instead create the Timer in the constructor of your class. Then in the ActionListener you just start() the existing Timer.
Then the Pause and 'Resumebuttons will also just invoke thestop()andrestart()` methods on the existing Timer as well.
Related
This is the block of code that I am using to check for key presses. If I press the 'esc' key then the JFrame closes. But, if I press the 'space' bar the listener performs the last JButton pressed, NOT the specific button I am telling it to click. The doClick() also does not run unless a JButton was previously clicked.
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent ke) {
if(ke.getKeyCode() == KeyEvent.VK_ESCAPE) {
SaveScripts.saveData(player);
dispose();
}
if(ke.getKeyCode() == KeyEvent.VK_SPACE) {
center.buttonMenuAttack.doClick();
}
}
});
Edit 1: Ok after some more testing, the issue seems to be that the listener breaks when anything in the frame is clicked.
Program Launches
Listener is active and working.
Any component of the frame is clicked, the listener breaks
Edit 2: I ended up going with camickr's solution, its much easier to set up and I haven't had any issues with using it.
InputMap events = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actions = getRootPane().getActionMap();
events.put(KeyStroke.getKeyStroke("SPACE"), "click");
actions.put("click", new AbstractAction() {
public void actionPerformed(ActionEvent event) {
center.bAttack.doClick();
}
});
events.put(KeyStroke.getKeyStroke("ESCAPE"), "click");
actions.put("click", new AbstractAction() {
public void actionPerformed(ActionEvent event) {
manage.bDataExit.doClick();
}
});
I figured out the issue. The Listener stopped working because when a button is clicked, it becomes the focused. I made a class that extends JButton so that all my buttons have the same behavior and added the following line of code to its constructors;
setRequestFocusEnabled(false);
This way, after a button is clicked the JFrame remains focused, allowing the Listener to behave as intended.
As the title says, I would like to know the syntax for that
I am making a first person boxing game when you click the button it punches the enemy but after releasing it, the image of the punch disappears right away.
the concept of the game is how many click the user can make in a certain period of time
I don't have a code to show because its blank inside the button
Start with this:
JButton btnPunch = new JButton("");
btnPunch.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnPunch.setVisible(btnPunch.isVisible() ? false : true);
}
});
If you want an action to be done On Release use:
addMouseListener(new
MouseAdapter() {
public void mouseReleased(MouseEvent e)
{ // TODO: add your code here
} });
I need to disable a JButton on on click and enable it again 2 seconds later, so for I've tried sleeping the ui thread from the event handler, but that leaves the button in a selected state where you can't read the text of the disabled button.
The code looks something like this:
JButton button = new JButton("Press me");
button.addActionListener(new ActionListener{
public void actionPerformed(ActionEvent ae) {
JButton button = ((JButton)e.getSource());
button.setEnabled(false);
button.setText("Wait a second")
button.repaint();
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
}
button.setEnabled(true);
button.setText("");
}
What happens is the button remains in a "being selected" state with no text for the 2 seconds and instantly disables and re-enables the button at the end, which isn't what I want, what I'm aiming for is the button to stay in a disabled state with text on it for two seconds and then re-enable.
What do I do?
As user2864740 indicated - "Don't use Thread.sleep on the UI thread (the UI "freezes" and does not have a chance to repaint). Use a Timer class."
Here's an example of the kind of thing he was referring to. Should be close to what you want to do:
JButton button = new JButton("Press me");
int delay = 2000; //milliseconds
Timer timer = new Timer(delay, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
button.setEnabled(true);
button.setText("");
}
});
timer.setRepeats(false);
button.addActionListener(new ActionListener {
public void actionPerformed(ActionEvent ae) {
JButton button = ((JButton)e.getSource());
button.setEnabled(false);
button.setText("Wait a second")
timer.start();
}
}
So what I want to do is that when I press button JTextField text starts to update to new value every 3 seconds. I have tried Thread sleep metod, but it freezes whole program for the sleep time and after it is over textfields gets the latest input. So here is better explained example of what i am trying to do.
I press the JButton which puts the numbers in JTextFiel every 3 seconds as long as there is available values. I dont want it to append new text, just replace old with new. Anyone got ideas how I can do that? Thanks in advance.
You should use a javax.swing.Timer.
final Timer updater = new Timer(3000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
// update JTextField
}
});
JButton button = new JButton("Click me!");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updater.start();
}
});
The Timer will not block the Event Dispatch Thread (like Thread.sleep does) so it won't cause your program to become unresponsive.
You can't sleep in the EDT. You can either use a swingworker (better solution) or do something like this:
//sleep in new thread
new Thread (new Runnable() {
public void run() {
Thread.sleep(3000);
//update UI in EDT
SwingUtilities.invokelater(new Runnable() {
public void run() {updateYourTextHere();}
});
}
}).start();
You need to get 'the work' done on a separate thread. See some of the answers here: Java GUI Not changing
I have created a swings application and there is a "Start" button on the GUI. I want that whenever I clicked on that "Start" button, the start button should be disabled and the "Stop" button be enabled.
For that I have written the following code in the "ActionPeformed(...)" method of the "Start" button
startButton.setEnabled(false);
stopButton.setEnabled(true);
But the above code is not creating the desired affect on the GUI.
Is the above code correct for what I want to do?
It's not working with "repaint()" too.
Edit:
The code is very long so I can't paste all the code. I can tell, though, more about the code.
In the "ActionPeformed" method of "start" button, after calling the above two statements, I am executing a "SwingWorker" thread.
Is this thread creating any problem?
For that I have written the following code in the "ActionPeformed(...)" method of the "Start" button
You need that code to be in the actionPerformed(...) of the ActionListener registered with the Start button, not for the Start button itself.
You can add a simple ActionListener like this:
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
startButton.setEnabled(false);
stopButton.setEnabled(true);
}
}
);
note that your startButton above will need to be final in the above example if you want to create the anonymous listener in local scope.
The code is very long so I can't paste
all the code.
There could be any number of reasons why your code doesn't work. Maybe you declared the button variables twice so you aren't actually changing enabling/disabling the button like you think you are. Maybe you are blocking the EDT.
You need to create a SSCCE to post on the forum.
So its up to you to isolate the problem. Start with a simple frame thas two buttons and see if your code works. Once you get that working, then try starting a Thread that simply sleeps for 10 seconds to see if it still works.
Learn how the basice work first before writing a 200 line program.
Learn how to do some basic debugging, we are not mind readers. We can't guess what silly mistake you are doing based on your verbal description of the problem.
This works.
public class TestButton {
public TestButton() {
JFrame f = new JFrame();
f.setSize(new Dimension(200,200));
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
final JButton stop = new JButton("Stop");
final JButton start = new JButton("Start");
p.add(start);
p.add(stop);
f.getContentPane().add(p);
stop.setEnabled(false);
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
start.setEnabled(true);
stop.setEnabled(false);
}
});
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
start.setEnabled(false);
stop.setEnabled(true);
}
});
f.setVisible(true);
}
/**
* #param args
*/
public static void main(String[] args) {
new TestButton();
}
}