I have two methods: go() and stop(), and a for loop looping through these methods 3 times. go() activates automatically when the loop starts and stop() will only activate once a button is pressed 3 times:
private static int buttonPress;
for (int i = 0; i < 3, i++) {
go();
do {} while(pressCount < 4);
stop();
}
Whenever the button the pressed, pressCount is incremented by 1:
public void button(View v) {
pressCount++;
}
The problem is that with this setup, when the do while loop launches, the app freezes and crashes.
Is there any way to fix this while still having the go() activate before stop(), having stop() activate after pressCount is greater than 3, and looping through 3 times?
Thanks
you cannot block the main thread for more than 5 seconds if that happens then an anr (Application not responding) dialog pops up.
You cannot pause main thread, the app freezes.
private int loopCount = 0;
private int pressCount = 0;
public void button(View v) { /* Runs when button is clicked */
if (loopCount < 4){
pressCount++;
if (pressCount == 3){
pressCount = 0;
loopCount++;
stop();
}
}
}
This code runs stop() when the button is pressed three times, but runs that only three times. (After 9 presses nothing happens)
try this
private boolean isStop = true;
private int buttonPressedCount = 0;
private void goOrStop() {
if(isStop) {
go();
isStop = false;
} else {
stopIfCan(); // :)
}
}
private void stopIfCan() {
if(buttonPressedCount >= 3 ) {
buttonPressedCount = 0;
isStop = false;
stop();
}
}
public void button(View v) {
buttonPressedCount++;
}
Related
volatile private boolean mouseDown = false;
private int max = 0;
private int min = 0;
private Robot robot;
public MouseClickListener()
{
try
{
robot = new Robot();
} catch (AWTException e)
{
e.printStackTrace();
}
}
#Override
public void nativeMouseClicked(NativeMouseEvent nativeMouseEvent)
{
}
#Override
public void nativeMousePressed(NativeMouseEvent nativeMouseEvent)
{
if (nativeMouseEvent.getButton() == NativeMouseEvent.BUTTON1)
{
max = Native.get().getFrame().getCps().getValue() + Native.get().getFrame().getDev().getValue();
min = Native.get().getFrame().getCps().getValue() - Native.get().getFrame().getDev().getValue();
mouseDown = true;
initThread();
}
}
#Override
public void nativeMouseReleased(NativeMouseEvent nativeMouseEvent)
{
if (nativeMouseEvent.getButton() == NativeMouseEvent.BUTTON1)
{
mouseDown = false;
}
}
Hi there, so basically I'm trying to make an auto clicker which clicks at values to a JSlider (a random value between say 9 and 13, just for example).
So on mouse click the initThread method is called, and the clicks per second is worked out ( a random number between the JSlider value, which is from a diff. class), and then from that, I click and then sleep the thread for 1 / randomNum (in seconds) so that it clicks that many times per second.
For some reason it's clicking at like 200cps and lagging my computer out. Does anyone see any problem with my code?
Thanks.
NEW CODE FOR CLICKER;
public class ClickMethod implements Runnable
{
#Override
public void run()
{
System.out.println("STARTED");
do
{
System.out.println("RUNNING");
Random r = new Random();
int random = r.nextInt((max - min) + 1) + min;
robot.mousePress(BUTTON1_MASK);
robot.mouseRelease(BUTTON1_MASK);
try
{
Thread.sleep(1000 / random);
} catch (InterruptedException e)
{
e.printStackTrace();
}
} while (mouseDown);
}
}
For some reason this only runs once and then isn't called when the mouseDown variable changes.
If this is intended to be clicked by you every so often then it creates numerous threads which all click away
public void nativeMousePressed(NativeMouseEvent nativeMouseEvent)
{
if (nativeMouseEvent.getButton() == NativeMouseEvent.BUTTON1)
{
max = Native.get().getFrame().getCps().getValue() + Native.get().getFrame().getDev().getValue();
min = Native.get().getFrame().getCps().getValue() - Native.get().getFrame().getDev().getValue();
mouseDown = true;
initThread();
}
}
You need to remove initThread() from there and call it once somewhere , e.g., in the constructor.
I need to run through a for loop where the text of a JLabel is set with the counter variable i and after that a Timer method is called. I now want the loop to wait until the method finishes.
Code:
public void actionPerformed(ActionEvent arg0) {
for (int i = 1; i < 6; i++) {
labelNr.setText(Integer.toString(i));
startTimer();
}
}
Because what it does now is that it instantly sets the text of the JLabel to 5, because it runs through the loop, but starting the timer just in the first loop.
I want the text of the JLabel to be 1 for the first loop, then call the Timer method, then 2 for the second loop, again Timer, 3 for the third loop and so on.
It basically just needs to wait until the startTimer() method has finished its execution. I know that synchronized is the possible solution, but I do not know how to implement it properly...
Thanks in advance.
OK, since I want a quick and dirty answer, it was voted down. So how about this:
public void actionPerformed(ActionEvent arg0) {
changeLabelAndExecuteTask(1)
}
public void changeLabelAndExecuteTask(int i){
labelNr.setText(Integer.toString(i));
startTimer(i);
}
public void startTimer(final int i){
//start a timer here
new Timer().schedule(new TimerTask(){
#Override
void run(){
methodTimerCall(i)
}}, 0);
}
public void methodTimerCall(int i){
//execute things here
if(++i < 6){
changeLabelAndExecuteTask(i);
}
}
forget the under part
You can add a static boolean and reset it value by the timer:
bool waitForTimer = false;
public void actionPerformed(ActionEvent arg0) {
for (int i = 1; i < 6; i++) {
waitForTimer = true;
labelNr.setText(Integer.toString(i));
startTimer();
while(waitForTimer){}
}
}
public void startTimer(){
//start a timer here
}
public void methodTimerCall(){
//execute
waitForTimer = false;
}
An effective approach could be to put the code inside the for loop in a separate method, and have the 'startTime()' method call this method at the end of its execution.This way you guarantee that it runs exactly when the method is finished, rather than at an arbitrary time (I.e. with Thread.sleep();)
Can you guys tell me how can I execute function updateTiles() ONLY after all nodes' actions in function slideTiles(String s) are finished? I tried adding some while loop but it freezes whole program. After running functions one after another the animations just don't show up.
public boolean ccTouchesEnded(MotionEvent event)
{
CGPoint location = CCDirector.sharedDirector().convertToGL(CGPoint.ccp(event.getX(), event.getY()));
x2=location.x; y2=location.y;
float diffY = y1-y2;
float diffX = x1-x2;
if (Math.abs(diffX)>Math.abs(diffY)&&diffX<0)
move="right";
else if (Math.abs(diffX)>Math.abs(diffY)&&diffX>=0)
move="left";
else if (Math.abs(diffX)<=Math.abs(diffY)&&diffY<0)
move="up";
else if (Math.abs(diffX)<=Math.abs(diffY)&&diffY>=0)
move="down";
int row=(int)(y1/TILE_SQUARE_SIZE);
int column=(int)(x1/TILE_SQUARE_SIZE);
slideTiles(move);
//wait for animations to finish
int sum=0;
boolean actionDone=false;
while (!actionDone)
{
for (CCNode c : tilesNode.getChildren())
{
sum+=c.numberOfRunningActions();
}
//String s=sum+"";
//statusLabel.setString(s);
if (sum==0){
actionDone=true;
break;
}
sum=0;
}
updateTiles();
return true;
}
//////
public void slideTiles(String move)
{
// Increment the moves label and animate the tile
CCBitmapFontAtlas moveslabel = (CCBitmapFontAtlas) getChildByTag(MOVES_LABEL_TAG);
moves++;
moveslabel.runAction(CCSequence.actions(
//CCDelayTime.action(0.25f),
CCScaleTo.action(0.2f, 6/5f),
//CCDelayTime.action(0.25f),
CCScaleTo.action(0.2f, 5/6f)
));
moveslabel.setString("Moves:\n " + CCFormatter.format("%03d", moves ));
if (move.equals("up"))
{
for (int start=NUM_COLUMNS; start<2*NUM_COLUMNS; start++)
for (int y=start; y<NUM_COLUMNS*NUM_ROWS; y+=NUM_COLUMNS)
{
if (tileNumbers[y]!=EMPTY)
{
for (int f=start-NUM_COLUMNS; f<y; f+=NUM_COLUMNS)
{
if (tileNumbers[f]==EMPTY)
{
//y->f
CGPoint moveTo = tilesNode.getChildByTag(f).getPosition();
CCMoveTo movetile = CCMoveTo.action(0.25f, moveTo);
CCSequence movetileSeq = CCSequence.actions(movetile);//CCCallFunc.action(this,"stopAction"));
tilesNode.getChildByTag(y).runAction(movetileSeq);
tileNumbers[f]=tileNumbers[y];
tileNumbers[y]=EMPTY;
break;
}
}
}
}
}
Edit: Is this kind of solution correct? It works surprisingly well.
public boolean ccTouchesEnded(MotionEvent event)
{
...
...
slideTiles(move);
float time = 0.25f+0.05f; //0.25f is time of moveTo action for each tile
CCDelayTime delay = CCDelayTime.action(time);
CCCallFunc cA = CCCallFunc.action(this, "updateTiles");
CCSequence se = CCSequence.actions(delay, cA);
runAction(se);
return true;
}
Generally, you shouldn't use while loop to wait in UI thread , it will cause big problem you have saw it.
You should use Thread to do this waiting job.
new Thread(new Runnable() {
#Override
public void run() {
while(true){
//here you wait forever doesn't matter the UI thread.
if(everythingDone) {//here to add your condition
new Handler().post(new Runable() {
#Override
public void run() {
//Here you can do what you want and will be done in UI Thread
}
});
}
}
}
}).start();
This question already has an answer here:
How do you have the code pause for a couple of seconds in android?
(1 answer)
Closed 8 years ago.
In my layout, I have TextViews that are initially set to be invisible. When the user presses the start button, I want one of these TextViews to be visible for .8 seconds. Then I want it to become invisible again and show another TextView for .8 seconds and so on. So basicly, it's like(textView1 pops up for a bit then disappears, then textView2 pops up for a bit then disappears...). There needs to be a good amount of time between each textView. My problem is finding a way to make my code wait a bit in between the:
findViewById(R.id.textView1).setVisibility(00000000); //makes it visible
and
findViewById(R.id.textView1).setVisibility(00000004); //makes it invisible
I have tried many different methods, but most either makes the textView stay invisible, because it gets to the .setVisibility(00000004) to quickly, or it pauses the code, but never seems to become visible as if .setVisibility(00000000) was ignored. This is what I am trying currently, but the textViews stay invisible.
int counter=0;
public void GamePlay(View view)
{
turns[counter]=(int)(4*Math.random()+1);
counter=0;
while(turns[counter]!=0)
{
if(turns[counter]==1)
{
findViewById(R.id.textView1).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView1).setVisibility(00000004);
}
else if(turns[counter]==2)
{
findViewById(R.id.textView2).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView2).setVisibility(00000004);
}
else if(turns[counter]==3)
{
findViewById(R.id.textView3).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView3).setVisibility(00000004);
}
else if(turns[counter]==4)
{
findViewById(R.id.textView4).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView4).setVisibility(00000004);
}
counter++;
}
}
public void HoldGame()
{
Timer timer=new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
}
}, 1*1000);
}
You can try handler class -
Handler handlerTimer = new Handler();
int count = 0;
Runnable runnable = new Runnable(){
public void run() {
if(count==0)
findViewById(R.id.textView1).setVisibility(00000004);
else if(count==1)
findViewById(R.id.textView2).setVisibility(00000004);
else if(count==2)
findViewById(R.id.textView3).setVisibility(00000004);
else if(count==3)
findViewById(R.id.textView4).setVisibility(00000004);
count++;
if(count<4)
handler.postDealyed(runnable, 8000)
}};
Or you can you use ScheduledThreadPoolExecutor
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
int count=0;
scheduler.scheduleAtFixedRate
(new Runnable() {
public void run() {
if(count==0)
findViewById(R.id.textView1).setVisibility(00000004);
else if(count==1)
findViewById(R.id.textView2).setVisibility(00000004);
else if(count==2)
findViewById(R.id.textView3).setVisibility(00000004);
else if(count==3)
findViewById(R.id.textView4).setVisibility(00000004);
count++;
}
}, 0, 8, TimeUnit.SECONDS);
For more information
I'm trying to learn Threads in Swing.
I have a Frame with a JProgressBar (progress), five JButtons (Start, Suspend, Resume, Cancel, Close), and a JLabel (label1).
The frame opens. Only Start is enabled. Start calls my class Progressor:
Updated Again Once and For All
Progressor progressor; //declared as class variable, initialized new in constructor and again in overridden done method
Here's the ButtonListener class:
public class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == jbStart) {
progressor.execute();
label1.setText("Progressing ...");
jbCancel.setEnabled(true);
jbResume.setEnabled(true);
jbSuspend.setEnabled(true);
jbClose.setEnabled(true);
}
if(e.getSource() == jbCancel) {
progressor.cancel(true);
label1.setText("Progress Canceled");
}
if (e.getSource() == jbSuspend) {
label1.setText(progressor.suspendProgress());
}
if (e.getSource() == jbResume) {
label1.setText(progressor.resumeProgress());
}
if (e.getSource() == jbClose) {
dispose();
}
}
}//buttonlistener
Here's the SwingWorker class:
public class Progressor extends SwingWorker<Void, Integer> {
private volatile boolean suspend = false;
private Object lock = new Object();
#Override
protected Void doInBackground() {
for (int i = 0; i <= 10; i++) {
checkForSuspend();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
publish(i);
}
return null;
}
#Override
protected void process(List<Integer> list) {
int value = list.get(list.size() - 1);
progress.setValue(value);
}
public void checkForSuspend() {
synchronized (lock) {
while (suspend) {
try {
lock.wait();
} catch (InterruptedException ie){
}
}
}
}//checkForSuspend
#Override
protected void done() {
label1.setText("All Done. Press close to exit");
progressor = new Progressor();
}
public synchronized String suspendProgress() {
suspend = true;
return "Progress suspended ...";
}
public synchronized String resumeProgress() {
synchronized (lock) {
suspend = false;
lock.notify();
return "Progress resumed ...";
}
}
}//Progressor class
Everything works except the cancel doesn't doesn't actually cancel the thread (the progress bar continues).
Should I suspend it before canceling?
This How to Pause and Resume a Thread in Java from another Thread question looks very similar to yours and has some nice examples in the answers.
As for your own code and why it does not work:
You create a new progressor on every click. You should be using and controlling one, instead of creating new ones every time.
When suspending your progressor finishes work instead of suspending. As the above question states - you should be looking at the flag at some points of your computation and acting on it. Example:
while (!cancel) {
if (!suspended) {
for (int i = 1; i <= 10; i++) {
Thread.sleep(1000);
publish(i);
}
}
}
The above code will suspend when it next reaches 10 (unless you resumed it before that), and finish when you press cancel (Cancel needs to be added as an extra flag in the obvious manner).
Your thread should run inside a while loop that looks for a boolean to change value from another object, then simply change the state with setPause(true/false) when you click the button:
while(true){
if(object_everyone_can_reference.getPause()){
Thread.sleep(1000);
}
}