Programmatically add character to TextInput when Hiragana IME is active - apache-flex

I'd like to be able to add a character to a TextInput programmatically (say when you press a button) even when using IMEs (I'm using a Japanese IME right now). Normally this would be super easy, i.e.
protected function button_clickHandler(event:MouseEvent):void
{
ti.text = "k";
}
where ti is a TextInput component. However, things get a little tricky when using an IME. The code above, for instance, adds a k in ti even if you're using the Hiragana IME.
I looked at the IME documentation and tried something like this
protected function button_clickHandler(event:MouseEvent):void
{
IME.setCompositionString("k");
}
at first I thought this was doing the trick, but it seems like it always defaults to what looks like Half-Width Katakana (although I'm not 100% sure), even if the Hiragana conversionMode is currently selected, or if I set it right before setting the composition string. Unfortunately the IME library doesn't seem to be open source so I have no idea if this is a bug or not.
Was wondering if anyone had any advice - I realize this is super specific so the odds are low, but thought I'd try.
thank you!
post-edit: here is some code to try out what I'm talking about. Note: you'll need Japanese IME setup on your machine. I'm using this on a Windows 7 box with Japanese IME setup, and running it on standalone Flash. It's hard to see the difference between typing a k in Hiragana and in Katakana, but if you look closely you should notice a difference (and if you type an 'a' right after you should see different results popping up).
<?xml version="1.0"?>
<!-- dpcontrols/adg/SimpleADG.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
protected function button_clickHandler(event:MouseEvent):void
{
ti.setFocus();
try
{
IME.enabled = true;
IME.conversionMode = IMEConversionMode.JAPANESE_HIRAGANA;
IME.setCompositionString("k");
}
catch (error:Error)
{
trace("Unable to set conversion mode.\n" + error.message);
}
}
]]>
</fx:Script>
<s:VGroup>
<s:TextInput id="ti"/>
<s:Button label="go" click="button_clickHandler(event)"/>
</s:VGroup>
</s:Application>

First, look at this link: http://livedocs.adobe.com/flex/3/html/help.html?content=18_Client_System_Environment_6.html
Make sure you have IME enabled and the proper settings. Second, what version of flex are you using? Do you have a font that's loaded into the application that can handle the language?

filed a bug - we'll see what Adobe says.

Related

Drag & drop of files from the file system into Flex doesn't work

I am trying to implement drag & drop of files from the file system into Flex, but somehow it doesn't work.
To be precise, it refuses to register when the nativeDragEnter event happens, meaning, it doesn't do anything when i drag a file system file into a component. I tried it with mx and spark components, using flex 3.6A and 4.10 but nothing works.
I am working on Windows 8.1. Could this be the problem?
Below is what i did, did i miss something?
<mx:Script>
<![CDATA[
protected function hbox1_nativeDragEnterHandler(event:NativeDragEvent):void
{
var a:String = "segdfsh";
}
]]>
</mx:Script>
<mx:HBox width="100%" height="100%" nativeDragEnter="hbox1_nativeDragEnterHandler(event)">
</mx:HBox>
The code in the question seems to work after all, but for some reason it didn't work if i debug it from Flashbuilder, but when i release my project, then it works like a charm, so yeah, no issue here, i guess.

Flex List item renderer

