Vaadin refresh grid after adding row - java

My grid is not refreshing automatically after adding a row. I've tried several solutions from other questions but they didn't work. E.g. grid.clearSortOrder(); and grid.markAsDirty();. My goal is to add rows after time periods. Therefore I'm using a Timer and the rows are added but the grid does not refresh until I click in the table.
Easy code example:
Grid grid = new Grid();
grid.addColumn("Name");
grid.addColumn("Age");
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
grid.addRow("Exmaple","99");
}
}, 1000, 1000);

You will Need Server push for this. See Vaadin-Doc-Serverpush.
You want to change the UI from another Thread (Timer.schedule() will execute in another thread).

Vaadin callbacks are triggered by user interactions like mouse press on a button, selection of an option and so on. When you need the user interface to reflect a change that was not caused by the mouse/keyboard, you need to enable server push:
#Push
public class App extends UI {
#Override
public void init(VaadinRequest request) {
timer.schedule(new TimerTask() {
public void run() {
access(() -> grid.addRow("Example", "99"));
}
}, 1000, 1000);
}
}
Note the usage of UI.access(Runnable) to lock the UI when it is accessed from a non-request thread.

Related

App Stops refreshing after a couple of hours?

I build a printer app that i need to run 24/7 to check if there is new order, I wrote a code that refreshes the activity every 60 seconds to check if there's a new order. The problem is that it runs fine for an hour or so but after that the activity stops refreshing automatically until i click the refresh button. Then again it works for an hour or so and again stops refreshing automatically. Can somebody please help me with this?
I've use the following code to refresh the activity.
private static final int delay = 60;
Timer timer;
OrderAdapter oadaptor;
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
getLiveOrders(bID,"ALL");
oadaptor.notifyDataSetChanged();
}`enter code here`
});
}
}, 0, delay * 1000);
You shouldn't be doing that with a Timer but a service instead. That way it will continue running even if the app is in the background.

Delay routine in Swing on button click which should not stall the application

I am trying to do the following: click a button, button disappears for 2 seconds, text appears for 2 seconds and after those 2 seconds the visibility is reversed. So far I have done this:
btnScan.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
txtScanning.setVisible(true);
btnScan.setVisible(false);
try {
Thread.sleep(2000); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
btnScan.setVisible(true);
}
});
and the result is that as soon as I click the btnScan, the whole program freezes for 2 seconds before doing anything. How do I add the delay at the correct order?
You should not call sleep method in your code that dispatches the event. All the work related UI is handled by EDT(Event Dispatch Thread) and a sleep method will cause it to freeze and hence your Swing application will freeze.
To overcome it you should use a Timer. Run the timer and execute the UI manipulation using SwingUtilities.invokeLater so that it is handled by EDT.
import java.util.Timer;
// make it a member variable
Timer timer = new Timer();
........
public void actionPerformed(java.awt.event.ActionEvent evt) {
button.setVisible(false);
timer.schedule(new TimerTask() {
#Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
button.setVisible(true);
}
});
}
}, 2000);
}
Currently in your code, you are causing the EDT (event dispatcher thread) to pause with the invocation of Thread.sleep
Performing any long running tasks in the EDT will cause your UI to freeze.
To achieve what you desire, use a SwingWorker thread to perform your actions
This might help: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Swing is a single threaded environment, anything that blocks this thread will prevent it from processing new events, including repaint requests.
Swing is also not thread safe, meaning img you should never create or update the UI from outside the context of the EDT.
In this case you can use a Swing Timer to trigger a callback to occur at some time in the future which (the notification) will be executed within the context of the EDT, making it safe to update the UI with
Take a look at Concurrency in Swing and How to us Swing Timers for more details
Making use of Swing timer, you can do something like this:
btnScan.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
txtScanning.setVisible(true);
btnScan.setVisible(false);
Timer timer = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent acv) {
btnScan.setVisible(true);
txtScanning.setVisible(false);
}
});
// setRepeats(false) to make the timer stop after sending the first event
timer.setRepeats(false);
timer.start();
}
});

