How to run a Litho animation automatically? - litho

What's the proper way to start a Litho animation when an Activity is first displayed. All of the Litho animation examples are initiated by a user action, but I want to run one automatically.
I tried to extend a Litho animation example RTAnimationComponentSpec to fire the animation for the #OnEvent(VisibleEvent.class) instead of just #OnEvent(ClickEvent.class). But it didn't fire though.
Existing click event handler:
#OnEvent(ClickEvent.class)
static void onClick(ComponentContext c) {
RTAnimationComponent.updateStateSync(c);
}
Additional event handler that I added:
#OnEvent(VisibleEvent.class)
static void onVisible(ComponentContext c) {
RTAnimationComponent.updateStateSync(c);
}
I confirmed the VisibleEvent didn't fire by:
Loading the Render Thread example and confirmed the animation didn't start
Setting a breakpoint in the onVisible() method
How can I run a Litho animation automatically?

One solution I found works is to make use of the #OnCreateInitialState
#OnCreateInitialState
static void createInitialState(
ComponentContext c,
StateValue<Boolean> state) {
state.set(true);
}
This runs the animation, but I'm not sure if it's the preferred way.

Related

How do I programmatically play a button animation?

How do I make it look like a button was pressed using C# code? If I can actually push the button (play the animation and activate the events associated with the button press) with code that would be even better.
Playing the animation is pretty easy, using the Visual State Manager:
private async void PretendToClickButton()
{
VisualStateManager.GoToState(myButton, "Pressed", true);
await Task.Delay(250);
VisualStateManager.GoToState(myButton, "Normal", true);
}
You can play with the delay as you see fit.
Programmatically raising the event is not possible; you just have to call the handler method(s) directly (which assumes you the code that handles the event).
[Edit: You could subclass Button and provide your own mechanism for simulating the Click event, but that makes the XAML a wee bit trickier]

MediaCapture and Window VisibilityChanged

[Question]
On Windows Phone 8.1, what exactly happens in between the time when the user leaves the app and the OnSuspended event fires? I'm having trouble with the ability to manage objects in that span, in particular MediaCpture object.
To better explain the problem, here is the scenario:
The user is on a page with a video preview being pumped to a CaptureElement
The user taps the Start button
The user taps Back button and returns to the page with a broken MediaCapture
With WinRT there isn't an ObscuredEvent and OnNavigatingFrom doesn’t fire unless you’re going to another page in the same Frame. After some investigation, I've found that the only event that fires is Window.Current.VisibilityChanged
I've gone ahead and hook it when the page is NavigatedTo and unhooked in OnNavigatedFrom (see ex2 below). Inside the event, I check for parameter that tells if the app is hiding or showing and dispose/initialize accordingly(see ex.1 below).
[Problem]
However, this only works with the debugger attached. If I do this without the debugger attached, it doesn't reinitialize and frequently crashes the camera and I have to literally reboot the device.
Code Example 1 (note: e.Visible == false is leaving the app and true when returning)
async void Current_VisibilityChanged(object sender, VisibilityChangedEventArgs e)
{
if (!e.Visible) //means leaving the app
{
await DisposeAll(); //cleans the MediaCapture and CaptureElement
}
else
{
if(mediaCaptureManager != null) await DisposeAll();
await Initialization(); //set up camera again
}
}
Example 2 (hooking into the event)
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Window.Current.VisibilityChanged += Current_VisibilityChanged;
this.navigationHelper.OnNavigatedTo(e);
}
protected async override void OnNavigatedFrom(NavigationEventArgs e)
{
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
this.navigationHelper.OnNavigatedFrom(e);
}
[Update: Resolution]
Instead of using VisibilityChanged, hook into Window.Current.Activated on the page's constructor. With the debugger completely detached, the Activated event will provide the WindowActivationState parameter in the WindowActivatedEventArgs. Like this:
private async void CurrentOnActivated(object sender, WindowActivatedEventArgs e)
{
if(e.WindowActivationState == CoreWindowActivationState.Deactivated)
{
//dispose MediaCapture here
}
else if(e.WindowActivationState == CoreWindowActivationState.CodeActivated || e.WindowActivationState == CoreWindowActivationState.PointerActivated)
{
//initialize MediaCapture here
}
}
See my answer in https://stackoverflow.com/a/28592882/3998132. Using Window.VisibilityChanged in conjunction with your Page\UserControl Loaded\Unloaded handler should solve your issue I believe.
Using Window.Activated is less desirable than Window.VisibilityChanged because Activated relates to being visible AND having focus where as VisibilityChanged only pertains to visibility. For showing a preview having focus is not applicable. Since Windows Store apps on Windows Phone can only have one Window showing there is no difference in using either however if your app becomes universal and runs on let's say on Windows 8+ Modern shell (which can show multiple Store apps with the Snap window feature) or Windows 10 desktop (which can support multiple Store apps showing at the same time) you will not want to stop preview when a user changes focus from your app but your app is still showing.
I'm not sure if it wouldn't be more suitable to use Suspending/Resuming events. Note only that in this case, you will have to debug it properly - it behaves little different while being run with/without debugger attached.
As for the code - hooking your event in OnNavigatedTo/OnNavigatedFrom is not a good idea - when the OS suspends the app and you are using SuspensionManager then OnNavigatedFrom will be called, but when you go back to your app (resume it), then OnNavigatedTo will not be called.
Using Window events may also work here, but why not subscribe it once, somewhere in constructor? - it's window-wide and hence in phone there is only one window, which stands for app, then subscribe once. In this case, you may add a line that recognizes the current page in window and if that page contains mediacapture then dispose (create similar). Then you can also dispose/initialize in navigation events in case user doesn't leave your app and just navigate.