I have created an item renderer spark list in flex , but i want to call a function on addition of new row in list and not afterwards. I am getting a data object in rendered list in it i am getting the type of data to be displayed in list ie. either text or image. So on addition of new data in list i want a function to be called up in rendered list that checks the type of data received and then it will either create and add an image element or a text element. So the main problem is how i get a function called on addition of data. I have tried events like datachange and added but they keep on calling the function over and over again when we scroll the list but i want the function to be called once only on addition of data and not after wards. Below is the renderer list code , maybe you will get a better idea of what i am trying to do:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" dataChange="test_add()">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
public function test_add() : void {
Alert.show("type="+data.msg_type);
if(data.msg_type=="text"){
//code to create and add new text element to list_row//
}
if(data.msg_type=="image"){
//code to create and add new image element to list_row//
}
}
]]>
</fx:Script>
<s:Group id="list_row" width="100%" verticalAlign="middle" verticalCenter="0">
</s:Group>
</s:ItemRenderer>
Any help will be highly appreciated.
Thanks
As far as I can tell from the code you show, the easiest solution to your problem would be to work with two separate ItemRenderers: one that renders text and the other that renders images. You can do this using the SkinnableDataContainer#itemRendererFunction property instead of itemRenderer.
The List with the new property:
<s:List id="myList" dataProvider="{dp}"
itemRendererFunction="getItemRenderer" />
The function that returns a factory for the right ItemRenderer.
private function getItemRenderer(item:Object):IFactory {
if (item.msg_type == "text")
return new ClassFactory(MyTextItemRenderer);
if (item.msg_type == "image")
return new ClassFactory(MyImageItemRenderer);
}
In these two different ItemRenderers you can then display your data as you wish.
Edit: why it's OK that the dataChange event fires every time you scroll.
There is in fact nothing wrong with your approach as you describe it, although I would argue that the itemRendererFunction approach allows for better separation of concerns. I could tell you that you can turn the unwanted behavior off, simply by setting the List#useVirtualLayout property to false.
<s:List id="myList" dataProvider="{dp}"
itemRenderer="myItemRenderer" useVirtualLayout="false" />
Though this will do what you ask for (i.e. create the ItemRenderers only once), that would not be good advice. There is a good reason this property is set to true by default.
When virtual layout is used, item renderers are created only as they are needed, i.e. when they come into view and need to be displayed to the user. This allows you to load thousands of items without performance loss.
Let's say you load 1000 value objects: that doesn't take up much memory or CPU. But now you want to render them. If you don't use virtual layout an item renderer will be created for all of them up front, which means thousands of graphic elements and thousands of event listeners (how many exactly depends on your setup). Now that is going to hurt performance on a slow computer.
If you do use virtual layout only - say - 10 item renderers will be created at once. If the user scrolls down, the next 10 will be created and the ones that just disappeared from the view are removed and eventually garbage collected. So you see: what you may have perceived as something that was bad for performance at first, is actually a very good thing.
So I would advise you not to do what I just told you. Unless perhaps you would have a situation where you knew there would never be more than a very limited number of items in your List. Then you may consider not using virtual layout.

Allowing mouse events to bubble reliably through the youtube chromeless player?

Hello all!
I'm working on a prototype that would require me being able to read and track the mouse movement over a playing youtube video. The basic code to replicate my problem boils down to this simple test case:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
initialize="{go();}">
<mx:VBox>
<mx:Label id="test" text=""/>
<mx:SWFLoader source="http://www.youtube.com/apiplayer?version=3" />
</mx:VBox>
<mx:Script>
<![CDATA[
function go(){
Security.allowDomain("*");
Security.allowInsecureDomain("*");
addEventListener(MouseEvent.MOUSE_MOVE,
function(e:MouseEvent){trace(test.text=e.stageX+"")});
}
]]>
</mx:Script>
</mx:Application>
Expected behavior is:
Youtube player loads
The label on the top right tracks the X coordinate of the mouse
The number should update even when moving the mouse over the Youtube player
So far the program behaves as expected when running from the IDE (tested on both FlashDevelop and FlashBuilder) and even when running the file manually from the output folder. But, alas, when I try to run it from anywhere else than the debug folder (be it another location on my computer or up on a webserver), the Youtube player seems to eat the events.
I don't get sandbox security warnings when debugging (thanks to allowDomain("*")) but I'm running out of ideas on why the program fails once you take the file out of the debug folder.
I would immensely appreciate any clues. Please note that as far as solutions go, I'm willing to try a different tech than flash if you have a proof of that working somewhere else.
Ok so I'm answering my own answer (I know...) only to let it recorded somewhere if someone needs it.
As much as I tried, there was no success with tweaking the security sandbox settings. I even tried all possible combinations, and no dice.
What I did do, out of desperation, was actually adding mouse listeners to the Loader.content property once loading is finished. And it worked well enough.
It's the only place I've found where a loading application can safely access the loadee's mouse events without obstructing its inner mouse logic.
Hope it helps someone else get unstuck in the future!

