How to completely initialise a component but not add it to the display? Flex - apache-flex

I need to completely initialize a custom component in my Flex app (i.e. I should be able to access it from action script and get its properties and its children etc), But I do not want to add it to the display or make it visible.
I have tried to add it to my visible component, but keep it visible, but often many of its properties are set only when it is drawn, so i don't get what i need.
Is there a way to add a custom component to some sort of 'Virtual' display, that is not visible to the user?

You could add the component to an invisible Sprite - that way the component itself could both be on the stage and have its own visible property set to true.

Did you try using initialize()? After a view is added to the display list, the initialization stage begins. Calling initialize() before addChild() should let you initialize the view without needing to first add it to the stage.
For more info visit:
http://flexscript.wordpress.com/2008/10/24/flex-component-lifecycle-and-flex-component-framework/
http://blog.deadinkvinyl.com/2008/10/05/flex-3-addchild-and-initialize/

Not sure if possible without adding it to the display list, although I'd wish it were to some extent.
I once had to make custom drag proxy, which didn't work with the real component, because of some weird skinning issues. So instead I had PopupMananger add a box as a popup, added my component to the box, called validateNow on the component, drew it in a bitmap data, removed the popup, and used the bitmap data as the proxy.
So what you were trying was missing a call to validateNow most likely.

Related

How can You refresh a vaadin grid after data change

How can You refresh a grid, when some new row was added to its datasoruce container or one of its rows has been edited?
I have tried the hacks written about here (http://www.helpsforcoder.com/code/31861375-vaadin-refresh-grid-after-row-modification.html ) and here (deleted link to malicious advertisement) but with no positive result. I add / edit the row in a separate subwindow that 'pop-ups' over the view, where the grid, that should update its contents, is placed.
grid.getDataProvider().refreshAll();
Grid listens to changed property values. So if you are working on the property level of vaadin everything should be fine.
If you extract your bean out of the BeanItemContainer you directly manipulate the values of the bean. That way the property container can not recognize your manipluating action.
So you have to send your grid implementation a message, the properties have changed manually.
When your BeanItemContainer still has the hard reference to the changed object, grid.markAsDirty() should work.

JavaFX nodes - How to make them resizable by the end user?

I am developing a JavaFX application where a class I have developed (extended from javafx.scene.Parent) is created on-the-fly based on what entry the user has clicked in a ListView control.
Just to be clear about this node, it is not created using a layout tool like SceneBuilder, it is created at runtime based on the user's actions.
The constructor for my custom node class creates a VBox and a Label and uses passed coordinates (X,Y) in the constructor method to set its own Layout coords. I then use a custom utility class to make the node draggable. This new node is then added to the main application Pane.
However, I have failed to find out how I can make these nodes resizable by the user. That is, allow the user to mouse over the corner of the node, hold and drag to resize. An operation that all users are used to, no matter what the OS.
Has anyone done anything like this in JavaFX? (My searches on the subject only seem to pull up subjects on the automatic resizing that a parent node does with its child nodes.)
Many thanks,
Ian.
As you can see on the documentation of VBox you can only define minimum, prefered and maximum range, there's not really a way to make it manually resizable.
The only proper solution to solve your problem is to develop your own class to do it, because what you want seems very specific, with your problem description, I don't think use some layouts or panels will do what you exactly want.
I found something that you can use : Dragging to resize a JavaFX Region
This allows you to resize a region, all you have to do after is to put you VBox in this region, but notice in this article that :
Only height resizing is currently implemented.
This code won't work in JavaFX8, you'll have to check the comment to see how it worls in JavaFX8
Hope this helps.

How to update a QLayout and get the new dimensions before returning?

This is driving me nuts. I have a custom menu class that, when set visible, shows a list of items located in a particular folder. When a hardware button is pressed, my application gets the latest list of items, populates the menu with them, and returns.
The menu displaying these items uses a QListWidget filled with custom widgets. Each of the widgets contains one or more QLabels in a horizontal layout, and is created at the time the menu is shown. In order to adjust the text displayed based on the menu width available, I need to get the size of the QLabel AFTER it has been resized according to the layout, but before the menu becomes visible to the user. The problem is, my layout does not get updated until all of the functions constructing my list return.
I have tried QApplication::ProcessEvents() and the layout update functions, but none of them have updated the values of my QLabels before returning. I can set a QTimer when the button is initially pressed, and have it show the menu, update the items, and stop itself, but that seems like a terrible solution.
Any help would really be appreciated! I've spent most of a day on this.
Marlon
I had this exact problem and could not find an answer anywhere on the Internet. Calling Layout.update(), Layout.activate(), or widget.adjustSize() (all suggested in various places) all did not work.
I had a widget with a vertical layout that I wanted to add a QLabel to and then immediately use the size of the QLabel.
The only thing that worked reliably was
layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();
It would seem that layouts will just not recalculate until you either return from a function and allow the Qt event loop to progress or manually call show() yourself.
How to update a QLayout and get the new dimensions before returning?
Don't. You're not meant to do that. It'll drive you "nuts" because you're doing it backwards. Layout updates are handled asynchronously from the event loop. Instead of getting layout dimensions right away, set yourself up to be part of the system. Some options are:
Implement a custom widget that will interact properly with the layout, growing to fill the available width of the layout. Perhaps all you need is a size policy and a way to elide text?
Make a custom layout that takes the special properties of your use case into account.
You want to call QWidget::adjustSize() on your parent widget. This will force the layout recalculations.
Have you tried using layout()->update(); ?
I've tried many but nothing works for me on Qt 5.15.
Only invented little patch - create timer and get size after 20 msec:
QTimer::singleShot(20, this, [this]
{
const auto height = myLayout->contentsRect().height();
// ...
});

Make a Spark TitleWindow modal without using much AS3?

I want to be able to show a Spark TitleWindow container as a modal without having to construct it by code via AS3. I tried creating the TitleWindow before-hand manually by dragging and resizing it around and adding objects, etc then hiding it. Then on a button, I set the called function to the ones below:
public function doPopup():void {
testWindow.visible = true;
PopUpManager.addPopUp(testWindow, this, true);
}
Unfortunately, this only shows testWindow but not as a modal. I want it to be like this so that I can freely resize and design the layout of my TitleWindow and only have to call some function to show it as a modal one.
I'm pretty sure the reason you are seeing this behavior is because your TitleWindow (that you've declared within the mxml of the parent container) is already added to the stage even though it is set as not visible. A workaround you could try is to call this.removeElement(testWindow) in a creation complete handler for the parent container. That will get it off the stage so the PopUpManager can add it later properly.
Having said that, I would recommend putting your TitleWindow into a separate mxml file and instantiate it using the PopUpManager. It's cleaner that way and you can still use the design mode to lay it out as you see fit.
Hope that helps.
Try the Cairngorm 3 Popup library :
http://opensource.adobe.com/wiki/display/cairngorm/HowToUseCairngormPopup