Usage of timer may be slowing my application down

I'm writing an app that will have a list of "active alarms" for users to interact with in various ways. Each timer is represented by an object that contains a "created time" that represents when the alarm came into existence. I have a fragment that displays all of the alarms to a user, where each Alarm is represented as a RelativeLayout with a TextView containing the "age" of a timer, where age is calculated by the created time subtracted from the current time. The requirements for my application state that the age needs to be calculated and updated once every second.
Here's the code for my timer:
final Handler myHandler = new Handler();
final Runnable myRunnable = new Runnable(){
public void run()
{
alarmDuration.setText("Age: " + tempAlarm.getAge());
}
};
try {
//This timer is meant to update the time on each Alarm once a second.
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
myHandler.post(myRunnable);
}
};
//Schedule the timer to go every second.
timer.schedule(timerTask, 0, 1000);
}
catch(Exception e)
{
e.printStackTrace();
}
Each alarm view has its own Handler, Runnable, and Timer. Here's where my problem lies: When I am displaying less than 10 of these timers, the app seems to run fine and can manage the updating with no problem. However, I tried loading somewhere in the realm of 100 alarms, and the application began to drop frames (as seen in my console). On configuration change (such as rotating the screen), I was getting dropped frames in the realm of 50-60.
Is this a good way to update these textViews or is there a method that would create less of a drag on the application? One idea I had was to possible put the IDs of all the alarm age views into an ArrayList and then have just one Handler, Runnable, and Timer to update the entire list.
Any other suggestions would be greatly appreciated!

Set delay on image and then have it removed

I am programming a game where as one image changes place with another and I want the second image to be removed after 200ms, something I really could use some help with.
I'm still a beginner and all help is appreciated! Answer as if you were talking to a five year old!
public void setVisible(Boolean visible) {
ImageIcon ii = new ImageIcon(this.getClass().getResource(explode));
image = ii.getImage();
//this.visible = visible;
/*WITH THIS LINE OF CODE THE EXPLODE DOES NOT SHOW AT ALL,
I WANT TO MAKE SURE IT SHOWS BUT ONLY FOR 200MS*/
}
Thanks in advance!
You can use a scheduled thread for it. You can use the ScheduledExcecutorService for it
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
public void displayImageFor200Ms(){
ImageIcon ii = new ImageIcon(this.getClass().getResource(explode));
image = ii.getImage();
scheduler.schedule(new Runnable() {
public void run() {
// remove image now!
}
}, 200 , TimeUnit.MILLISECONDS);
}
don't forget to shut down the scheduler when you don't need it anymore (you could use a global, pooled Scheduler for all your delayed actions and shut it down when your game is over)
Since you shouldn't do these time blocking methods like Thread.sleep(200) in the EDT, here is another solution with the Timer and TimerTask classes:
public void setVisible(boolean visible) {
ImageIcon ii = new ImageIcon(this.getClass().getResource(explode));
// show / hide image
ii.setVisible(visible);
if (visible) { // only hide image, if it's previously set to visible
new Timer().schedule(new TimerTask() {
public void run() {
ii.setVisible(false);
}
}, 200); // hide it after 200 ms
}
}
Thanks #AndrewThompson for the advice!

Handling timers in java

I have an application which runs a timer to check for idle time and once there is no activity for 10 seconds the application will close. I have nearly 100 screens and i want to track the inactivity seconds on all the screens. Its hard for me to write the handling events in all buttons, textboxes, labelboses one by one. What i have to do is add 10 seconds on every action of the user on the application. Even if it is mousemove add 10 seconds so tat the application wont close for another 10 seconds. Is there any way to handle this effectively ?
I would suggest the following handler:
final Timer tm = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("10 SECONDS AND NOTHING HAPPENED");
}
});
tm.start();
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
tm.restart();
}
}, -1);
You could look into Toolkit.addAWTEventListener this allows you to add a MouseMotionListener to react to mouse movements throughout your app and act accordingly.

Categories