I've been trying to make a button visible when the counter == 7 but it just keeps crashing whenever I add a method showButton().
This is the method that makes the button visible:
public void showButton() {
b.getHandler().post(new Runnable() {
public void run() {
b.setVisibility(View.VISIBLE);
}
});
}
While this is where the thread starts and animates, tho it keeps crashing whenever the counter reaches 7.
void animateFace() {
Runnable r = new Runnable() {
public void run() {
while (true) {
counter++;
if (counter > 8)
counter = 0;
if (counter == 1)
facedest8 = facedest1;
if (counter == 2)
facedest9 = facedest2;
if (counter == 3)
facedest10 = facedest3;
if (counter == 4)
facedest11 = facedest4;
if (counter == 5)
facedest12 = facedest5;
if (counter == 6)
facedest13 = facedest6;
if (counter == 7)
facedest14 = facedest7;
showButton();
SystemClock.sleep(1000);
}
}
};
Thread t = new Thread(r);
t.start();
}
UI updates should be done on the main thread. Try this:
public void showButton() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
b.setVisibility(View.VISIBLE);
}
});
}
To display the button after an 8 sec delay, you can do this:
public void animateFace() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
b.setVisibility(View.VISIBLE)
}
}, 8000);
// No need to call showButton() anywhere in this case
}
if showButton() is part of activity, then,
public void showButton() {
runOnUiThread(new Runnable() {
#Override
public void run() {
b.setVisibility(View.VISIBLE);
}
});
}
if showButton() is outside activity then pass reference of activity to showButton(),
public void showButton(Activity context) {
context.runOnUiThread(new Runnable() {
#Override
public void run() {
b.setVisibility(View.VISIBLE);
}
});
}
Related
i have created a donutprogressBar and i am setting the progressbar value and its working fine for the first time but when i set the value for second time than the progressbar gets fluctuating between the first value and the second value , i want the progressbar to be set conatsntant to the second value
here is my code :
strMalePercentage = jsonObject.getJSONObject("male").getString("percentage_manglik_present");
txtPercentage.setText("Manglik Male"+strMalePercentage);
Progress(strMalePercentage);
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_ManglikMatchMale){
linearMale.setVisibility(View.VISIBLE);
linearFemale.setVisibility(View.GONE);
imgMatchGender.setBackgroundResource(R.drawable.ic_male1);
txtPercentage.setText("Manglik Male");
Progress(strMalePercentage);
btnMale.setBackgroundColor(getResources().getColor(R.color.textPrimary));
btnMale.setBorderColor(getResources().getColor(R.color.sky_blue));
btnFemale.setBackgroundColor(getResources().getColor(R.color.light_pink));
btnFemale.setTextColor(R.color.textPrimary);
btnMale.setTextColor(R.color.gray_light);
}else
{ linearMale.setVisibility(View.GONE);
linearFemale.setVisibility(View.VISIBLE);
imgMatchGender.setBackgroundResource(R.drawable.ic_female1);
txtPercentage.setText("Manglik Female ");
Progress(strFemalePercentage);
btnFemale.setBackgroundColor(getResources().getColor(R.color.textPrimary));
btnFemale.setBorderColor(getResources().getColor(R.color.light_pink));
btnMale.setBackgroundColor(getResources().getColor(R.color.sky_blue));
btnMale.setTextColor(R.color.textPrimary);
btnFemale.setTextColor(R.color.gray_light);
}
}
public void Progress(final String Percentage){
Timer timer;
donutProgress = (DonutProgress) findViewById(R.id.donut_progress_male);
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
double d = Double.parseDouble(Percentage);
int i = (int) d;
donutProgress.setProgress(0);
donutProgress.setProgress(i);
}
});
}
},1000,100);
}
Maybe something like this, so the timer reference is outside and you can cancel it if already running
private Timer timer;
public void progress(final String Percentage){
donutProgress = (DonutProgress) findViewById(R.id.donut_progress_male);
if (timer == null) {
timer = new Timer();
} else {
timer.cancel();
}
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
double d = Double.parseDouble(Percentage);
int i = (int) d;
donutProgress.setProgress(0);
donutProgress.setProgress(i);
}
});
}
},1000,100);
}
I have a phone and tablet.
In my code, there is a thread for Autosound.
For phone it looks like
void Thread(boolean b){
new Handler().postDelayed(new Runnable() {
public void run() {
while (!stopRequested) {
if(MainScreen.tgbutton.isChecked() == false) {
mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
public void onLoadComplete(SoundPool mSoundPool, int sampleId, int status) {
mSoundPool.play(mSlovo, 1, 1, 1, 0, 1);
}
});
stop();
}
else {
stop();
}
}
}
public void stop () {
stopRequested = true;
}
}, 100);
};
Tablet so
void Thread(boolean b){
new Handler().postDelayed(new Runnable() {
public void run() {
while (!stopRequested) {
if(MainScreen.tgbutton.isChecked() == false) {
mSoundPool.play(mSlovo, 1, 1, 1, 0, 1);
stop();
}
else {
stop();
}
}
}
public void stop () {
stopRequested = true;
}
}, 100);
};
I want to combine these two threads into one, but need to know to what API should be used with setOnLoadCompleteListener.
UPD: on the tablet works without the listener, if you add a listener that the sound is not working on the tablet
I would like to ask, if is there a better away to call a method multiple times giving a 5 sec delay between each call.
But I really want is to call the Toas() method about 7 times, and with my code below, it doesnt look right.
Thanks guys
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
CallMultipleToast();
........
private void CallMultipleToast(){
Runnable call_1 = new Runnable() {
#Override
public void run() {
Toast("Message one");
Runnable call_2 = new Runnable() {
#Override
public void run() {
Toast("Message two");
Runnable call_3 = new Runnable() {
#Override
public void run() {
Toast("Message three");
//CAN I ADD MORE
}
};//end call_3
new Handler().postDelayed(call_3, 5000);
}
};//end call_2
new Handler().postDelayed(call_2, 5000);
}
};//end call_1
new Handler().postDelayed(call_1, 5000);
}
private void Toast(String message){
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
maybe you can do it like this :
private void CallMultipleToast(){
Thread t = new Thread(){
#Override
public void run(){
try {
for(i=0;i<7;i++){
Toast("Message "+(i+1));
sleep(5000);
}
} catch (InterruptedException ex) {
Log.i("error","thread");
}
}
};
t.start();
}
Try this:
final int DELAY= 5000;
int count = 0;
String[] msgs = {"one", "two", "three", "four", "five"};
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
if (count < 5) {
Toast(msgs[count]);
handler.post(runnable);
}
count++;
}
};
handler.postDelayed(runnable, DELAY);
I'm using a indicator progress set to -1.0 to show some loading while loginprocess is running.
But when I press the Enter button and start my executor with the loginProcess, my interface stays freezed even if I use Plataform.runLater to set visible my ProgressIndicator.
My button event:
public void initManager(final LoginManager loginManager) {
btnEntrar.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
String email = loginTxtField.getText().trim();
String token = tokenTxtField.getText().trim();
if (email.equals("")) {
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", "Digite o e-mail");
}
});
return;
}
try {
Future future = loginProcess(email, token);
showLoginLoading(future);
future.get();
if (!loginGatewayFailed && !loginTargetAppFailed) {
Login loginTargetApp = new Login(email, null, null);
loginManager.autheticated(loginTargetApp, loginGateway, gateway, file);
} else {
if (loginTargetAppFailed) {
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", loginTargetAppFailedCause);
}
});
} else {
if (loginGatewayFailed) {
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", loginGatewayFailedCause);
}
});
}
}
}
} catch (final Exception ex) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, ex.getMessage());
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", ex.getMessage());
}
});
}
}
});
}
My loginProcess:
public Future<?> loginProcess(String email, String token) throws Exception {
// MY PROCESS
return Executors.newSingleThreadExecutor().submit(new LoginTask(this, email, token));
} catch (Exception e) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, e.getMessage());
throw e;
}
}
method showLoginLoading:
private void showLoginLoading(Future future) {
while (!future.isDone()) {
Platform.runLater(new Runnable() {
#Override
public void run() {
progressInd.setVisible(true);
// progressInd.setProgress(-1.0);
}
});
}
}
The problem was in thread management. I was trying to execute the login instructions in the same thread that the main FX view runs.
I figured it out using the Platform.isFxApplicationThread(); It returns true if the calling thread is the JavaFX Application Thread.
To fix my problem i just needed to create a new thread to run all my login instructions as you can see in bellow example:
public void initManager(final LoginManager loginManager) {
btnEntrar.setOnAction(new EventHandler<ActionEvent>() {
boolean mainThread = Platform.isFxApplicationThread();
System.out.println("This is the main Thread: " + mainThread);
Platform.runLater(new Runnable() {
#Override
public void run() {
progressInd.setVisible(true);
}
});
new Thread() {
public void run() {
boolean mainThread = Platform.isFxApplicationThread();
System.out.println("This is the main Thread: " + mainThread);
String email = loginTxtField.getText().trim();
String token = tokenTxtField.getText().trim();
if (email.equals("")) {
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", "Digite o e-mail");
}
});
return;
}
try {
Future future = loginProcess(email, token);
// showLoginLoading(future);
future.get();
if (!loginGatewayFailed && !loginTargetAppFailed) {
Login loginTargetApp = new Login(email, null, null);
loginManager.autheticated(loginTargetApp, loginGateway, gateway, file);
} else {
if (loginTargetAppFailed) {
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", loginTargetAppFailedCause);
}
});
} else {
if (loginGatewayFailed) {
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", loginGatewayFailedCause);
}
});
}
}
}
} catch (final Exception ex) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, ex.getMessage());
Platform.runLater(new Runnable() {
public void run() {
Dialog.showError("Erro", ex.getMessage());
}
});
}
}
}.start();
});
}
How can i use the callme(input); to get launched with a new thread?
/* We send username and password for register and load a heavy load */
public class button3 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String input = output.getText();
if (input.length()<=0)
{
JOptionPane.showMessageDialog(null, "Empty....");
} else {
callme(input);
}
}
}
public static String callme() { //heavy loads... starts, which freezed the button
return "Did you called me?";
}
Try 1: but getting failed (output1 does not get the returned text results):
/* We send username and password for register and nat mapping */
public class button3 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String input = output.getText();
if (input.length()<=0)
{
JOptionPane.showMessageDialog(null, "Empty....");
} else {
new Thread(new Runnable() {
public void run() {
try {
output1.setText( callme(output.getText()) );
} catch(Exception t) {
}
}
}).start();
}
}
}
Try 2: Also tried this, did not returns output1 = callme();
new Thread(new Runnable() {
public void run() {
final String result = callme(output.getText());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
output1.setText( result );
} catch(Exception t) {
}
}
});
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
callme(input);
} catch(Exception t) {
// appropriate error reporting here
}
}
}).start();
Note that input must be declared as final.
Also, consider using invokeLater(Runnable) from Swing Utilities
Try this:
public class button3 implements ActionListener {
public void actionPerformed(ActionEvent e) {
final String input = output.getText();
if ( input.length() <= 0 ) {
JOptionPane.showMessageDialog(null, "Empty....");
}
else {
Thread t = new Thread(new Runnable() {
public void run() {
callme(input);
}
});
t.start();
}
}
public static String callme(String input) {}
}
If you modify swing controls inside your method you should use
new Thread(new Runnable() {
#Override
public void run() {
final String result = callme(input);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
output1.setText( result );
} catch(Exception t) {
}
}
});
}
}).start();
If you need the return value, you should really be using a Callable with an ExecutorService which will give you back a Future that you can use the retrieve the value later on.
See:
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html