What is the invalidateProperties(), invalidateSize() and invalidateDisplayList() functions did while extending a component in adobe flex/air? - actionscript-3

What invalidateProperties(), invalidateSize() and invalidateDisplayList() methods are did when extending a component in adobe flex/air ?.
And why these are necessary?

As per the documentation, these functions signal flex/flash to call another function before updating and rendering the display list. This "other function" seems to be for validation (and possibly altering the values if they're incorrect). So by calling an invalidate function, you force a recalculation. Or, in other words, a redraw. This removes any left over graphical artifacts.
That's my explanation via the documentation. Perhaps someone with more experience can build upon my answer.

All these components are based upon the RENDER event so no matter how many changes they go through (ex: x, y, width, etc ...) they are drawn only once per frame. But to get the RENDER event to trigger for each component a stage.invalidate() must be called and parsed on a per component basis. All the component invalidate methods allow you to force a redrawing of the component by skying the RENDER event step or in other cases by starting the RENDER event workflow.

Related

How to assign hotkeys to trigger event in Slate

Is there a way to schedule an event when a key is pressed on the keyboard. I can't seem to find that in the event triggers.
There are two possible answers to this.
First one is that slate is just javascript, with sandboxing layers (for security and functionality) so to an extent if you know the dom element ID could just try to reach it with something similar to this: https://developer.mozilla.org/en-US/docs/Web/API/Document/keypress_event#examples
const log = document.getElementById('log');
document.addEventListener('keypress', logKey);
function logKey(e) {
log.textContent += ` ${e.code}`;
}
Due to the sandboxing layers it may not be possible depending on what you are trying to achieve. If you want to do this natively, then the trick to effectively designing apps with slate is to think that the whole world gets recomputed whenever a variable changes. Similar to what happens with the lifecycle refreshes on Angular.js
There isn't a native global event for a key press in slate, so if you want to listen for any keypress that bubbles to the document, that won't work. But for most use cases you can work around it. For example by setting a variable from an input and then just read it from somewhere else.
1 - Go to the variables tab and create a new variable.
2 - Create an input box.
3 - Set the variable to update every time the variable changes.
4 - Read the variable from some widget or function.

how to know when Map control was first manipulated?

I am using the Map control in Windows Phone 8.
I need to implement a page where user can select his location using the map control.
I am trying to know when the app was first manipulated by the user.
Some background info:
I saw that when the control is shown, it automatically centers the world map, and CenterChanged event is raised.
I am not able to understand how ManipulationStarted, ManipulationDelta and ManipulationCompleted work.
the first time I drag, ManipulationStarted is not called, only ManipulationCompleted.
I could consider the first manipulation by user as being the 2nd time the CenterChanged is fired.
But this is a hack or a guess, I am not happy not having a good understanding how it works.
The Map control intercepts and handles Manipulation events and as such you don't get all of them. Remember, once routed events are marked at e.Handled=true they no longer bubble up.
Depending on your Scenario WP8 exposes the UseOptimizedManipulationRouting property which might prove useful. Setting UseOptimizedManipulationRouting=false causes Map, Pivot and other controls to not swallow events for nested controls.
If that doesn't help, have a look at the following Nokia Wiki article where the author ran into the same problem as you did and used Touch.FrameReported to get out of it # http://www.developer.nokia.com/Community/Wiki/Real-time_rotation_of_the_Windows_Phone_8_Map_Control

Flex/AS3: how to manage re-draw of chart when changing multiple chart properties?

I'm missing something fundamental about charting in Flex. I'm creating a custom chart component that includes an autoscale function, which modifies the chart's x-axis and y-axis limits, and provides a new data series for the chart. The custom chart component looks like:
<s:Group ...>
...
private function autoScale():void {
...
// this is where I compute newXmin, newXmax, newYmin, newYmax, startIndex, endIndex
...
haxis.minimum = newXmin;
haxis.maximum = newXmax;
vaxis.minimum = newYmin;
vaxis.maximum = newYmax;
myChart.series.dataProvider = myData.slice(startIndex, endIndex+1);
}
...
<mx:LineChart id="myChart">
<mx:horizontalAxis>
<charts:MyAxis id="haxis" labelFunction="setXLabels()"/>
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:LinearAxis id="vaxis" labelFunction="setYLabels()"/>
</mx:verticalAxis>
</mx:LineChart>
...
</s:Group>
At any time, the user may zoom in/out (code not shown), which calls the autoScale() function.
My thinking, correct me if I'm wrong, is that the above program re-draws the chart FIVE times (once for each line of code shown in function autoScale(). Is it possible to tell Flex to ignore re-drawing changes to the component until I issue some specific command that says, "OK, now I've set everything I need to -- go ahead and redraw the chart"?
I've been reading about invalidateDisplayList, but haven't been able to figure out if this is the intended application for it, and if so, how to apply it here. I've only ever seen invalidateDisplayList applied to custom components in the set and get functions used to pass data in/out of the custom component (see here, for example). In my example above, the properties I'm discussing are all set inside the custom component (e.g. in the autoScale() function). Not sure if that makes a difference.
Any advice appreciated.
Flex's component lifecycle would prevent chart being redrawn 5 times because the properties are modified 5 times with in the statements as you described, that's the beauty of the lifecycle.
In short, most properties change don't right away translate to drawing, but instead a flag is raised indicating that property has changed, such process is called invalidation. The component would then wait until the next redraw cycle, typical a frame after (Flash is a frame-based animation environment). When redraw happens, the code can then evaluate all situations holistically.
Flex's lifecycle provides granular invalidation. Developer could choose from invalidateProperties(), invalidationSize(), invalidatDisplayList() and invalidateSkinState() (for Spark components). As Flex goes through the lifecycle of "validating" these invalidations, commitProperties(), measure(), updateDisplayList(w, h), getCurrentSkinState() would be called to perform the validation. You may find more information about the component lifecycle here, here, and here.
In your case, you should not have to invalidate on your own, unless the charting component does not properly invalidate certain property, you don't need to call the invalidate or validate methods.

How to updating JLayeredPane while the JFrame is running ? java

Having read many tutorials, articles and questions, I am still have confusions about updating the GUI. Plus there are numerous related questions here on this website and still no luck - even though I think my problem is very simple.
Basically, I have a JFrame that has a JLayeredPane as its root container. And I have some layers of JPanels inside it.
The main issue is with updating a particular JPanel in this JLayeredPane. And for this particular Panel, I have implemented an update method that changes the contents inside it.
updatePanel(int para)
//doesn't remove this panel
//removes some existing labels and replaces it with new ones
Once I create the whole Frame, obviously just calling this method won't show any change displayed the frame.
private void static main (String[] args){
WindowFrame frame = new WindowFrame()//WindowFrame extends JFrame
frame.updatePanel(2);
.....
.....
}
And that's where I am stuck. I want to update the contents as the frame is displayed.
I saw these methods mentioned by people but due to nature of problems, I couldn't fully grasped the concepts. Plus the documentation on these methods isn't really helping - at least to me.
revalidate()
validate()
repaint()
How/when should these methods should be called? Or is this not the right way of what I should be doing, given these methods and the problem I am trying to solve?
Thank you for your time.
Basically you need two methods:
revalidate()
This method does the same as invalidate() but in AWT event dispatching thread (i will just call it Swing thread later on)). It updates container and all of its ancestors (parent containers in which this one is placed) layouting.
Basically if you either move something inside this container or place/remove components inside of it you should call this method (or invalidate in case you are performing it in Swing thread, for example inside any Mouse/Action listener body or just inside).
repaint()
This method forces component, all its sub-components (if it has them) and parent container (basically if this component is NOT opaque) to update what they are "painting".
Usually you don't need this method since all standard Swing components know when to repaint themselves and they do it on their own (that ofcourse depends on components UIs and some other things). This method might be useful in case you have your own specific components with some unique painting-way (for e.g. some custom selection over the components) and in some rare problematic cases with standard components.
Also the way this method acts depends on the components placement (due to some Swing painting optimizations) - if you have some massive repaints rolling you'd better optimize them to repaint only those parts (rects) that you actually need to repaint. For example if you change the component bounds inside any container the best choice is either to repaint its old bounds rect and new bounds rect OR repaint rect that contains both of those bounds, but not the whole container to avoid repainting uninvolved in the action components.
So, basically in your case after some changes with panels you should call revalidate on their container (or invalidate) followed by repaint (in case revalidate leaves some visual artefacts) again for the container.
Guess i didn't miss anything and i hope that now you know the basic meaning of those methods.
revalidate at the end of your update method like so .
updatePanel(int para){
.....
.....
this.revalidate(); //of course this refer to the panel
parent.revalidate(); // parent refer to the window
}