Flex: Render an unrealized UIComponent to BitmapData?

What is the best way to render to a UIComponent which hasn't been added to the stage? (I'm using UIComponents as renderers for objects, and want to render new copies for image export, filtering, etc.)
Two strategies I've seen/used so far include realizing the component to ensure it calls all the lifecycle methods:
Add the component to Application.application, render with BitmapData.draw(), remove component. This is similar to what I've seen done for printing unrealized components as well.
Add the component to a pop up window, render with BitmapData.draw(), dismiss popup after rendering complete.
I believe both of these just rely on the UI not refreshing while the current thread/event is executing, though (1) could also rely on the component being realized out of view.
Is there a better way?
What I've used in the past with much success is the following:
Create a new instance of your component
Add an event listener for FlexEvent.CREATION_COMPLETE
Set visible=false on the component
Add the component as a child of the main Application
When the component is created, the event listener function will be invoked. The rest of the logic should be put in / invoked from your event listener function
Remove the event listener you added in step #2.
Use ImageSnapshot.captureImage() or captureBitmapData() to capture the visual representation of the component.
Remove the component from the main Application
Process the image data as you need to.
I've used this to snapshot various Flex charting components for use in PDF's generated on the server side. After getting the BitmapData I use the PNGEncoder or JPEGEncoder classes to compress the data, then encode it in Base64 before uploading to the server.
I'm pretty sure you can use the draw() method in BitmapData without having your component on the DisplayList.
For example is use it when I need to modify images I load with the Loader Class. In the init handler I create a BitmapData instance and draw the Bitmap from the loadInfo.content property, then copyPixels() or whatever I need to modify the loaded image
So much of a UIComponent's layout can be tied to it's context. This is especially true for a lot of its derivatives (e.g. HBox) since the fluidity of the layout is tied to it's parent's size and the number of siblings sharing its parents space.
Additionally Flex can be a real pain to get to visually update. Often critical render functions aren't done synchronously ... there are callLater, callLater2 and other hacky approaches that make dealing with the auto-magical layout properties of UIComponents a major headache. Not even calling validateNow or updateDisplayList can guarantee that the layout will be correct on the current frame (instead of a few frames in the future).
I suggest the best thing you can do is not use a UIComponent and try and use a Sprite or other.
Your approach to attach it but make it invisible (alpha = 0, mouseEnabled = false, mouseChildren = false) is decent. You should listen for the FlexEvent.CREATION_COMPLETE callback before you are certain it is properly laid out. Then you can bitmapData.draw it and then remove it from the stage. If you must use UIComponents then I know of no better way.
You can call the lifecycle function manually before using the BitmapData.draw(). Do the following.
createChildren().
commitProperties().
updateDisplayList().
bmd.draw().
The first 2 steps are not 100% necessary, you can put all codes into updateDisplayList(). Because you invoke the function manually, you don't have to worry this is invoked by Flex framework many times.

Resources