On a project I’m working on, I need to have semi-transparent containers to hold controls over top of screen-filling bright and colorful background. While I’m not 100% satisfied with it, I think it will suffice for the time being.

I was originally going for an effect similar to the window borders in Windows 7 where the background image is blurred when viewed through the glass. I couldn’t find an easy way to do that effect in Flex 4. If you know of a way, please comment below.

Live Demo – Right-Click to View Source

Posted by Andrew, filed under Flex, as3. Date: July 31, 2010, 11:03 pm | 1 Comment »

I recently had an opportunity to give a talk at 360|Flex along with Randy Troppmann. Slides and code examples are posted below. Video of the session will come sometime in the unforeseen future as they have many hours of other sessions to post-process before getting to mine.

Presentation PDF (warning: large)

MileageBuddy (viewsrc enabled)

HeatmapExample (viewsrc enabled)

Test GPX file

Posted by Andrew, filed under 360 Flex, AIR, Data, Degrafa, Flex, GPS, as3. Date: March 11, 2010, 5:04 pm | No Comments »

I had the privilege of speaking to the Indy Flex User Group last night on the topic of Degrafa. While I’m not one of the architects or contributors to the project, I do make extensive use of Degrafa in most of my personal and consulting development work. Below is presentation material and example code I used during the presentation. All the examples have view-source enabled. Just right-click.

Presentation:
Degrafa_IndyFlex_User_Group.pdf

Simple Circle Example:
DegrafaExample1

Button Skinning Example:
DegrafaExample2

Component Development Speedometer Example:
DegrafaExample3

Axiis Example:
Smith Chart Example

ChromaPassword FXG Example:
ChromaPassword

MiniShapeDesigner Example (note, not mine):
MiniShapeDesigner

Posted by Andrew, filed under Degrafa, Flex. Date: February 24, 2010, 9:44 am | 3 Comments »

I’m slated to speak at 360|Flex San Jose on March 7-10 on the topic of GPS data and doing neat things with it in Flex/AIR. I’ll be co-presenting along with Randy Troppmann. Randy had been doing work for quite awhile in the GPS space with his work on runningmap.com. Runningmap.com is a website that allows runners/walkers/joggers/movers to track and catalog their accomplishments. They’ve also developed an iPhone application that can record your gps track as you run. It’s quite an honor to be able to present with such an accomplished developer.

I’ve been holding off on doing a blog post about 360|Flex until I could give you a sneak peak of the new prototypes of Swift GPS. Swift GPS is a wearable hardware device that will allow you to record GPX files to a USB thumbdrive that tracks your current position and movement. During my part of this session, we’ll go into how to take this GPX data and do neat things with it in Flex like overlay the data onto a 3D map. Other highlights will be doing a bit of heat-mapping using the GPS data.

This conference WILL SELL OUT, so don’t be one of the hundreds of chumps posting regrets to your twitter account after the conference starts and you didn’t get in. Click on my 360|Flex badge on the right-side of the blog to sign up today. If I win the speaker suite for the most signups through my blog badge, I’ll give away a prototype device to one of the people who helped put me over the top. Don’t wait. Sign up today.

Posted by Andrew, filed under 360 Flex, Data, Flex, GPS. Date: February 9, 2010, 8:42 pm | No Comments »

GraniteDS is a free and open source (LGPL’d) alternative to Adobe® LiveCycle® (Flex™ 2+) Data Services for Java EE application servers. Java Message Service (JMS) is a technology designed for handling real-time Publish/Subscribe architectures of which Apache ActiveMQ is an implementer.

By default, the GraniteDS messaging architecture (called Gravity) uses its own internal simple Publish/Subscribe infrastructure. This works great if your front-end only needs to worry about handling clients from Adobe Flex, but what about if you need to send messages from other back end processes and have your flex app update in real-time?

The GraniteDS download package ships with a good example called graniteds_chat. It demonstrates a simple chat application between two or more Flex clients using the built-in Publish/Subscribe architecture of GraniteDS’s Gravity component. My goal is to use this example, but replace the default GraniteDS architecture with the more robust ActiveMQ architecture running in a separate process.

