In my Java application, I have a timer to keep track of how long someone does not scan a QR code. After 20 seconds, I throw a message telling them to use a manual entry instead of scan the QR code. However, how can I stop the timer once it's started? For example, a user goes to the QR scanning panel. The 20 second timer starts. The user successfully scans a QR code. Now how can I stop the timer? The timer is in my code like this.
Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run() {
//delay = 20000;
// if the timer has not been stopped, proceed with timer
if(!SpectroClick.stop_timer){
//System.out.println("20 seconds later");
//scanQRPanel.getCameraView().getWebcamPanel().pause();
stopScanning();
// Create the message to display
String text = "No QR code has been found. We suggest that you use a Manual Override." + "<br><br>" + "Press 'OK to confirm, or 'Cancel' to continue scanning for another QR code.</br>";
String message = "<html><div style=\"text-align: center;\">" + text + "</html>";
// Show the confirmation dialog screen, and wait for user input
int i = JOptionPane.showConfirmDialog((Component) null, message,
"Confirm", JOptionPane.OK_CANCEL_OPTION);
// User selected 'OK'
if (i == JOptionPane.OK_OPTION) {
for (SpectroClickEventListener listener : listeners) {
listener.userSelectedOverride();
}
}
// User did not select ok, go to new test
else{
startScanning();
}
}
}
}, delay);
I have a conditional to check if the timer is being used, however is there a way to throw some kind of exception to the timer?
The question has been already answered here.
The methods you are looking for are "cancel()" and "purge()".
I threw them into your code but haven't had a chance to run it yet:
Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run() {
//delay = 20000;
// if the timer has not been stopped, proceed with timer
if(!SpectroClick.stop_timer){
//System.out.println("20 seconds later");
//scanQRPanel.getCameraView().getWebcamPanel().pause();
stopScanning();
// Create the message to display
String text = "No QR code has been found. We suggest that you use a Manual Override." + "<br><br>" + "Press 'OK to confirm, or 'Cancel' to continue scanning for another QR code.</br>";
String message = "<html><div style=\"text-align: center;\">" + text + "</html>";
// Show the confirmation dialog screen, and wait for user input
int i = JOptionPane.showConfirmDialog((Component) null, message,
"Confirm", JOptionPane.OK_CANCEL_OPTION);
// User selected 'OK'
if (i == JOptionPane.OK_OPTION) {
for (SpectroClickEventListener listener : listeners) {
listener.userSelectedOverride();
}
}
// User did not select ok, go to new test
else{
startScanning();
}
} else{
timer.cancel();
timer.purge();
}
}
}, delay);
You shouldn't be using java.util.Timer for this, but a Swing Timer, as you're violating the single thread rules of Swing with your current approach.
A Swing Timer can be configured for a single run, which means you won't need to worry about stopping it your self
Have a look at Concurrency in Swing and How to use Swing Timers for more details
Related
I'm doing a project in school and I've a distinction feature to implement but have some issues. What I need to do is that I've to check the number of beds left in my SQL database and if it goes below a critical number a JOptionPane appears.
What I'm trying to do is another scenario which is tougher, 2 Frames opened. Eg, first frame user uses the bed, it'll drop to the critical value 10, on the other frame when the user moves his mouse arrow the JOptionPane will pop up showing a message.
I've looked up in this community but I can't seem to implement the codes to make it work. I've got to a point where there's no errors but I can't seem to close the JOptionPane. Basically I would only want this event to fire only when user of either frames go below the bed count.
I'm brand new to this actionevent. I'm doing this project as 3 tier programming with MySQL database.
I've looked at these sites but to no avail:
Stopping mouseMoved
How to temporarily disable event listeners in Swing?
Code for the Frame to show the JOptionPane
public HomePageForm() {
setTitle("Home");
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setBounds(100, 100, 640, 428);
contentPane = new JPanel();
contentPane.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
String cardioMsg = "Beds are running out for Cardiothoracic Department!";
String oncoMsg = "Beds are running out for Oncology Department!";
String orthoMsg = "Beds are running out for Orthopaedic Department!";
String pediaMsg = "Beds are running out for Pediatric Department!";
if (ignoreMouseMovedEvents) {
return;
}
ArrayList<ChangeBed> bedList = new ArrayList<ChangeBed>();
ChangeBedControl cbc8 = new ChangeBedControl();
bedList = cbc8.processCountBedsAvailableDpt4();
for (int i = 0; i < bedList.size(); i++) {
bedsForPediatric = bedList.get(i).getRowCountAvail();
}
if (bedsForPediatric <= 3) {
int valuePedia = JOptionPane.showConfirmDialog(null, pediaMsg, "URGENT", JOptionPane.WARNING_MESSAGE);
if (valuePedia == 0 || valuePedia == 2) {
ignoreMouseMovedEvents = true;
valuePedia = JOptionPane.CLOSED_OPTION;
}
}
}
});
Codes for Controller Class
public ArrayList<ChangeBed> processCountBedsAvailableDpt4() {
ChangeBed changeBed = new ChangeBed();
ArrayList<ChangeBed> bedList = new ArrayList<ChangeBed>();
bedList = changeBed.countBedsAvailableDpt4();
return bedList;
}
Entity class to retrieve from SQL DB
public ArrayList<ChangeBed> countBedsAvailableDpt4() {
ArrayList<ChangeBed> bedList = new ArrayList<ChangeBed>();
boolean rowBooleanAvail;
int rowCountAvail;
try {
myConn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ooadp?useSSL=false", "root", "root");
Statement myStmt = myConn.createStatement();
ResultSet myRs = myStmt.executeQuery("SELECT count(*) FROM bed WHERE bedStatus = 'Available' AND department = 'Pediatric'");
while (myRs.next()) {
rowBooleanAvail = myRs.last();
rowCountAvail = myRs.getRow();
ChangeBed cb = new ChangeBed(myRs.getInt(rowCountAvail), "");
bedList.add(cb);
}
} catch (Exception e) {
e.printStackTrace();
}
return bedList;
}
Basically I also have a Login Frame, upon logging in it opens up the frame I've shown in the above codes. At first showing a JOptionPane upon Mousemoved event showing a warning message. Once I click Ok/Cancel it closes the JOptionPane and stops the mousemoved event.
If I have another login frame whereby I login to the homepage (codes of the frame shown above), the same process will repeat whereby an optionpane will be shown.
So now I'll have 2 homepages opened and both mousemoved event deactivated and it won't fire again.
For frame 2, if I were to hit the critical value of to show the JOptionPane as soon as I move the mouse in the first homepage frame - how can I do that?
Lets answer with a question back to you: why do you want to stop the events?
Meaning: you programmed a listener that reacts to certain events. Now you are saying: at some point; I don't want "reactions"; so how do I prevent those events going into my listener?!
That is one way to look at it.
The other: simply tell your listener(s) that they should ignore incoming events, like:
Class SomeExample {
private boolean ignoreMouseMovedEvents = false;
...
#Override
public void mouseMoved(MouseEvent e) {
if (ignoreMouseMovedEvents) {
return;
}
... handle move events
Now you just need to update that boolean field whenever you want to ignore mouse move events.
But lets be precise here: I am not saying that ignoring events is always the best solution. I am merely expressing: if it is hard for you to prevent events from coming "into your system"; then maybe it is easier to let them coming; but change the way how your system reacts to them.
Finally: there is also a slightly different variation of this: instead of telling your listener to ignore events; you can also de-register your listeners from the event source. In other words: you can simply drop your listener from the frame you attached it to. And you re-add it, when events should be processed again.
Please can any one forward me the sample code related. Cause i tried a lot and on internet no useful info or links i can found related to it.
Thanks in Advance
This might be a workaround. But it works!
In your scheduler, have a default thread running every 1 minute (Or interval of your choice) that pings a file or DB for any changes.
The scheduler should be refreshed if the scheduler finds an entry in the DB.
From your JSP, on click of a button, create a relevant entry in the DB.
While pinging the DB, if the scheduler finds an entry, then it will do the necessary action.
Code snippet
// Default constructor.
public Scheduler()throws SchedulerException, Exception
{
try
{
SchedulerFactory sf = new StdSchedulerFactory();
sche = sf.getScheduler();
sche.start();
if(sche.isShutdown())
{
SendAlerts.sendMsgToGroup("Scheduler Failed To Start at "+sdtf3.format(new Date())+" hrs.",defaultMsgGroup);
logger.fatal("Scheduler Failed To Start At = " + sdtf1.format(new Date()) );
}
else
{
SendAlerts.sendMsgToGroup("Scheduler started at "+sdtf3.format(new Date())+" hrs.",SchStartAlertGroup);
logger.fatal("Scheduler Started At = " + sdtf1.format(new Date()) );
}
sysdate = new Date();
readFromDBAndConfigureSchedules();
while (true)
{
if(sche.isShutdown())
{
SendAlerts.sendMsgToGroup("Scheduler Failed To Start at "+sdtf3.format(new Date())+" hrs.",defaultMsgGroup);
logger.fatal("Scheduler Failed To Start At = " + sdtf1.format(new Date()) );
}
else
{
logger.info("Scheduler is Running. Table Last Pinged at : "+sdtf1.format(sysdate));
}
/*
-----------------
IN THE CHECK DB TABLE METHOD, HANDLE REQUESTS FOR STOP, PAUSE, RE-SCHEDULE ETC
------------------
*/
SchRunJob.checkDBTable();
// Loop will repeat every 1 hour = 60 minutes * 60 seconds = 3600 seconds
Thread.sleep (3600 * 1000);
} // End of while Start Flag is Y
} // End of try block
catch (Exception e)
{
SendAlerts.sendMsgToGroup( "Fatal Exception Caught.Scheduler Shut Down at " + sdtf1.format(new Date()),defaultMsgGroup);
logger.fatal("Fatal Exception Caught.Scheduler Shut Down at " + sdtf1.format(new Date()));
e.printStackTrace();
System.exit(0);
}
} // End of default constructor**
I have an app that could set the time for processing. The problems is when I update the time, the processing will increase. For example:
Initially the timer start at 07:00AM
Let say, I update the timer to 08:00AM then the next day onwards, the program will run again at 07:00AM and also at 08:00AM. (The 07:00AM is still in scheduler, how to remove the 07:00AM?)
How to make the scheduler to only run the 08:00AM the next day?
public void setKonfigurasi(String name, String value) {
log.info(SERVLET_NAME + "Entering setKonfigurasi");
amBean.setParam(name,value); //update the time into database
//name = 'processFileConf|kodPT|userA|20140312 08:30 AM'
// reschedule timer after configured by user
try {
String kodPT = name.substring(name.indexOf("|") + 1, name.indexOf("|",name.indexOf("|") + 1));
String configStr = value.substring(2); //get the new time
String currentStr = CommonUtil.getCurrentDate();
DateFormat dateformat = new SimpleDateFormat("dd/MM/yyyy KK:mm:ss a");
Date currentDate=new Date() ;
Date configDate = dateformat.parse(currentStr+" "+configStr);
long config = configDate.getTime();
long current = currentDate.getTime();
// today
long delay = config-current;
if (delay < 0)
// tomorrow
delay += (1000*60*60*24);
// create the timer and timer task objects
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("showtime for "+kodPT);
processFile("auto"+kodPT);
}
}, delay, 1000*60*60*24);
ServletContextEvent servletContextEvent = EtServletContextListener.getContext();
ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.removeAttribute ("timer");
servletContext.setAttribute ("timer", timer);
} catch (Exception e) {
log.error("Exception on date format : "+e.getMessage());
}
log.info(SERVLET_NAME + "Exiting setKonfigurasi");
}
You need to call cancel() on the previous timer and create a new one. The javadoc says:
Terminates this timer, discarding any currently scheduled tasks. Does
not interfere with a currently executing task (if it exists). Once a
timer has been terminated, its execution thread terminates gracefully,
and no more tasks may be scheduled on it.
I have found out about how to do what I want. Instead of using java.util.Timer to create the timer, we should use javax.ejb.Timer since the Timer in ejb have an info to identified each timer.
Timer Service EJB
I have a form for the user to fill out in a JFrame which then writes the collected data to a JTable in a different class.
I'm trying to configure it that when the user selects "Submit" that the JFrame will close, but not close down the program. What would be the command I need to achieve this?
The code for the submit button is as follows is as follows:
JButton bMark = new JButton("Submit");
bMark.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String start = tbStart.getText();
String end = tbEnd.getText();
String[] marking = {start, end, active, body, dysk, trem, brady};
//This is just for me to ensure the collected data is correct
System.out.println(marking[0] + " " +marking[1] + " " +marking[2] + " " +
marking[3] + " " + marking[4] + " " + marking[5] + " " + marking[6]);
//This is is the class the form data is being sent to
markTable.main(marking);
//This is where I would like the close the current window
}
});
bMark.setBounds(308, 191, 86, 23);
The class name is createMark and the method is public createMark
Thanks to anyone who replies,
Jared.
//This is where I would like the close the current window
there are these ways
JFrame#setVisible(false), but not terminating current JVM, this session exist until PC restarted,
JFrame#dispose() terminating current JVM,
System#exit(int); terminating current JVM,
better would be to JFrame#setDefaultCloseOperation
don't suplly JOptionPane, maybe will be better use that directly
You need to set the default close operation on the JFrame as such:
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
This will take care of the case where the user closes the window using the title bar or hits something like Alt+F4.
Next, simply call setVisible(false) when the submit button is pressed.
I'm building a video player in pure Java around JMF, with completely custom UI controls. Everything was working great until I put in a JLabel which updates the current play time in hh:mm:ss.ss format. The label updates acceptably, but occasionally halts for 10+ seconds at at a time, which is unacceptable.
The JMF Player is created in a SwingUtilities.invokeLater(new Runnable()... block. Here is the UI updating code:
protected void createUIUpdater() {
System.out.println("Creating UI updating worker thread");
new Thread() {
#Override
public void run() {
while(mediaPlayer.getState() == Controller.Started) {
updatePlayPosition();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.err.println("Sleep interrupted!");
}
}
System.out.println("UI Updater thread finished.");
}
}.start();
}
protected void updatePlayPosition() {
Movie movie = timelineEditor.getMovie();
movie.setInsertionPoint(Rational.valueOf(mediaPlayer.getMediaTime().getSeconds()));
updateTimeLabel();
}
protected void updateTimeLabel() {
Movie movie = timelineEditor.getMovie();
Rational time = movie == null ? new Rational(0,1) : movie.getInsertionPoint();
// ... hours/minutes/seconds calculated
timeLabel.setText((hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes)
+ ":" + (seconds < 10 ? "0" + seconds : seconds)
+ "." + (frame < 10 ? "0" + frame : frame));
}
which is called in a ControllerListener on a StartEvent. During this time the audio/video are playing.
I'm admittedly a bit of a novice when it comes to concurrency in Java, and I'm sure there's a better way of handling this separate thread. Any suggestions?
you could replace your Thread/sleep with ScheduledExecutorService:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html
because when using sleep there is no guarantee as to how long the thread will actually sleep , it may take more the the time you specify to return to the running status.
After closer inspection, it seems that my thread is executing fine, it is just getting blocked occasionally on mediaPlayer.getMediaTime() (where mediaPlayer is a javax.media.Player).
Turns out, calling mediaPlayer.getMediaNanoseconds() does not block.