Swing JTabbedPane : addChangeListener or addContainerListener or both?

I have one swing code written by other person. For swing tabbed pane, he has added both change and container listener and both calls the same method:
addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent theEvent ) {
someMethod();
}
} );
addContainerListener(new ContainerAdapter() {
public void componentAdded(ContainerEvent theEvent) {
someMethod();
}
public void componentRemoved(ContainerEvent theEvent) {
someMethod();
}
} );
Whenever tab is removed from this tabbed pane, it internally calls JTabbedPane.removeTabAt(int index), which in turn calls fireStateChanged() causing new change event listened by change listener.
Now as new component (tab) is removed from tabbed pane, it also calls componentRemoved(ContainerEvent theEvent) method of container listener.
Both change even and container events, then calls same method someMethod(), which does set background and foreground colors.
I would like to know, if this kind code might cause some issues. Recently we are facing random IndexOutOfBoundException exeptions. I am just wondering, if this is causing this issue.
Also as per my understanding in swing, once event is listened, logic inside it should be executed using worker thread (e.g. SwingWorker). Please let me know if this is correct.
I am new to swing, thus any hint would be appreciated.
Thanks.
Whenever tab is removed from this tabbed pane, it internally calls
JTabbedPane.removeTabAt(int index), which in turn calls
fireStateChanged() causing new change event listened by change
listener.
This is true if the removed tab is also the selected tab. In the other cases, you won't be notified.
You need to choose what event you want to listen to:
Addition/Removal of components?--> go for ContainerListener
Selected tab? --> go for ChangeListener
I would like to know, if this kind code might cause some issues.
Recently we are facing random IndexOutOfBoundException exeptions. I am
just wondering, if this is causing this issue.
Since there is no line in your sample code that could throw that Exception, it is impossible to answer your question. Post an SSCCE that shows your issue.
Also as per my understanding in swing, once event is listened, logic
inside it should be executed using worker thread (e.g. SwingWorker).
Please let me know if this is correct.
It depends:
If you need to modify anything in the UI, anything related to Swing, it needs to be executed on the EDT (Event Dispatching Thread) and thus, SwingWorker is not an option.
If you need to perform business logic operations, and especially if they can be lengthy, then you should indeed use a SwingWorker or any other mechanism to execute that code in another thread than the EDT. Consider visiting the Swing tag wiki on "Concurrency"

JTextPane liveness

My Swing application prints lines of text to a JTextPane inside of a JScrollPane when a JButton is pressed. For quick operations there is no issue. However, some JButtons invoke operations that may take a few minutes. The button remains greyed out during this time.
What currently happens is that the text is "batched up" and then I get hundreds of lines all at once at the end of the operation at the same moment the button becomes un-greyed. The problem is that I would like the text being appended to the document displayed in the JTextPane to appear sooner (at the moment it is appended) rather than at the time the entire operation completes. This would create a better user experience.
What am I doing wrong?
Use a SwingWorker for performing your background operation.
// Your button handler
public void actionPerformed(ActionEvent e) {
(new SwingWorker<Void, String>() {
public Void doInBackground() {
// perform your operation
// invoke publish("your string");
}
protected void process(List<String> chunks) {
// append your string to the scroll pane
}
}).execute();
}
You are invoking code directly from within the AWT-Thread which blocks every event. The solution is to put your long-running code in a separate Thread. As your code is executed and obtains results, you notifiy your view (using the observer/observable pattern).As your view is notified, you update the scrollpane content.
You must also verify if you are running in the AWT-Thread or not (SwingUtilities.isEventDispatchThread()). If you are not, then you need to dispatch the update of the view in the AWT-Thread using SwingUtilities.invokeLater() because Swing is not Thread-safe.

Setting the application focus to a java-program in Ubuntu/LTSP

We are using LTSP with Thin-Clients. We are using it, to run a Java-Swing-Application. The users should not be able to do anything else, so instead of a Gnome-Session we use a shell-script to start our application.
Nearly everything works perfect but one thing: When the Thin-Client starts, the application starts too but doesn't receive the focus. We have to click once with the mouse inside the application, which is not that good, because the application is designed to be used without a mouse.
I didn't found anything useful, a toFront() on my Main Frame wasn't successful.
Has anyone any better suggestions??
You can use method java.awt.Window#setAlwaysOnTop(boolean) to grab the focus and after the first user interaction reset the alwayOnTop property.
You could try to call requestFocus on your JFrame as soon as it becomes visible:
JFrame frame = new JFrame();
frame.addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
((JFrame) e.getSource()).requestFocus();
}
});
frame.setVisible(true);