The reasons for doing so are several. First, ActiveMQ can handle persistent messaging. If my server crashes for some reason, I won’t lose messages that were currently in the queues/topics. Secondly, I want to demonstrate running ActiveMQ in a separate process. GraniteDS already has an Embedded ActiveMQ example on their wiki where it loads and runs inside the Tomcat container. I want to break it out as a completely separate process. This gives me additional future scalability if I need to run ActiveMQ on a different box entirely, or setup a multi-machine JMS infrastructure.

First, download the latest package of GraniteDS. Extract out the folder structure, and modify any of the env.properties file to point to your installed Flex SDK. My env.properties inside graniteds/examples/graniteds_chat looks like this:

#==============================================================================
# Granite Data Services Examples build properties (http://www.graniteds.org).
#==============================================================================

# Set 'FLEX_HOME' property to your flex3 sdk installation directory and
# 'FLEX_TASKS_JAR' to your flexTasks.jar location.
FLEX_HOME=C:/Program Files (x86)/Adobe/Flex Builder 3 Plug-in/sdks/3.4.0.9271
FLEX_TASKS_JAR=${FLEX_HOME}/ant/lib/flexTasks.jar

# Set 'SERVER_HOME' property to your JBoss installation directory and
# 'SERVER_HOME_DEPLOY' to your JBoss deploy directory.
#SERVER_HOME=/jboss-4.2.3.GA
#SERVER_HOME_DEPLOY=${SERVER_HOME}/server/default/deploy

# Alternatively, set 'SERVER_HOME' property to your Tomcat installation
# directory and 'SERVER_HOME_DEPLOY' to your Tomcat deploy directory.
SERVER_HOME=C:/apache-tomcat-6.0.16
SERVER_HOME_DEPLOY=${SERVER_HOME}/webapps

Next, run ANT inside the graniteds_chat folder. It will pick up everything that needs to be compiled from the parent folders and deploy a war package to your local tomcat installation. Before starting tomcat and watching the default chat example in action, you’ll first have to modify Tomcat a bit so that it can support non-blocking IO. GraniteDS recommends using either the HTTP APR or the NIO connector in Tomcat to enable non-blocking IO. For our purposes, we’ll use the NIO connector for Tomcat. Inside the Tomcat conf folder, edit server.xml and look for a line like the following:

<Connector port="8080"
           protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

Modify this section so that Tomcat can use the NIO Http connector.

<Connector port="8080"
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           connectionTimeout="20000"
           redirectPort="8443" />

After that change is complete, start Tomcat and navigate with two separate browsers to http://localhost:8080/graniteds-chat. Login with separate usernames and make sure that you can chat successfully between the two browsers. You should see something like the following:
Andrew1_chat
Andrew2_chat

Next, let’s go about integrating ActiveMQ. Download and install ActiveMQ in its own folder. Browse to the bin folder and run activemq.bat. This should be all we need to do on the ActiveMQ side of things. Next, we need to configure GraniteDS to talk to ActiveMQ via JMS instead of its internal messaging architecture.

Stop Tomcat and drill into the installed chat application and modify services-config.xml. Mine is located at C:/apache-tomcat-6.0.16/webapps/graniteds-chat/WEB-INF/flex/services-config.xml. Before editing, you’ll notice that it’s using its own internal SimpleServiceAdapter.

<?xml version="1.0" encoding="UTF-8"?>

<!--
 GRANITE DATA SERVICES
 Copyright (C) 2007-2008 ADEQUATE SYSTEMS SARL

 This file is part of Granite Data Services.

 Granite Data Services is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 3 of the License, or (at your
 option) any later version.

 Granite Data Services is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, see <http://www.gnu.org/licenses/>.
-->

