I write a swing GUI application and I use a button. If I click on a button, my application needs to do some online request. I want to set a "Please wait" JPanel at this time. So I use the SwingWorker. It is all working. The doInBackground() method starts but it didn't finish.
I debugged the application and I see that if I create a new object, the application goes into a class FutureTask.java and call the method run(), after this it goes into ThreadPoolExecutor.java into the runWorker method and the thread stops there.
private void buttonBuchenActionPerformed(java.awt.event.ActionEvent evt) {
mainProg.showInfoWithoutButton(80000, "Please wait", mainProg.getPanel_first());
startPayment();
}
After a click on the button i change the Panel with the showInfoWithoutButton Methode. After the Panel is changed the startPayment() method starts.
public void startPayment() {
new SwingWorker<Void, Void>() {
#Override
public Void doInBackground() {
Calendar cal = Calendar.getInstance();
DateFormat formatDb = new SimpleDateFormat("yyyy-MM-dd");
Date date1;
try {
date1 = formatDb.parse(mainProg.getFreeRoom().getAbreiseBeds());
cal.setTime(date1);
cal.add(Calendar.DAY_OF_MONTH, -1);
} catch (ParseException ex) {
Logger.getLogger(EnterConfirmation.class.getName()).log(Level.SEVERE, null, ex);
}
String date = formatDb.format(cal.getTime());
try {
boolean paymentSuccess;
if(mainProg.getConfig().getString("terminal").equals("true")){
mainProg.getOpp().connectOpp();
paymentSuccess = mainProg.getOpp().startPayment(mainProg.getFreeRoom().getPriceGesamt(), mainProg);}
else paymentSuccess = true;
DBController db = new DBController();
db.initDBConnection();
//numberOfAvailbility is the unit.
String numberOfAvailbility = db.getQtyOfAvailbilityFromID(mainProg.getFreeRoom().getId());
if(paymentSuccess == true){
//----------------------------------
// HERE IT GOES TO FutureTask.java and the methode finish:
JsonNewBooking a = new JsonNewBooking(mainProg.getFreeRoom().getId(), 1, mainProg.getFreeRoom().getAnreiseBeds(), date, mainProg.getFreeRoom().getGuestnr(), mainProg.getBooking().getName(), mainProg.getBooking().getEmail(), mainProg.getBooking().getStreet(), mainProg.getBooking().getPlace(), mainProg.getBooking().getLand(), String.valueOf(mainProg.getFreeRoom().getPriceGesamt()));
//----------------------------------
String bookid = a.setBookingToBeds();
if(mainProg.getConfig().getString("terminal").equals("1"))
mainProg.getOpp().printReceipt(paymentSuccess);
if (!bookid.equals("null")) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date checkInDay = simpleDateFormat.parse(mainProg.getFreeRoom().getAnreiseBeds());
Date todayDate = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
if (checkInDay.compareTo(todayDate) == 0) {
System.out.println(bookid);
//ReturnKeyWithoutTerminal because was 100% paid already
gui.return.returnWithoutTerminal(mainProg, bookid);
mainProg.getFreeRoom().reset();
mainProg.getBooking().reset();
mainProg.getPanel_bookNow().resetAll();
mainProg.resetPanel();
mainProg.getBackToMainPanelTimer().stop();
} else {
mainProg.getFreeRoom().reset();
mainProg.getFreeRoom().reset();
mainProg.getPanel_bookNow().resetAll();
mainProg.resetPanel();
mainProg.getBackToMainPanelTimer().stop();
}
} catch (ParseException ex) {
Logger.getLogger(EnterConfirmation.class.getName()).log(Level.SEVERE, null, ex);
}
}
}else
mainProg.getOpp().printReceipt(paymentSuccess);
} catch (IOException ex) {
Logger.getLogger(EnterConfirmation.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}}.execute();
}
Normally the method should finish normally but it stops at the line where I create the object "a" (sorry for the bad name).
Maybe someone have an idea why it calls the class FutureTask.java and the ThreadPoolExecutor.java and stops the doInBackground method.
Related
I want to return a String from a callback
My class which fetch date from server in a thread and i want this value in main thread as a String. I am beginner in Java.
public class InternetDate {
private final Activity activity;
private String finalDate = "";
public InternetDate(Activity activity) {
this.activity = activity;
}
public void setDateAndTimeFormat(String dateAndTimeFormat) {
mDateAndTimeFormat = dateAndTimeFormat;
}
public void getCurrentDate(OnGetDate onGetDate) {
new BackgroundTask(activity) {
#Override
public void doInBackground() {
try {
finalDate = getCurrentDateFromInternet();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onPostExecute() {
try {
JSONObject jb = new JSONObject(finalDate);
String name = jb.getString("UnixTimeStamp");
onGetDate.onSuccess(name);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
} catch (JSONException e) {
}
}
}.execute();
}
private String getCurrentDateFromInternet() throws Exception {
String date_api = example.com/api;
URL url = new URL(date_api);
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(url.openStream()));
return in.readLine();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
}
public interface OnGetDate {
void onSuccess(String date);
}
I want this as a String. Please help me to archive this String in MainThread
private String getDate(){
String currentDate = "";
InternetDate internetDate = new InternetDate(this);
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
currentDate = date; // Null return
}
});
return currentDate;
}
You might wait for the response using a semaphore, but this kind of code is blocking by nature and leads to apps with a poor user experience, because the ui thread is blocked during the whole process
//import java.util.concurrent.*;
//[...]
private String getDate() throws TimeoutException {
final String[] result = new String[]{null};
final Semaphore sem = new Semaphore(0);
new InternetDate(this).getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
result[0] = date; // Null return
sem.release();
}
});
try {
if (sem.tryAcquire(10, TimeUnit.SECONDS)) {
return result[0];
} else {
throw new TimeoutException("no response after 10 seconds");
}
} catch(InterruptedException e) {
return null;
}
}
You can use Executors :
private String getDate() throws ExecutionException, InterruptedException {
// This line is non-blocking:
Future<String> future = Executors.newCachedThreadPool()
.submit(() -> new InternetDate().getCurrentDateFromInternet());
// The invocation of 'get' is blocking:
return future.get();
}
I assume getCurrentDateFromInternet returns the date in the format you want.
Your problem can be solved using a MutableLiveData object without blocking the UI thread.
Let's start assuming you have a main class named MainThread where your getDate method lives.
In this class first create the following MutableLiveData object:
private MutableLiveData<String> date = new MutableLiveData<>();
The object above will be updated with the date value as soon as it's available to your program.
Next create/update the method that'll make a call to the getDate method (which we'll keep for simplicity's sake):
private void exampleDateMethod() {
// first create an observer; in the observer you put the code that does something with the Date
date.observe(this, new Observer<String>() {
#Override
public void onChanged( String date ) {
// this is where you do something with the date, an example:
findViewById( R.id.date_view ).setText( date );
}
});
// pass the MutableLiveData to the getDate method so that its value can be updated:
getDate( date );
}
And change the getDate method to pass the Date to the MutableLiveData object:
private void getDate( MutableLiveData<String> liveDate ){
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
// set the value of the MutableLiveData object, this will notify the observer and execute the code in its onChanged method
liveData.setValue( date );
}
});
}
I need to get the current time only (without data) in HH:mm format (eg. 14:20) and then update it every second or minute. I kinda get it with this code, but is it possible to convert it to a string?
And I need to pass the value "time" in a separate public String.
Any solution?
Thanks
public class ClockCounter extends TimerTask {
public long time = System.currentTimeMillis();
#Override
public void run(){
time += 1000; //add 1 second to the time
//convert ms time to viewable time and set MainActivity.text (textview) text to this.
}
public long getTime(){ return time; }
}
UPDATE: Got it working with a service that runs every second.
Using liveData and coroutines:
val currentTime = liveData {
while (true){
emit(Calendar.getInstance().time)
kotlinx.coroutines.delay(1000)
}
}
You just need to have a final variable SimpleDateFormat.
final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
and you can get time with format in anywhere you want using this code:
String time = dateFormat.format(new Date());
you can do that like this :
private void clock() {
final Handler hander = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
hander.post(new Runnable() {
#Override
public void run() {
getTime();
clock();
}
});
}
}).start();
}
void getTime() {
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss", Local.getDefault());
textview.setText(dateFormat.format(new Date()));
}
You can use the code below for get curent Clock with Hours ,Minutes and Seconds
final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
String time = dateFormat.format(new Date());
I am trying to execute Thread into the Both method using thread.Run and as well as thread.start
Here the case
Main Class
Thread thread = new GetTimeZones();
ByImletingInterface thread21 = new ByImletingInterface();
thread21.getMailStarttime(5);
ByImletingInterface thread2 = new ByImletingInterface();
thread2.getMailStarttime(10);
thread.start();
new Thread(thread21).start();
new Thread(thread2).start();
Thread 1
public class ByImletingInterface implements Runnable {
private int starttime;
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(starttime * 1000);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
System.out.println("Checking Mail");
}
}
and Other therad
public class GetTimeZones extends Thread {
#SuppressWarnings("static-access")
#Override
public void run() {
// TODO Auto-generated method stub
Locale locale;
DateFormat timeforMatter;
DateFormat dateforMatter;
String timeoutput = null;
String dateoutput = null;
try {
java.util.Date date;
for (int i = 0; i < 20; i++) {
date = new Date();
locale = new Locale("en");
timeforMatter = DateFormat.getTimeInstance(DateFormat.DEFAULT,
locale);
dateforMatter = DateFormat.getDateInstance(DateFormat.DEFAULT,
locale);
//System.out.println(timeforMatter);
timeoutput = timeforMatter.format(date);
dateoutput = dateforMatter.format(date);
System.out.println(timeoutput);
System.out.println(dateoutput);
System.out.println();
try {
Thread.sleep(2000);
} catch (Exception e) {
// TODO: handle exception
}
}
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
e.printStackTrace();
}
super.run();
}
}
how ever for describing my prob both class is not needed but still m giving it.
when i use therad.start into main class like i did. Its sententiously executing three of threads.
But when i use theread.run one by one thred is exected. means its synchronize. Why this happens?
When you call the run() method, you are running it on the current thread, so of course it will run one by one, as there is only one thread (each run() method will be executed after the previous one is done).
Only when you call start() a new thread is created and the run() method is executed in that new thread.
I am creating a PC program which is based on iCalendar format. I need to be able to get the data from a current ics file and display it as a calendar or at least something similar to calendar. I know how to get the data from ics file just don't have any idea how to easily use that data for displaying purposes.
Here is my starting code:
public void getCalendarData(File f) throws FileNotFoundException, IOException, ParserException
{
FileInputStream fin = new FileInputStream(f);
builder = new CalendarBuilder();
calendar = builder.build(fin);
}
One thing is ical4j, which is basically a utility that wraps the ICS format.
Another thing is a front end for a calendar/schedule :-)
But, lucky us, there's a nice JSF component with Primefaces, that you can use if a web interface is OK for you.
http://www.primefaces.org/showcase/ui/data/schedule.xhtml
Basically, what you need, is to just parse the data from ICS and feed the primefaces component data model (the link above has both the JSF and the managed bean example of how to use the component)
So you'd have to so something like this
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMdd");
#PostConstruct
private void loadIcs() {
eventModel = new DefaultScheduleModel();
CalendarBuilder builder = new CalendarBuilder();
try {
net.fortuna.ical4j.model.Calendar calendar = builder.build(this.getClass().getResourceAsStream("canada.ics"));
for (Iterator i = calendar.getComponents().iterator(); i.hasNext();) {
Component component = (Component) i.next();
//new event
Date start = SDF.parse(component.getProperty("DTSTART").getValue());
Date end = SDF.parse(component.getProperty("DTEND").getValue());
String summary = component.getProperty("SUMMARY").getValue();
eventModel.addEvent(new DefaultScheduleEvent(summary,
start, end));
System.out.println("added "+start+end+summary);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ParserException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
Not sure if you mean the actual GUI or getting the list of dates from an icalendar which is fairly complex given the RRULE properties. In ther first case, the choice is wide open (HTML, ...) in the later case there is an example here copied below :
// Reading the file and creating the calendar
CalendarBuilder builder = new CalendarBuilder();
Calendar cal = null;
try {
cal = builder.build(new FileInputStream("my.ics"));
} catch (IOException e) {
e.printStackTrace();
} catch (ParserException e) {
e.printStackTrace();
}
// Create the date range which is desired.
DateTime from = new DateTime("20100101T070000Z");
DateTime to = new DateTime("20100201T070000Z");;
Period period = new Period(from, to);
// For each VEVENT in the ICS
for (Object o : cal.getComponents("VEVENT")) {
Component c = (Component)o;
PeriodList list = c.calculateRecurrenceSet(period);
for (Object po : list) {
System.out.println((Period)po);
}
}
I am writing automated test cases in Selenium/WebDriver in java. I have the following code implemented to poll for existing WebElements, but as I am not an expert in Java I was wondering if there is a cleaner way to write this method:
/** selects Business index type from add split button */
protected void selectBusinessLink() throws Exception
{
Calendar rightNow = Calendar.getInstance();
Calendar stopPolling = rightNow;
stopPolling.add(Calendar.SECOND, 30);
WebElement businessLink = null;
while (!Calendar.getInstance().after(stopPolling))
{
try
{
businessLink = findElementByLinkText("Business");
businessLink.click();
break;
}
catch (StaleElementReferenceException e)
{
Thread.sleep(100);
}
catch (NoSuchElementException e)
{
Thread.sleep(100);
}
catch (ElementNotVisibleException e)
{
Thread.sleep(100);
}
}
if (businessLink == null)
{
throw new SystemException("Could not find Business Link");
}
}
This particular line is what makes me think the code is a little dirty:
while (!Calendar.getInstance().after(stopPolling))
You can do something like this
long t = System.currentMillis(); // actual time in milliseconds from Jan 1st 1970.
while (t > System.currentMillis() - 30000 ) {
...
How about using the System time in millis?
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, 30);
long stopPollingTime = calendar.getTimeInMillis();
while (System.currentTimeMillis() < stopPollingTime) {
System.out.println("Polling");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}