Runtime problems after migrating from Flex3 to 4 in compatibility mode

We are migrating our Flex-3.2 application to Flex 4.1, mainly to take advantage of the new text flow/engine features. In a first step we decided to go with compiling for MX-only and in Flex-3-compatibility mode.
Thanks to some helpful resources (
http://www.adobe.com/devnet/flex/articles/flexbuilder3_to_flashbuilder4.html
Any Flex 4 migration experience?
http://www.adobe.com/devnet/flex/articles/flex3and4_differences_02.html
) I am able to compile our application.
But I find myself surprised about the amount of runtime differences ranging from the problem that I cannot cast ResultEvent.currentTarget to HTTPService ( which apparently was introduced in 3.5 ) to many layout problems to differences in event dispatching ( e.g. one of our legacy components listens to the add event which it just doesn't seem to get anymore ).
It seems there is very little documentation on this. I'd like to find a list with detailed changes so that we don't have to rely on QA to stumble across hopefully all issues.
This documents lists some, but doesn't seem exhaustive.
Does someone have a better list of documented changes?
Thanks
Stefan
PS. List of concrete examples I have found so far:
1) In Flex 4 the add event is not fired:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" layout="absolute" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
private function notFired():void
{
trace("ADDED");
}
private function fired():void
{
trace("COMPLETE");
}
]]>
</fx:Script>
<mx:TextArea add="notFired();" creationComplete="fired();"/>
</mx:Application>
Now do the same in Flex 3 and you'll see both events fire.
Apparently, this is a bug. Might be possible to work around this but certainly decreases my level or trust substantially.
2) Dialogs/popups show all content mirrored.
A bug as well. Easy to work around, but how could something that obvious slip?
3) Problems with injected "Ôª" chars.
See post here.
Let's see some of your doubts...
1) add never was a reliable event since flash player 9 release. It's a common bug. Try to create a movieclip out of displaylist and add a child in it that have the Event.ADDED listener. In some situations (don't know exactly what situation) it doesn't work (Adobe Fail). But, instead the "add" flex event, use the "added" or "addedToStage" once you want to detect if it's already in your applications display list.
2) Fail. Check the layout manager source-code of the framework.
3) I've never seen this. (Even in compatibility mode). Can you show an example? Did you check if the application encoding is the same you're using on your strings? Maybe the string table could be doing some confusion due to the characters encodings (or maybe your editor). Try other editors and verify the code file contents on a linux shell with SED. With a find and a sed you can fix it easily.

Optimal way to enable user to pick style at run time - Flex

What I'm trying to do: allow a user to be able to select a color palette for a custom component by selecting from a drop down menu with a variety of icons.
I have the drop down menu part down, but I'm trying to understand how to best handle the various styles in my code. Ideally I would have liked to be able to load styles at run time, but I don't see a major advantage with this so I'm now thinking about compiling in all styles. Still, I can't seem to find a decent way to structure the code. Hacking it seems pretty easy / fast, but there's got a better way than having a big fat array of values which can be indexed via some index associated with each icon - yuck!
Would love to hear your thoughts or see any pointers to obvious ways to handle this.
thank you!
fred
I'd define a set of style names in CSS, then you can use a collection of style names to provide values for your style selector control, like so:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Style>
.style1{color:red;}
.style2{color:green;}
.style3{color:blue;}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
public static const styleNames:ArrayCollection =
new ArrayCollection(['style1', 'style2', 'style3']);
]]>
</mx:Script>
<mx:ComboBox
id="styleCombo"
styleName="{styleCombo.value}"
dataProvider="{styleNames}"
/>
</mx:Application>
The optimal way to achieve this is to compile several CSS+Swf(assets) files and then loading them at runtime according to what the user selected.
This is by far the best practice out there, I used it for large applications and small applications and it stands tall above every other solution I could think of.
good luck

Resources