<services-config>

    <services>
        <service id="messaging-service"
           class="flex.messaging.services.MessagingService"
           messageTypes="flex.messaging.messages.AsyncMessage">
            <adapters>
                <adapter-definition id="default" class="org.granite.gravity.adapters.SimpleServiceAdapter" default="true"/>
            </adapters>

            <destination id="gravity">
                <channels>
                    <channel ref="my-gravityamf"/>
                </channels>
            </destination>
        </service>
    </services>

    <channels>
        <channel-definition id="my-gravityamf" class="org.granite.gravity.channels.GravityChannel">
            <endpoint
               uri="http://{server.name}:{server.port}/{context.root}/gravity/amf"
               class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

</services-config>

You’re going to want to modify this services-config.xml file so that it uses ActiveMQ and the JMS Adapter.

<?xml version="1.0" encoding="UTF-8"?>

<!--
 GRANITE DATA SERVICES
 Copyright (C) 2007-2008 ADEQUATE SYSTEMS SARL

 This file is part of Granite Data Services.

 Granite Data Services is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 3 of the License, or (at your
 option) any later version.

 Granite Data Services is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, see <http://www.gnu.org/licenses/>.
-->

<services-config>

    <services>
        <service id="messaging-service"
           class="flex.messaging.services.MessagingService"
           messageTypes="flex.messaging.messages.AsyncMessage">
            <adapters>
                <adapter-definition id="default" class="org.granite.gravity.adapters.JMSServiceAdapter" default="true"/>
            </adapters>

            <destination id="gravity">
                <channels>
                    <channel ref="my-gravityamf"/>
                </channels>
                <properties>
                    <jms>
                        <destination-type>Topic</destination-type>
                        <connection-factory>java:comp/env/jms/flex/TopicConnectionFactory</connection-factory>
                        <destination-jndi-name>java:comp/env/jms/discussion</destination-jndi-name>
                        <destination-name>discussion</destination-name>
                        <acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
                        <transacted-sessions>false</transacted-sessions>
                        <!--
                             JNDI environment. Specify the external JNDI configuration to
                             access a remote JMS provider.
                        -->
                        <initial-context-environment>
                            <property>
                                <name>Context.PROVIDER_URL</name>
                                <value>tcp://localhost:61616</value>
                            </property>
                            <property>
                                <name>Context.INITIAL_CONTEXT_FACTORY</name>
                                <value>org.apache.activemq.jndi.ActiveMQInitialContextFactory</value>
                            </property>
                        </initial-context-environment>
                    </jms>
                </properties>              
            </destination>
        </service>
    </services>

    <channels>
        <channel-definition id="my-gravityamf" class="org.granite.gravity.channels.GravityChannel">
            <endpoint
               uri="http://{server.name}:{server.port}/{context.root}/gravity/amf"
               class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

</services-config>

You may have noticed that the GraniteDS JMSServiceAdapter uses JNDI to find and connect to JMS. Since Tomcat has a valid JNDI container, let’s define the necessary info in Tomcat. You can add the JNDI info inside tomcat’s conf/context.xml file.

<?xml version='1.0' encoding='utf-8'?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->
<!-- The contents of this file will be loaded for each web application -->
<Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
   
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
   <Manager pathname="" />
   -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
        on session expiration as well as webapp lifecycle) -->
    <!--
   <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
   -->
   
    <Resource name="jms/flex/TopicConnectionFactory"
              type="org.apache.activemq.ActiveMQConnectionFactory"
              description="JMS Connection Factory"
              factory="org.apache.activemq.jndi.JNDIReferenceFactory"
              brokerURL="tcp://localhost:61616"
              brokerName="activeMQBroker" />
    <Resource name="jms/discussion"
              type="org.apache.activemq.command.ActiveMQTopic"
              description="Discussion topic for GraniteDS"
              factory="org.apache.activemq.jndi.JNDIReferenceFactory"
              physicalName="discussion" />
   

</Context>

