I want to have a clock showing current time and refreshes every second. The code I am using is:
int timeDelay = 1000;
ActionListener time;
time = new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
timeLabel.setText(DateTimeUtil.getTime());
/*timeLabel is a JLabel to display time,
getTime() is samll static methos to return formatted String of current time */
}
};
SwingWorker timeWorker = new SwingWorker() {
#Override
protected Object doInBackground() throws Exception {
new Timer(timeDelay, time).start();
return null;
}
};
timeWorker.execute();
What I want to refresh the timeLabel text in another thread other than EDT.
Am I doing it correct? Any other better way?
Also for information, i've added timeLabel to a extendedJPanel which contains few similar kinds of utilities, and is called in another MainJFrame.
You can do this without a SwingWorker, because this is what the Swing Timer is made for.
int timeDelay = 1000;
ActionListener time;
time = new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
timeLabel.setText(DateTimeUtil.getTime());
/* timeLabel is a JLabel to display time,
getTime() is samll static methos to return
formatted String of current time */
}
};
new Timer(timeDelay, time).start();
Related
I'm trying to make a 'delete' button that deletes either a) a single character in a text-area if pressed and released in quick succession, or b) all of the text if pressed and held down for more than 2 seconds without release.
Is this possible in Java?
In order to be able to detect long key presses from the keyboard input, you need to understand and use 2 concepts:
1. KeyListener.
2. How to get current time.
Once you understand both, just compare the times between keyPressed and keyReleased and call the proper delete action.
Alternativly to a Swing-Timer (watch here for example) you could use a simple SwingWorker to realize the delay. In general you should not execute a delay, i.e. by Thread.sleep(1000), on the Swing EDT, since this would block the gui (for further information ...). Furthermore you should use a MouseListener to capture other informations that you need (stop the timer when mouse is released or exits the buttona area). Here is a very short example:
public class JButtonTest extends JFrame {
public static void main(String[] args) {
JButtonTest x = new JButtonTest();
JButton button = new JButton("Delete");
button.addMouseListener(new MouseAdapter() {
private static final long DELTA = 2000;
private SwingWorker<Void, Void> waitingWorker;
private Long timer;
#Override
public void mousePressed(MouseEvent e) {
timer = System.currentTimeMillis();
System.out.println("delete single char");//DO single delete here
if (waitingWorker != null && !waitingWorker.isDone())
waitingWorker.cancel(true);
waitingWorker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
Thread.sleep(DELTA);
return null;
}
#Override
protected void done() {
if (timer != null && System.currentTimeMillis() >= timer + DELTA)
System.out.println("delete all text");//DO text delete here
}
};
waitingWorker.execute();
}
#Override
public void mouseReleased(MouseEvent e) {
timer = null;
}
#Override
public void mouseExited(MouseEvent e) {
timer = null;
}
});
x.add(button);
x.setSize(100, 100);
x.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x.setVisible(true);
}
}
I want to use the method javax.swing.Timer to create a timer that will start at 3:00, then go down to 0:00. I have no idea how to use this method and how to proceed. From now on, I have this code, but I have no idea if it is good. One thing sure is that it doesn't work.
private javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
int minute = 3;
int seconde = 60;
do {
lblTimer.setText(Integer.toString(seconde));
seconde--;
} while (seconde != 0);
}
});
In this example, a TimerButton responds after the delay passed to the constructor, e.g.
new TimerButton("Back in three minutes", 3 * 60 * 1000));
Your StopListener would take the desired action when the Timer expires, e.g.
private class StopListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
// further actions here
}
}
See How to Use Swing Timers for additional details.
I have SwingWorker named Worker;
public class Worker extends SwingWorker<Void, Void> {
private MainProgramWindow mpw;
public Worker(MainProgramWindow mpw) {
this.mpw = mpw;
}
public String getStartDate (){
String inputStringDate = mpw.startDateBox.getText();
SimpleDateFormat inputFormat = new SimpleDateFormat("dd.MM.yyyy");
Date inputDate = null;
try {
inputDate = inputFormat.parse(inputStringDate);
} catch (ParseException ex) {
Logger.getLogger(MainProgramWindow.class.getName()).log(Level.SEVERE, null, ex);
}
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00.000");
String outputStringDate = outputFormat.format(inputDate);
return outputStringDate;
}
public String getEndDate (){
String inputStringDate = mpw.endDateBox.getText();
SimpleDateFormat inputFormat = new SimpleDateFormat("dd.MM.yyyy");
Date inputDate = null;
try {
inputDate = inputFormat.parse(inputStringDate);
} catch (ParseException ex) {
Logger.getLogger(MainProgramWindow.class.getName()).log(Level.SEVERE, null, ex);
}
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd 23:59:59.999");
String outputStringDate = outputFormat.format(inputDate);
return outputStringDate;
}
#Override
protected Void doInBackground() throws Exception {
//here you make heavy task this is running in another thread not in EDT
int i = 50;
setProgress(i);
//Rest of code.
ResultSet rs1;
Statement stmt;
String query1 = "select date,id,dur from exampletable\n" +
"where adetdate between '"+getStartDate()+"' and '"+getEndDate()+"'";
rs1 = stmt.executeQuery(query1);
//Rest of Code
while(i <= 100){
setProgress(i++);
Thread.sleep(5); // random magic number
}
return null;
}
}
Worker run succesfully and creating excel file in defined location.
My problem is; When i start the Program GUI coming with StartDate Chooser - EndDate Chooser - StartJob Buton. When Buton clicked some progress bar called and progress bar execute this Worker and progress bar start listening.
But Worker always use first GUI appearing values of startdate and enddate. I define two method in Worker for get the actual startdate and enddate values and using them in the String query1.
Why query1 succsefully called but not recognised methods getStartDate() and getEndDate() i dont understand. Any Idea ?
EDIT:
Also i have PbarNEW class for progressbar;
package AgentStatGenerator;
//Imports here
public class PbarNEW extends JPanel {
JProgressBar pbar;
public PbarNEW() {
// initialize Progress Bar
pbar = new JProgressBar();
// add to JPanel
add(pbar);
SwingWorker myWorker = new Worker();
myWorker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(final PropertyChangeEvent event) {
switch (event.getPropertyName()) {
case "progress":
pbar.setIndeterminate(false);
pbar.setValue((Integer) event.getNewValue());
break;
}
}
});
myWorker.execute();
}
public static void main(String args[]) {
final PbarNEW it = new PbarNEW();
JFrame frame = new JFrame("Progress Bar Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(it);
frame.pack();
frame.setVisible(true);
}
}
When i click Buton in MainProgramWindow (Main GUI) progresbar appearing and start listening of Worker. But SwingWorker myWorker = new Worker(); not working after creating constructor in Worker.
private void createExcelButonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String[] arguments = new String[] {"123"};
PbarNEW.main(arguments);
}
Please edit your question for spelling and grammar. As written it is very difficult to read, making it harder to understand your problem.
As for your problem, are you creating the SwingWorker when an event occurs? For instance, when a button is pressed? If so, you should pass the pertinent values of interest into the SwingWorker via its constructor. I don't see that your SwingWorker even has a constructor. Give it one and allow appropriate parameters to be passed in that will be used set the object's fields.
Edit regarding changes in your posted code:
public class Worker extends SwingWorker<Void, Void> {
MainProgramWindow MPW = new MainProgramWindow();
Shoot, you're creating a completely new GUI program inside of your SwingWorker -- don't do this!. This object you've created is completely distinct from the one being displayed. Instead pass in constructor parameters as I've suggested. Shoot, you can pass in the current GUI object as a constructor parameter, but don't create a new one in the SwingWorker.
e.g.,
public class Worker extends SwingWorker<Void, Void> {
private MainProgramWindow mpw;
public Worker(MainProgramWindow mpw) {
this.mpw = mpw;
}
Edit 2
For a trivial example of what I mean:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MyGui extends JPanel{
private JTextField textField = new JTextField("Start", 10);
private JButton button = new JButton("Press Me");
public MyGui() {
textField.setEditable(false);
textField.setFocusable(false);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
MySwingWorker mySwingWorker = new MySwingWorker(MyGui.this); // pass in the GUI
mySwingWorker.execute();
}
});
add(textField);
add(button);
}
public void setTextFieldText(String text) {
textField.setText(text);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("MyGui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyGui());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MySwingWorker extends SwingWorker<Void, Void> {
private static final long SLEEP_TIME = 2 * 1000;
private MyGui myGui;
public MySwingWorker(MyGui myGui) {
this.myGui = myGui; // use the gui to set a field
}
#Override
protected Void doInBackground() throws Exception {
Thread.sleep(SLEEP_TIME);
return null;
}
#Override
protected void done() {
myGui.setTextFieldText("Done!"); // call field's method
}
}
Your worker will use the start date and end date as of the time the instance has been created. This is because your query is created as a member variable, at the time of the object's instantiation.
Move the query construction into the doInBackground and you'll be ok.
I'm trying to get a JLabel to display the date and update every second. To do this I'm using Swing's Timer class and implementing my own class called DateTimer. DateTimer is also an ActionListener.
This is DateTimer:
public class DateTimer implements ActionListener {
private int delay;
private JLabel label;
private Calendar cal;
public DateTimer(int delay, JLabel label) {
this.delay = delay;
this.label = label;
cal = Calendar.getInstance();
new Timer(this.delay, this).start();
}
public void actionPerformed(ActionEvent e) {
this.label.setText(this.cal.getTime().toString());
}
}
I call this from somewhere else in my code like this:
new DateTimer(1000, this.label);
I get the date to display once, then it doesn't ever update.
I'm new to Java GUIs and handling actions so please excuse my ignorance.
java.util.Calendar.getInstance() returns an object representing the current date and time at the time it is created. It doesn't update automatically as you are assuming.
I created a game and in my swing GUI interface I want to put a timer. The way I do this at the moment is have a field with the current time , gotten with System.currentTimeMillis() which gets it's value when the game starts .In the method of my game i put the System.currentTimeMillis()- field; and it tells you the current time passed since the game started.
Nevertheless, how do get this to update itself every second lets say, so the JLabel will have : timePassed: 0s , timePassed: 1s and so on. Have in mind that i don't use threads in my game at any point.
EDIT: thank you all for your kind suggestions. I used a combination of your answers please give me some feedback.
I have the JLabel as a field called time. (else i cant handle it).
time = new JLabel("Time Passed: " + timePassed() + " sec");
panel_4.add(time);
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
time.setText("Time Passed: " + timePassed() + " sec");
}
};
Timer timer = new Timer(1000, actionListener);
timer.start();
Have a look at the swing timer class. It allows to setup recurring tasks quite easily.
This is how I would set my JLabel to update with time & date.
Timer SimpleTimer = new Timer(1000, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
jLabel1.setText(SimpleDay.format(new Date()));
jLabel2.setText(SimpleDate.format(new Date()));
jLabel3.setText(SimpleTime.format(new Date()));
}
});
SimpleTimer.start();
This is then added to your main class and the jlabel1/2/3 get updated with the timer.
new Thread(new Runnable
{
public void run()
{
long start = System.currentTimeMillis();
while (true)
{
long time = System.currentTimeMillis() - start;
int seconds = time / 1000;
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
label.setText("Time Passed: " + seconds);
}
});
try { Thread.sleep(100); } catch(Exception e) {}
}
}
}).start();
wirite this in Constructor
ActionListener taskPerformer = new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
jMenu11.setText(CurrentTime());
}
};
Timer t = new Timer(1000, taskPerformer);
t.start();
And this Write out Constructor
public String CurrentTime(){
Calendar cal = new GregorianCalendar();
int second = cal.get(Calendar.SECOND);
int min = cal.get(Calendar.MINUTE);
int hour = cal.get(Calendar.HOUR);
String s=(checkTime(hour)+":"+checkTime(min)+":"+checkTime(second));
jMenu11.setText(s);
return s;
}
public String checkTime(int t){
String time1;
if (t < 10){
time1 = ("0"+t);
}
else{
time1 = (""+t);
}
return time1;
}