symbols placed on the timeline become undefined if stepping backwards

I am using the frames in the timeline of a .swf as pages in a flash app. The user can advance to the next page by clicking a button that takes her to the next frame. Similarly, it is possible to navigate to the previous frame/page as well.
Most of the content is placed on the stage (i.e. created by dragging an instance of a library symbol to the stage) but properties of those instances, such as .visible might be changed via actionscript. Also, some objects are loaded from external flash files and displayed programmatically with addChild / addChildAt.
The problem is, if I am on Frame N+1 and there is an object displayed on the stage programmatically (i.e. with addChild, not by having it placed on the stage) and navigate to Frame N where there is an object that is placed on the stage (i.e. dragged from the library),
then the instance of that object is undefined/null and throws an error if I try to set its properties (like .visible).
The error does not occur if I am moving to the NEXT frame, only if I am moving to the PREVIOUS one. Therefore I assume that some kind of initialization is not getting called while going one frame back.
I was also thinking that the objects would just not "live" to the next timeframe, that is, their value would be lost and re-initialized because of scope, but if there is no dynamically created object on the stage, I can navigate back and forth just fine.
Is there a way to ensure that the objects created on the stage do not disappear while navigating back to the previous frame?
The first, and more useful, part of the answer is this: timeline keyframes and scripts can give conflicting information about display objects - whether they should exist, where they should be, and so on. For example, when you add an item by playing into its frame, and then delete it with script, and then play into its frame again. When this happens, there's no unambiguously correct thing for Flash to do, so it tends to be unpredictable. I believe what generally happens is that once you fiddle with a given object via script, it's considered to no longer pay attention to the timeline - but your mileage will vary.
Having said that, the reason things are different when you play backwards is the second and more arcane part of the answer. Internally Flash functions differently when seeking forward and backwards on the timeline. Flash internally treats keyframes as changes to be applied in the forward direction, so as you play forward, it applies those changes in sequence. When you move backwards, however, from frame N+X to frame N, it doesn't scan through the intervening X frames reversing those changes - it jumps back to frame 1 and fast-forwards along to frame N. Normally, it amounts to the same thing and you don't need to worry about it, but when you get into the twitchy area where scripts and the timeline have a different idea of what should be on the stage, you're liable to see things behave differently depending on which way you jump (as you are now).
The super-short version is, for things to work predictably, try to ensure that any given object gets added, updated, and removed the same way - either all via script, or all via the timeline. When that seems impossible, fiddle with your content structure - usually, the best solution is to change your object into two nested ones, so that the things you want to do with script occur one level higher or lower than the things you want to do with the timeline.
I'm not sure I got your question right, but as3 does not instantiate elements on the timeline as soon as you gotoAndSomething, but later that frame.
That is, you can't
this.gotoAndPlay(10)
this.elementOnTimelineFrame10.DoSomething()
without errors.
I remember using this chunk of code in the past to work around this problem. It uses the Stage.Invalidate() function to wait for an Event.RENDER before trying to access and children, more info (although vague as hell) is here
private function init():void
{
stage.addEventListener(Event.RENDER, stage_renderHandler);
}
private function stage_renderHandler(evt:Event):void
{
// Run your code here
updateChildren();
}
private function enterFrameHandler(evt:Event):void
{
// triggers the RENDER event
stage.invalidate();
}
This also might me very costly (performance wise). I would strongly advise against dynamically adding/removing objects to an existing timeline, is there any way in which you can place an empty Sprite above the timeline animation and use that for all your dynamic content?
Hope this helps