Finally, copy activemq-all-5.3.0.jar from your ActiveMQ install folder to apache-tomcat-6.0.16/webapps/graniteds-chat/WEB-INF/lib. This will ensure that JNDI has access to the ActiveMQ classes it needs to communicate to the ActiveMQ JMS broker. Start tomcat and refresh your two browser windows running the chat application. Send a few messages back and forth to ensure everything is working.

Now, we need to prove to ourselves that messages are indeed going through ActiveMQ and not just through GraniteDS. Open a new browser tab to the ActiveMQ monitor page http://localhost:8161/admin/topics.jsp . Make sure that the topic "discussion" exists and has some enqueued and dequeued messages.
active_mq_topics

If you really want to test out the system, create a simple Java program that can send a JMS message to ActiveMQ. Make sure the resulting message ends up in your Flex app.

import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;

public class ChatTest
{

    /**
     * @param args
     */

    public static void main(String[] args)
    {
        try
        {
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
            Connection connection = connectionFactory.createTopicConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            // create our request and response queues
            Topic topic = session.createTopic("discussion");
            // and attach a producer to the topic
            MessageProducer producer = session.createProducer(topic);
            // and start your engines...
            connection.start();
           
            // now send our test JMS message
            Message message = session.createObjectMessage(new String("Hello from JMS"));
            producer.send(message);
           
            //sleep a bit to make sure our message sent ok
            Thread.sleep(10000);
           
            session.close();
            connection.close();
            System.out.println("Sent message ok");
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }

    }

}

Posted by Andrew, filed under Data, Flex. Date: November 16, 2009, 11:44 am | 4 Comments »

dual_dragmanagers

The new Flex 3.4 SDK has been released. Since Adobe still hasn’t gotten around to fixing this bug, I’ve again taken it upon myself to release my MonkeyPatched code for Flex 3.4 that allows you to use the Flex DragManager along side the Native DragManager in an AIR app. You can grab the code from SVN from my google code site.

http://code.google.com/p/andrewwestberg/source/checkout

Posted by Andrew, filed under AIR, Flex, MonkeyPatch, as3. Date: August 28, 2009, 12:53 pm | No Comments »

oh_example

I’ve been using the ObjectHandles flex library project for quite some time. It’s used in the Nitro-LM Admin tool to give us resizeable horizontal menus.

In the new version of ObjectHandles2, we have the ability to use Sprites as the drag handles to resize and move objects around the screen. I was recently made a committer on the project and have added some functionality to allow Degrafa to be used to draw the handles and rotate them along with the object. Check out Example7 that highlights this new functionality.

ObjectHandles2Example View Source is enabled

Posted by Andrew, filed under Degrafa, Flex, as3. Date: August 25, 2009, 7:17 pm | 5 Comments »

I’ve recently had the opportunity to dig into Flex 4 skinning a bit deeper with the latest beta. While there is a lot to be desired from the separation of concerns in moving display code into the skin and leaving logic code in the component, there is one LARGE gaping deficiency in Adobe’s model.

I’ve noticed a number of people here (Andy McIntosh), and here (Andy Hulstkamp) working with button icon skins. The main reason for this is that Adobe saw fit to remove the icon property from the Spark button. Being a visual element, it does make some sense for Adobe to let users specify a button icon inside a skin as opposed to putting it in the main Button component.

Now to address the LARGE gaping deficiency in Adobe’s model. Adobe developed the skinning architecture WITHOUT taking something into account that we developers use on a regular basis. This is the Object Oriented principal of Inheritance. Note the following excerpt from Adobe’s livedocs:

Try to encapsulate skinning code. Place code that is used by multiple skins in the component class. Place code that is specific to a particular skin implementation in the skin class.

Most skins use absolute layouts within the skin class.

When creating skins, do not subclass existing skin classes. Instead, copy the source of an existing skin class and create another class. Use this method especially if you are going to reuse the skin for multiple instances of a component or multiple components. If you want to change the appearance of a single instance of a component, you can use FXG inline.

When creating a Spark skin, you can use MXML, FXG, embedded images, or any combination of the above. You do not use run-time loaded assets such as images.

