I'm looking for the best way to do the following. If someone could point me in the right direction I'd be greatfull.
I have 5 buttons,
Button 1
Button 2
Button 3
Button 4
Button 5
What I'd like to happen is every 5 seconds the focus of the button move one down. So the app starts and Button 1 has focus. Then 5 seconds later button 2 takes focus and so on so on until Button 5 and then back to Button 1. When I say focus I mean that if the space bar was pressed the button would be pressed. Any assistance would be appreciated. Thanks
You could use a java swing timer for this task. Take a look at the example in oracle docs
http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html
You can use the KeyboardFocusManager for this as well. Sample code below using Timer object from java.util. The code below changes focus every 500 ms.
final KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
manager.focusNextComponent();
}
}, 0, 500);
Hope this helps.
You can create thread that sleeps for 5 senconds, then awakes and sets focus to the next button. Store your buttons in array.
final int n = 5;
final int TIMEOUT = 5000;
Button[] buttons = new Button[n];
// fill the array
new Thread() {
for (i = 0; ; i < n ? i++ : i = 0) {
buttons.requestFocusInWindow();
try {
Thread.sleep(TIMEOUT);
} catch(InterruptedException e) {}
}
}.start();
You can also use java.util.Timer
Related
If I had 2 buttons in the android studio and if I wanted to implement something when the 2 buttons are pressed in a certain order and within a certain time period, how would the code be like?
Supposing 2 buttons, button1 and button2 and if pressed in the order button1, button2, button2, button1 implements some activty.
button1.onClick ----(within 1 second)---> button2.onClick ----(within 1 second)---> button2.onClick ----(within 1 second)---> button1.onClick -----> Then do some activity.
I hope this explains what I'm trying to achieve.
Any help is much appreciated. :)
UPDATE
This is what I have so far but I am nowhere close to even sure if this is the right way to go about this
I put an on click listener for both
buttonOne.setOnClickListener(this);
buttonTwo.setOnClickListener(this);
Then
public void onClick(View view) {
if(view == buttonOne) {
//a timer for 1 second {
if(view == buttonTwo) {
//a timer for 1 second {
if(view == buttonTwo) {
//a timer for 1 second {
if(view == buttonOne) {
startActivity(new Intent(this, Some.class));
}
}
}
}
}
}
}
}
The solution works by using handlers and delaying doing something for some time for this case 1 second. Because all the buttons have integer ids then the solution will work to prepare for you an integer array for ids in the right order you can later on loop in an array checking the ids in it comparing it with id of your buttons. Initially all button ids are zero (0), And if they user clicks the button he will be adding the right integer id if he doesnt click any other button in a period of 1 second. All ids in the array will be zero (0) again, except only if the last click is the 4th click and after that you will have to handle your logic by checking the array yourself.
Lets start by declaring the variables we shall use (Remember to read comments):
private Handler handler; //handler to delay all work in 1 second
private Runnable runnable; //runnable this will be doing the job in another thread
private int[] buttonIDs = {0, 0, 0, 0}; //all button ids are zero initially
private int pressNumber=-1; //The user has not clicked anything
These are two methods you will have to add in your class.
The first method:
private void startCounter() {
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
if(buttonIDs[3]==0){ // if the last id is still zero lets clear everything and start afresh
clearEverything();
}
}
}
handler.postDelayed(runnable,1000); // we tell it dont execute the code in run until a 1000 milliseconds which is 1 second
}
And the second method is:
private void clearEverything(){
// clear everything will really start everything afresh always call this method first if you want to repeat the game start afresh
pressNumber=-1;
for(int i=0;i < 4;i++) {
buttonIDs[i] = 0;
}
}
The code inside onClick finally is simply this:
if(pressNumber < 3){
pressNumber++; //increment the pressing to another value
buttonIDs[pressNumber] = view.getId(); //use that value as index to button id
if(runnable != null){
handler.removeCallbacks(runnable); // if there was any handler still running cancel it first because we have clicked some button
}
startCounter(); //after click always start counter and remember if the counter finishes it will reset everything
} else{
//Do something here the user has clicked all the buttons 4 times without delaying 1 second each!. The order of button clicks is the integer array buttonIDs and you can clearEverything(); to start again!
}
I'm currently making a game where I want to animate the piece being dropped on the board, but cannot use Thread.sleep() as it will interrupt the game. How can I do something like the code below so that it pauses for a certain amount of time between painting the oval again a bit further down.
for(int counter = 0 ; counter < getMouseX(); counter++) {
g.fillOval(x*70+10, y, 50, 50);
//code to wait for 'x' seconds here
}
Also, is there any way I could disable mouse clicks while this process is going on?
One way to do this would be to use a Swing Timer. Set the Timer to fire X timers per second, then perform your animation there.
It might look something like this:
final Timer t = new Timer(10, new ActionListener(){
public void actionPerformed(ActionEvent e){
//do your updating of your variables here
repaint();
counter++;
if(counter >= mouseX){
t.stop();
}
}
});
t.start();
More info can be found in the Timer tutorial here. You also might consider googling something like "java swing animation".
I am doing a Pacman game using A* algorithm in Java. I searched a lot of questions. I found a solution for one step. But I want to refresh my table in while block and my solution is just refreshing JTable according to the last step(just showing the result) in while(calculated all steps). But I want to refresh and show Pacman's places(location) step by step in while block. It has to look like Pacmans are moving. But I couldn't. My codes is below:
btnStartGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//randomly placement of Pacmans
table_1.setValueAt(yellowPacman, locationyellowX, locationyellowY);
...calculating heuristics
//after calculation
newXYellow =locationyellowX;
newYYellow =locationyellowY+1;
nodeYellow = 10 * newXYellow + newYYellow;
while(heuristics != zero){
...enemy pacmans' movement
//after enemy pacmans' movement calculating yellow pacman's movement
if((newXYellow>=0 && newXYellow<10 && newYYellow>=0 && newYYellow<10) && !wallList.contains(nodeYellow)){
//calculate heuristic again
manhattanDistance[0][0] = Math.abs(newXYellow-locationblackX[0])+
Math.abs(newYYellow-locationblackX[0]);
manhattanDistance[0][1] = Math.abs(newXYellow-locationblackX[1])+
Math.abs(newYYellow-locationblackX[1]);
manhattanDistance[0][2] = Math.abs(newXYellow-locationblackX[2])+
Math.abs(newYYellow-locationblackX[2]);
fyellow[0] = manhattanDistance[0][0] + manhattanDistance[0][1] + manhattanDistance[0][2];
selectedNodeXYellow = newXYellow;
selectedNodeYYellow = newYYellow;
timer2.start();//updated
while(delay != 0)
delay--;
delay = 4000;
locationyellowX = selectedNodeXYellow;
locationyellowY = selectedNodeYYellow;
nodeYellow = 10 * selectedNodeXYellow+ selectedNodeYYellow;
timer3.start();//updated
while(delay != 0)
delay--;
delay = 10000;
}//ending if
}//ending while
}
}//ending action
timer2 = new Timer(ONE_SECOND, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
table_1.setValueAt(null, locationyellowX, locationyellowY);//I wanted to delete old moves
timer2.stop();
}
});
timer3 = new Timer(ONE_SECOND, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
table_1.setValueAt(yellowIcon, locationyellowX, locationyellowY);//here I want to show each moves step by step in while block
timer3.stop();
}
});
UPDATE 1 :
Delay was just an idea. Maybe algorithm is calculated too quickly and timers cannot be fired. But it didn't work and also does not timer suppose to be fired at each one second? still I've seen the last values of JTable.
I suspect your main issue here is that you need to understand how the various threads in a Java GUI application work. Specifically, if you have code executing in the event dispatch thread then there will be no updates to the UI while that code is executing. In your case you are making multiple updates to a JTable and then returning control to the display which will then show the last value.
The solution here is to introduce a timer element that executes each step of your algorithm in each tick of the timer and then returns control to display the result. Check the javax.swing.Timer class for details. I also suggest you read the sections 'concurrency in Swing' and 'How to use Swing Timers' in the Java tutorials.
I'm working on a project to insert numbers based on the number of button clicks using a counter. There's only one single button involved. When that button is pressed once, it should enter 1 in the text field. If that button is pressed again within 3 seconds, 1 should be replaced with 2. If it is pressed after 3 seconds, then the next digit should be entered in the same fashion. I've added my code below.
I'm having some trouble with this program. When i press the button twice within 3 seconds, it enters "12" in the JTextField. Also I'm having trouble to reset the counter after one digit is entered.Hope you understand my question.
package timertry;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class TimerTry extends JFrame implements ActionListener{
public JFrame panel1;
JTextField tf;
JButton button;
int counter=0;
public TimerTry() {
panel1=new JFrame("Single button keypad try");
panel1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
tf=new JTextField();
tf.setEnabled(false);
tf.setHorizontalAlignment(JTextField.CENTER);
button=new JButton();
}
public void launchFrame(){
panel1.setLayout(null);
panel1.setVisible(true);
panel1.setExtendedState(JFrame.MAXIMIZED_BOTH);
panel1.add(tf);
tf.setSize(300, 50);
tf.setLocation(500, 150);
tf.setEnabled(false);
tf.setHorizontalAlignment(JTextField.CENTER);
panel1.add(button);
button.setSize(360,50);
button.setLocation(900, 250);
button.setLabel("Press");
button.setHorizontalAlignment(JTextField.CENTER);
button.addActionListener(this);
}
public static void main(String[] args) {
// TODO code application logic here
TimerTry tt=new TimerTry();
tt.launchFrame();
}
#Override
public void actionPerformed(ActionEvent e) {
Thread thread=new Thread(){
#Override
public void run(){
try{
sleep(3000);
counter++;
if(counter==1){
tf.setText(tf.getText()+counter);
}
else if(counter==2){
tf.setText(tf.getText()+counter);
}
else if(counter==3){
tf.setText(tf.getText()+counter);
}
else {
tf.setText(tf.getText()+counter);
}
}
catch(Exception ex){
ex.printStackTrace();
}
}
};
thread.start();
}
}
Here's your problem:
if(counter==1){
tf.setText(tf.getText()+counter);
}
else if(counter==2){
tf.setText(tf.getText()+counter);
}
else if(counter==3){
tf.setText(tf.getText()+counter);
}
else {
tf.setText(tf.getText()+counter);
}
Just add tf.setText(""); before each tf.setText(tf.getText() + counter);
Or even better, change your try-catch for this one.
try{
sleep(3000);
counter++;
tf.setText(String.valueOf(counter));
}
catch(Exception ex){
ex.printStackTrace();
}
instead of getting text from tf just set text, it will replace the text it had, instead of adding it again.
Your program does:
1 clic
tf = 1
then you get in an imaginary String let's call it textOfTF
textOfTF = 1
2 clic
textOfTF = 1 (because you get it from tf.getText()) 2
So
textOfTF = 12
And so on.
And as a recommendation don't use thread.sleep() on swing applications, I would recomend using Swing Timer.
thread.sleep() will make your application to freeze, while a swing timer don't.
There are a number of problems with your current approach....
You are spawning a new, independent, Thread each time the button is clicked. Each Thread waits for 3 seconds and the increments the counter regardless
tf.getText()+counter is actually converting the counter to String before it concatenates the result. This means if the text is "1" and the counter is "2", the value will be converted to "12", not "3". Instead, you should just convert the counter to a String directly
There are a number of ways you might resolve this problem...
You could check the current time against the last time the button was clicked, if the value is less then 3 seconds, you can increment the counter, otherwise you would need to reset and start again.
You could use a Swing Timer, which is set to a non-repeating delay of 3 seconds. When the button is clicked, you would restart this timer and increment the counter. When the timer is finally triggered, you would reset the counter to 0
If i did understood you correctly this should be the answer you are looking for. Please comment if something is wrong ! So assume we run the program for 6 seconds , which is divided into 2 period these are 0 -> 3 -> 6 , if you keep pressing the button between 0 and 3 the jtextfield changes to single number display but after 3 seconds another 3 seconds starts actually so there is no before and after within your logic , they cancel each other , so if you don't press the button until 6 seconds 1 and 2 will be displayed. You are able to press 3secondsbutton as much as you can for each 3 seconds which will only change the display mode to the single value. Actually the display mode is changes from multiple numbers to single number or vice versa for each 3 seconds which depends on button pressed or not. If you want to change multiple number display start from the last value , I mean not from beginning you need keep the last value and start displaying from that point so you might need to make some modification on below code.
Your Fields Should be like this
int count=0;
String currenttext = "";
boolean key;
int seconds = 0;
Start Button Action
private void startbuttonActionPerformed(java.awt.event.ActionEvent evt) {
timer();
threesecondsbutton.setEnabled(true);
}
Timer Calling Method
public void timer(){
timer.setInitialDelay(3000);
timer.start();
}
Overide Timer
private Timer timer = new Timer(3000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Single Display
if(key==true)
{
count++;
currenttext = currenttext + Integer.toString(count);
jTextField1.setText(Integer.toString(count));
}
// Multi Display
else
{
count++;
currenttext = currenttext + Integer.toString(count);
jTextField1.setText(currenttext);
}
seconds = seconds + 3;
jLabel3.setText(Integer.toString(seconds));
key = false ;
}
});
3 Seconds Button This Button Sets the key to check the button is pressed within 3 seconds or after 3 seconds
private void threesecondsbuttonActionPerformed(java.awt.event.ActionEvent evt) {
count++;
currenttext = currenttext + Integer.toString(count);
jTextField1.setText(Integer.toString(count));
key = true;
}
I want to create a simple clock using Java. The code is so simple that I will give an example:
for(int i=0;i<=60;i++)
jLabel11.setText( Integer.toString(i) );
The problem is while I'm running my program the result didn't show each update in sequence.
It show only the 60 digit immediately, without showing the change from 1 to 2 to 3 ...
How can i fix this problem?
The problem is that changes to the UI should run on the event dispatch thread, but blocking this loop (and blocking the UI) will stop the screen from repainting. Instead, use a timer to perform regular updates, e.g.
Timer timer = new Timer();
ActionListener updater = new ActionListener()
{
int count;
public void actionPerformed(ActionEvent event) {
jLabel11.setText( Integer.toString(count++) );
if (count==60)
timer.stop();
}
}
timer.setDelay(100);
timer.addActionListener(updater);
timer.start();
See the Sun Tutorial - How to use Swing Timers.