The inability to inherit skins is going to kill my productivity as a developer. For example, let’s say I really liked the code Andy McIntosh had done with the IconButton (which I do) and wanted to re-use it. Let’s say I’ve also done some work on button skinning for my application and I want nice looking gel buttons like this:
gel_button

Can I set up my GelButtonSkin to inherit from Andy’s IconButtonSkin to take advantage of his image functionality, but override his background drawing with my own? The simple answer from Adobe is NO. In order to accomplish what I want, I’ve have to create a completely new skin class and use copy/paste from both my GelButtonSkin and Andy’s IconButtonSkin to get my desired functionality.

You might say, “Well, Adobe says in the quote above that code that is used by multiple skins should be placed in the component class”. This begs the question though… Why did Adobe remove icon as a button property in the first place? It’s obviously one of those things where you might want different flavors of it. Perhaps a rectangle button /w icon vs. a rounded button /w icon. Instead, we’ll see a fragmentation of Flex while everybody and their brother develops their own flavor of IconButton along with their own custom skins to do exactly what they want. Productivity for developers moving between projects is going to take a hit due to this lack of code re-use.

Note: This post is intentionally antagonistic. I’d love to be proven wrong on my assertions. If someone has come up with an elegant work-around to the problem of skin re-use and inheritance that doesn’t resort to copy/paste, I’d love to be educated and saved from my ignorance.

Posted by Andrew, filed under Flex. Date: August 3, 2009, 3:56 pm | 51 Comments »

Get Adobe Flash player


View Source

I came across this infosthetics blog post discussing a Javascript interface for doing Chroma password.

I hadn’t yet had a chance to dive into any Flex 4 stuff, so I thought this might be a good little opportunity to play around with it. My algorithm isn’t exactly as described in the blog post, but it seems to work effectively. I’m using a portion of the SHA256 hash to generate the various colors. I’m animating between colors so as long as you type more than 1 character every 1/2 second, a screen grabber can’t grab the intermediary colors and figure out your password through trial/error.

This type of component is useful for ensuring that a person has entered their password correctly or to help them notice right away that their capslock key was on while typing it.

Posted by Andrew, filed under Flex, security. Date: July 31, 2009, 4:05 pm | No Comments »

I was at 360|Flex Indy in the session on the Axiis Data Visualization Framework presented by Tom Gonzales and Michael VanDaniker. Axiis is a framework built on top of degrafa that allows you to develop new and unique data visualizations that can go way beyond the simple column, bar, and pie charts available in the standard Adobe Flex charting libraries.

One of Tom’s first slides showed a Smith Chart. Tom mentioned jokingly that Axiis didn’t yet do something this complicated. For me sitting in the room, I was a bit taken aback. In my WCAP project, I have an open enhancement ticket from a customer asking for a smith chart visualization for transmission lines. They want to be able to click on a transmission line and view the directionality of the data on a smith chart. My original plan for accomplishing this ticket was to simply use an image for the smith chart background and draw my data on top of it. I must admit, I took Tom’s admission that Axiis couldn’t do a Smith chart as a throwing down of the gauntlet of sorts. I talked to him afterward to let him know I wanted to take on the challenge.

To date, I’ve only been working in Degrafa to get the basics of everything down. I’ll need to solicit Tom and Michael’s help in porting the work I’ve done over to Axiis and open-sourcing the code once I get a little further with it. So far, the most difficult part was calculating the arc angles and radii for each line on the smith chart based on the smith chart coordinates where the arc started and stopped. I still have a way to go in adding the various text labels along the curves as well as porting my work into a more reusable Axiis container.

The image above is the from-impedance(red) and to-impedance(blue) data across a 50 ohm transmission line with a sweep from 0.98mHz to 1.02mHz using a data point every 0.001mHz.

Hopefully, this little endeavor will benefit my WCAP customers as well as the open-source Flex community at the same time.

Posted by Andrew, filed under 360 Flex, Degrafa, Flex, WCAP. Date: May 30, 2009, 10:17 pm | 4 Comments »

« Previous Entries