Archive

Posts Tagged ‘JavaFX’

JavaFX Production Suite 1.2 on Linux

June 9th, 2009

So they have finally added support for JavaFX in Linux.  but the JavaFX Production Suite hasn’t been migrated yet.  Which is understandable, because the Adobe Suite isn’t exactly ported over, but you can still use the SVG Converter.  To port it over you first need to download the JavaFx Production Suite 1.2 Windows package.
Next run the cabextract utility, to pull all of the files out of the Windows executable (in the Debian distros, you should be able install cabextract with a - sudo apt-get install cabextract).  Just move the javafx_production_suite-1_2-windows-i586.exe to a separate directory and then run the cabextract from the command line:

cabextract javafx_production_suite-1_2-windows-i586.exe

Ultimately all you need is the svg2fx.jar file, and then you can run the interface with:

java -Xmx512M -classpath ./svg2fx.jar com.sun.javafx.tools.svg2fx.main.UIMain

If all of that sounds too annoying you can just download the jar file and the script to launch it from here.

tekgnu Linux, Programming , , ,

JavaFX 1.2

June 3rd, 2009

JavaFX has been quite a pleasure to learn thus far. If you have seen my tutorial on creating an SVG drawing, and adding functionality to it, you know I have been trying to learn the intricacies of the JavaFX scripting language.
Up to now, I have been plugging away on either my work laptop with Windows, or have implemented the necessary work-a-rounds to get the SDK to work in Linux. Such as the one proposed by Weiqi Gao, which by the way was a very cool work around on mounting the MAC JavaFX 1.0 SDK .dmg file as a loop back device.

And then came 1.2

Clearly JavaOne increased whipping the development horses. This truly is no minor release. Aside from the added support for Linux and OpenSolaris, there have been a bunch of additional changes from the core language (in support for Java Arrays, and the addition of Math functions) to significant addins (I am looking forward to investigating the new Task class). That being said, there comes some retrofitting. The first I noticed while opening my DialUI is that the UIStub, is no more.  Thus, when I opened the newly updated Netbeans to 6.5.1, I discovered a lot of RED. The UIStub has since been replaced by FXDNode, and there are some additional finite language changes.
Keep your eye out for my next article on JavaFX, I am sure there should be quite a few changes to the tutorial.  To get an excellent run down on some of the changes take a look at this article from Stephen Chin.

tekgnu Linux, Programming , , ,

Part 3. Breathing life into our JavaFX Dial

May 20th, 2009

Aeons ago when I wrote part 2, JavaFX was in it’s infancy at version 1. part3_javafx_dial Now we have leaped forward to version 1.1, ( :) ). The 1.1 release is clearly more of a bugfix, and by designed more of a teaser for some of the missing elements. We have the SDK where are the phones? And more importantly to the OS community where is my formal Linux release (fortunately there are work arounds).

Where we left off
In Part 2 of this article we took the very flat drawing, and turned it into a much more pretty dial. This only touched on the graphical horse power of JavaFX.  In this article, I address adding functionality into the JavaFX dial, by hitting some of the key functionality of JavaFX. From Animation, and Multimedia, to Event Handling to Transformations, this has been somewhat of a bumpy road.

The Good, the Bad, and the Ugly
Yes, the road has been very bumpy. Maybe my lack of experience, or maybe it is the
youth of the JavaFX environment, but I have learned alot by adding functionality to
the JavaFX dial.

The Good: Clean, logical code, that reads very well.
I didn’t find that I had to create any creative logic flows (man do I miss the goto command (simple, yet confusing), or for those C(++) programmers out there, man do I miss troubleshooting pointers (there is nothing that can expedite gray hair and baldness quite like it)).
Also anyone familiar with Event Handlers in Java will love this:

top.onMouseReleased = function(event : MouseEvent)
{
  if (enableAudio) { sndMuted = true; }
}

Yes that’s it, I released the mouse button, and (if I had enabled sound) then the sweet
clicking sound pilfered from my daughter’s toy would stop (more appropriately mute, a topic best left to the ugly).
Click the mouse again, and the sndMuted variable which is bound to the MediaPlayer itself, gets set to false,
and the clicking knob audio continues.
Another short snippet that is new, and very intuitive:

var animRotation = Timeline
{
  keyFrames:
  [
    at(0ms) { currAngle => currAngle }
    at(5s) { currAngle =>
      dialRotation tween Interpolator.LINEAR }
  ]
}

That is purely and simply animation. The dial is a’ spin’in.

The Bad - the lessons learned
So admittedly I am my own worse enemy. Rotating the dial represented a series of interesting challenges. First challenge: rotating the dial with the mouse. I appeal to anyone to provide a more simplistic answer, and will gladly throw them some street cudos. When I started pondering rotating an object based on the distance of the pointer, my head begain spinning (that’s when I realized that the speed at which my head was spinning was the more I thought about the problem). Then came the math (not my forte). So I thought myself into a triangle, and realized the three points as where the mouse was, where the mouse is, and the center of the circle.
The reasoning here is that the furhur you are from the center of the circle, the slowere the dial would rotate.
Nevertheless, I found the Law of Cosines to Trigonometrically solve my puzzle.
Yes that was ugly:

currAngle = dialRotation;
pointCurrent = Point2D
{
  x: event.x;
  y: event.y;
}
sideA = pointHub.distance(pointClick);
sideB = pointHub.distance(pointCurrent);
sideC = pointClick.distance(pointCurrent);

var cosC: Number = 0;
cosC = (Math.pow(sideA, 2) +
Math.pow(sideB, 2) -
Math.pow(sideC, 2)) /
(2 * sideA * sideB);

// Radians to Degrees + pointer alignment factor.
dialRotation +=
cosC * 57.2957795 + 30;

if (dialRotation < 0)
dialRotation = dialRotation + 360;
if (dialRotation > 360)
dialRotation = dialRotation - 360;

The second challenge: rotating a circle within an invisible box is seamless, but the second you add a pointer protruding outside the radius, you have a problem. The problem makes complete sense, the second you rotate the dial and the pointer hits the containing box, the entire dial shifts just enough to keep itself contained within the invisible box.  My workaround was I cheated. I started going down the path of maybe extending the containing scene, but then I realized that I just preferred the look of a smaller pointer. Yes, of course it worked but the lesson here is to be aware of the bounding rectangle to each object when a transform is applied.  The last “Bad” in the rotation challenge is around using the transforms. I wanted to utilize the rotate transforms to manage the load of constantly executing the trigonometric functions.  Ultimately I ended up using Animation (I hate to say it, but without direct support for Threads in JavaFX, I can see using Animation as a process controller).

The Ugly - the smoking mirrors.
So there are really two points where I became hung up, and found myself fishing for a work around. The first work around: The illusory init method which was discussed in part 2. I am still not exactly sure what the role is with the init and update methods are with the UIStub Class.
There is a definite method to the madness, and maybe the correct answer would’ve been to extend the javafx_dialUI class. Any feedback would be appreciated, commented, and inserted.  The second work around: Sound. The MediaPlayer has an issue, I have poked around to find that
I wasn’t the only person out there asking the questions around getting my WAV file to play.  First and foremost: How ever you create your audio, I would strongly recommend saving it at 1411 kbps as a WAV file.  Next until they fix this, the sound needs to have a length greater than two seconds.  I would recommend if you have a sound or need to create a sound to look to using Audacity. This is an excellent program with a lot of functionality, and still easy enough to use.  Nevertheless, the audio clip was over two seconds long which just running the audio when someone rotated the dial doesn’t make much sense. So here is where I used the functionality of the builtin MediaPlayer object.  The media player has two attributes that I needed to implement, one was the repeatCount, and two was the mute.  Fortunately for me the click wav file I created from my daughter’s teething toy, was a consistent sound.  This allows me to repeat the sound with having to worry where in the sound I was at.  I am assuming that if the sound was not loop-able, or if I needed to chain different sounds together I could just use the MediaPlayer currentTime attribute to select where I needed to be in the audio file.  So what also I did was bind the mute attribute of the player to the sndMuted variable I created, as described above.  Well once I got past these hurdles I was able to enable the basic functionality of the dial.

Enhancing the Functionality
After some pondering I figured on an assignment for this dial, which I will unveil in my next article (cheap teaser I know).  I did have to add a lot of additional public writable attributes:

// currAngle: is exactly that, but both readable and writable.
// To calculate the value on the
// currAngle, use public function currentValue(): Number {
// instead.
public var currAngle: Number;
// Don’t want the Pointer, remove it.
public var hasPointer: Boolean = true;
// Minimum and Maximum are the values that the Dial represents,
// while spinning from the 0th degree, to the 360th degree.
public var minimum: Number = 0.0;
public var maximum: Number = 100.0;
// enable Audio I have already discussed allows you to turn
// the sound off on the dial, and rotationWav
// allows you to change the sound made.
public var enableAudio: Boolean = true;
public var rotationWav = Media { source: “{__DIR__}click2.wav” }
// The incKey, decKey, are used for adding key handlers
// instead of using just the mouse.
// They need to be assigned to a KeyCode Object.
public var incKey: KeyCode = KeyCode.VK_MINUS;
public var decKey: KeyCode = KeyCode.VK_EQUALS;
// keyPressChange and mouseWheelChange, are the
// degree changes that will occur with each
// execution of either of those events to the dial.
public var keyPressChange = 5;
public var mouseWheelChange = 10;

For the Java files, or for the SVG Dial . just click.

< previous Part 2. Turning an SVG drawing into a JavaFX Dial

javafxdial

tekgnu OpenSource, Programming , , , , ,

Part 2. Turning an SVG drawing into a JavaFX Dial

March 3rd, 2009

So last time we left off with an admittedly boring Dial. This time I am going to show you how to be able to programmatically manipulate this
SVG Dial you just created. Why would you want to be able to do that? Well in line with the essence of Object Oriented Programming, it sure would be convenient to just draw one Dial and create as many different variations of it as you need in your application. Or if you want to create themes you can simply just create new instances with different fill colors (or any alterations your interested in).New Default Dial

So all we have to do is follow the instructions from the JavaFX Production Suite
Well not exactly. If you are simply taking your completed image, and just want to plop it, as is, into your program then no worries. What I found is that the sample UIStub class that NetBeans created was, well exactly that, a sample. Thus I am going to deliver two warnings, where you have to be cognizant, or the CustomNode produced will be surprisingly the same as the image itself. It took me quite some time to figure out the “right” way to implement the UIStub, in order to create accessible member variables that could update the image. Believe it or not, it really isn’t as straight forward as I would have thought.

Where to beginsvgconverter
You must have the JavaFX 1.1 SDK downloaded and installed (I would assume you have already accomplished this feat if you’re viewing this article). Next download and install the JavaFX Production Suite, if you haven’t done so already. The JavaFX Production Suite, provides a conversion utility to go from SVG to JavaFX’s fxz, (JavaFX compressed file format). There are also plugins for the Adobe Photoshop, and Illustrator products. If you’ve followed the drawing process from the last article you should have a SVG drawing that can convert, and import into NetBeans. First we need to run the conversion utility on the javafx_dial.svg we created. Located in the .\JavaFX Production Suite\SVG Converter directory you will have the SVG Converter.exe tool (admittedly I haven’t had the chance to try using this utility in Linux, but it looks like the exe may be just a wrapper for a Java application). Execute the program, and enter the location of the javafx_dial.svg file, and then where you want the output javafx_dial.fxz file to be placed. Note: The option checkbox, “Preserve “JFX:” IDs only, is by default checked. Uncheck this box. This option is so that you can have Graphics converter only import the objects that you have given the label of JFX:xxxx, which is great if you have successfully labelled all of the parts of the image that you are going to need. As for the javafx_dial, none of the items are in fact labeled this way, and there will be Paths that you will need to use the default label (this is a cheap chance to point out in NetBeans the ability to dissect the javafx_dial.fxz down to its declarations). Now that we have the javafx_dial.fxz file created you now need to open your IDE.

Working with your IDE
Open your favorite IDE, as for myself, I have since been working with NetBeans, but you can use Eclipse , jEdit, etc.. For reference this article examines
the specifics of NetBeans. With NetBeans open, create a new JavaFX project (I am assuming that the JavaFX plugins have been installed, if not try here). Name the project something meaningful to you, for this article my project name is JavaFXDial, and the Main File is called JavaFXDial.

Working with your JavaFX_Dial dissect_fxz
Using your File explorer, Drag and Drop your new javafx_dial.fxz on to the “Source Packages” area under your project. NetBeans includes a viewer to the fxz file format. If you double click on the javafx_dial.fxz file, you should see it in the “Navigator” panel. This will allow you to move through the XML style format, and as you click you will see the individual Groups, and SVGPaths become highlighted with a red outline. This becomes more useful when you begin looking to manipulate certain aspects of your drawing, that you either forgot to tag, or when the drawing hasn’t been tagged.

Creating the UIStub
Right click on the javafx_dial.fxz file under the package name (under Source packages), and select “Generate UI Stub…”. Select the default UIStub location, and hit OK. We have successfully followed the instructions provided in the UIStub example. This doesn’t get us exactly where we need to be.

public class javafx_testlUI extends UiStub
{
    override public var url = “{__DIR__}javafx_dial.fxz”;
    public var bottom: Node;
    public var layer1: Node;
    public var path2696: Node;
    public var path2702: Node;
    public var path3656: Node;
    public var path4194: Node;
    public var top: Node;

    override protected function update()
    {
        lastNodeId = null;
        try
        {
            bottom=getNode(”bottom”);
            layer1=getNode(”layer1″);
            path2696=getNode(”path2696″);
            path2702=getNode(”path2702″);
            path3656=getNode(”path3656″);
            path4194=getNode(”path4194″);
            top=getNode(”top”);
        }
        catch( e:java.lang.Exception)
        {
            System.err.println(”Update of the attribute
                ’{lastNodeId}’ failed with: {e}”);
            throw e;
        }
    }
}

The problem is this class doesn’t seem to really understand our drawing.

Warning Number 1.
The NetBeans code generator apparently scours the javafx_dial.jfx file for anything with an ID tag and assigns it a name based on the name of the Node. The issue here is everything in the file isn’t a node, there are groups, and SVGPaths. Hence, you can either cast, or if there is an applicable member function, you can just import the Node correctly (I am taking the same stance here by calling it a Node, because most of the objects inherit from the Node Class, that’s why casting a Node to a Group for example isn’t really an issue). So if you look at the API for the FXDContent class, which is used to import from the image, you will see the appropriate get functions for the object you need. To verify the object that you need you can always go back to the “Navigator” Panel, after double clicking on the javafx_dial.fxz, and walk through the Nodes. This is how I corrected the imports (including adding more meaningful names), notice of couse I changed the object’s declaration to match the Node type I was importing:

public class javafx_testlUI extends UiStub
{

    override public var url = “{__DIR__}javafx_dial.fxz”;
    public var top: Group;
    public var bottom: Group;

    public var bottomCircle: SVGPath;
    public var sawToothPattern: SVGPath;
    public var pointer: SVGPath;
    public var topCircle: SVGPath;

    override protected function update()
    {
        lastNodeId = null;
        try
        {
            bottom=
                getGroup(”bottom”);
            bottomCircle=
                getNode(”path2696″) as SVGPath;
            sawToothPattern=
                getNode(”path2702″) as SVGPath;
            pointer=
                getNode(”path3656″) as SVGPath;
            topCircle=
                getNode(”path4194″) as SVGPath;
            top=
                getGroup(”top”);
        }
        catch (e:java.lang.Exception)
        {
            System.err.println(”Update of the attribute
                ’{lastNodeId}’ failed with: {e}”);
            throw e;
        }
    }
}

Notice just for sake of clarity, I did cast the getNode(…) functions to the SVGPath, because there was no associated
getSVGPath function.

Altering the Dial
Well at this point you could in fact add to the Update function below the getNode(..) calls to set the Fill, such as:

pointer.fill = Color.YELLOW;
topCircle.fill = Color.GREEN;
bottomCircle.fill = Color.PINK;
// Actually this can be any Paint object but for sake of
// brevity, I just used Colors.

Well that isn’t too dynamic, or really re-usable. So what I was thinking was well, just turn the assignment into a variable and your good to go.

Hence warning number 2.
You can’t just assign pointer.fill = mySuperFabulousVariable, and expect anything to happen, when you assign it in your main program. There is an order of events with instantiating the UIStub, it really requires you to delete the built-in line:
override public var url = "{__DIR__}javafx_dial.fxz";
Instead you need to create an init function, and as the last, last, very last thing you do in this init is to assign that URL variable to your .fxz file location. The reasoning is that any assignments you perform before that will not take effect. So in my example I want to change four elements from my main program that is going to be instantiating my class: Top of the dial, bottom of the dial, pointer, and the sawtooth pattern. This is how I was able to access, and modify those variables:

init
{
// If the topColor isn’t assigned use Default.
    if (topColor == null)
    {
        topColor = RadialGradient
        {
            centerX: 0.45;
            centerY: 0.5;            
            stops:
            [
                Stop
                {
                    offset: 0.0
                    color: Color.WHITE
                },
                Stop
                {
                    offset: 0.4,
                    color: Color.DIMGRAY
                },
                Stop
                {
                    offset: 0.7
                    color: Color.BLACK
                },
            ]
        };
    }
// If the pointerColor isn’t assigned use Default.
    if (pointerColor == null)
    {
        pointerColor = LinearGradient
        {
            startX: 0.0,
            startY: 0.0,
            endX: 1.0,
            endY: 0.0
            proportional: true
            stops:
            [
                Stop
                {
                    offset: 0.0
                    color: Color.LIGHTGRAY
                },
                Stop
                {
                    offset: 0.4,
                    color: Color.LIGHTGRAY
                },
                Stop
                {
                    offset: 0.45
                    color: Color.WHITE
                },
                Stop
                {
                    offset: 0.5
                    color: Color.LIGHTGRAY
                },
                Stop
                {
                    offset: 0.6
                    color: Color.DIMGRAY
                }
                Stop    
                {
                    offset: 1.0
                    color: Color.BLACK
                },
            ]
        }
    }
// If the bottomColor isn’t assigned use Default.
    if (bottomColor == null)
    {
        bottomColor = RadialGradient
        {
            centerX: 0.45;
            centerY: 0.5;
            radius: 0.5;
            stops:
            [
                Stop    
                {
                    offset: 0.0
                    color: Color.WHITE
                },
                Stop
                {
                    offset: 0.4
                    color: Color.LIGHTGRAY
                },
                Stop
                {
                    offset: 0.7
                    color: Color.LIGHTGRAY
                },
                Stop
                {
                    offset: 0.9
                    color: Color.DIMGRAY
                },
                Stop
                {
                    offset: 1
                    color: Color.BLACK
                }
            ]
        }
    }
// If the sawToothColor isn’t assigned use Default.
    if (sawToothColor == null)
    sawToothColor = Color.DARKGREY;
/* So after a lot of testing I found that you MUST put
*     the URL assignment last, or the default constructors will not
*     work. I don’t really know why that is.

*/
    url = “{__DIR__}javafx_dial.fxz”;
}

Then in the update function I added at the bottom:

/*
* Here is the actual Fill assignments being made. If the value isn’t
* set then the Default from the INIT is used.
*/
pointer.fill = pointerColor;
topCircle.fill = topColor;
bottomCircle.fill = bottomColor;

Coloring the Sawtooth Pattern
Alright so the Sawtooth was more difficult to fill then I had foresight for. When I repeated the ‘U’ shape around the path of the circle, there was an inherent problem born. When you got to fill that ‘U’ Shape you end upd with half of a colored Arc. Well this isn’t very useful at all. It leave the bottom of the ‘U’ shape completely empty, until it hits the circle part of the object. Thankfully, this is JavaFX. So I created a new Circle around this new problem, which is really the size of the Bottom grouping (remember the Bottom group was the Sawtooth and the Circle). Then I created a new Shape, (actually a ShapeSubtract object) which was the remnants by removing both the sawToothPattern and the bottomCircle from this new Circle. Next I filled this new Shape, and added it to the Bottom Group.

var myCircle = Circle
{
    centerX: bottom.boundsInLocal.minX + (bottom.boundsInLocal.width / 2)
    centerY: bottom.boundsInLocal.minY + (bottom.boundsInLocal.height / 2)
// The -5 is used to get rid to the extra halo that gets created by the Circle
    radius: bottom.boundsInLocal.width / 2 - 5
}

var sawTooth = ShapeSubtract
{
    a: myCircle
    b:
    [
        sawToothPattern,
        bottomCircle
    ]
}

/*
* sawToothColor has a default assignment in the INIT, but can be
* overwritten.
*/
sawTooth.fill = sawToothColor;

// Add the new sawTooth instance to the Bottom Group.
insert sawTooth before bottom.content[0];

Running my own Dial
Now that we have fixed this, go back to your main, and instantiate this javafx_dialUI object, you can now overwrite those Paint objects (topColor, pointerColor, bottomColor, and sawToothColor), or keep just the defaults.

Stage
{
    title: “JavaFx Dial Example”
    width: 165
    height: 200

    scene: Scene
    {
        fill: Color.WHITE
        content: Group
        {
            scaleX: 0.5
            scaleY: 0.5
            translateX: -225
            translateY: -125
            content: javafx_dialUI
            {
// Go ahead overwrite the fill of the Object.
/*
*    Or you can take the Defaults.
* topColor: Color.ORANGE
* bottomColor: Color.GREEN
* sawToothColor: Color.YELLOW
* pointerColor: Color.PINK
*/
            }
        }
    }
}

For the NetBeans Project, the Java files, or for the SVG Dial just click.

In my next article, I plan to actually make the Dial, well into a dial that has both animation, and function.

< previous Part 1. Turning an SVG drawing into a JavaFX Dial

Part 3. Breathing life into our JavaFX Dial next >

- - tekgnu - -

tekgnu Programming , , , ,

Part 1. Turning an SVG drawing into a JavaFX Dial

February 4th, 2009

Remember: The idea is to create a dial that can be filled with any color, size, or scheme, so that we can reuse the image how ever we need.  So don’t worry so much about the design feel free to experiment this is a multi - part tutorial in Inkscape, Netbeans, and of course JavaFX.  I am looking for any feedback you can provide (as I stated in my “About” page, I am no expert at any of these, so collaboration is always helpful). If you have no interest in learning Inkscape, or you want to compare, feel free to download the dial here.

Dial control

First, in the pure essence of advocacy you need to download and install Inkscape (http://www.inkscape.org).  You can of course use any graphics program to create your control, as long as you have a way to tag the SVG components  (in SVG/FX parlance, they really are the groups of SVGPaths).  Nevertheless, once you have it installed open it up.  Select File, New, and Default.  You should have a blank canvas to start from. So to get to this, you really have to assemble three distinct components.  The bottom or base of the dial, the top or dial itself, and the pointer.  With Inkscape opened I like to start with the base, because it really is going to be the largest piece of the puzzle.  To create the base use the Circle object, and don’t worry about the dimensions, the precision here is in the cosmetics (because all it is all scalable).  To create the bottom - select the Circle, Ellipse, and Arc tool from the toolbar.  While holding the Ctrl and Alt keys, left click drag a line on the canvas.  The Ctrl and Alt keys are used to constrain the height and width, thus creating a circle.  Now select the whole Ellipse option from the menu bar.
These menu items appear once you have selected the Circle, Ellipses, and Arc tool.

Adding the dimpling
This feature is actually an object replicated along a path.
To create this feature we are going to arbitrarily create a new Circle object.
Once again select the Circle, Ellipse, and Arc tool from the tool bar.  Again we want to constrain the height and width for this arc, so hold the Ctrl and Alt keys, and left click drag a small line.  Next select the Switch to Arc option from the menu bar, and drag the right handle all the way over to the left handle (creating a half circle).  Align the dimple to the right of the circle, just touching it.  This is done by selecting the Arrow icon on the tools menu.  Now all you have to do is a left click drag so that the arc is only slightly touching the top side of the circle.  Holding the shift key select the bottom circle (so that both the dimple and the bottom circle are now selected).  Click on the Object menu item, and choose the Align and Distribute option.  (This will make the pattern smooth, as you will see in a moment).  By default this should create a new menu bar on the right side of the Inkscape window (appropriately titled Align and Distribute  Shift+Ctrl+A), with the short cut key you can use to activate this window).  Choose the Center on Vertical Access, and make sure that the Arc is still just touching the Circle.  (If not just nudge the Arc as needed, by just selecting the Arc and moving it up or down).  One cosmetic change, select just the bottom circle, and from the menu bar, select Object, then Fill and Stroke.  With the new menu box on the right side of the Window labeled Fill and Stroke (Shift+Ctrl+F), select the Stroke Style tab.  Change the Width from 2.00 to “1.00″ px.  This will make the inner circle thinner then the dimpling.  Now we need to create the effect of the dimpling.  If the Circle and Arc are not selected, first click the Arc, and then while holding down the Shift key,
select the bottom circle.  Select Effects from the menu bar, Generate from path submenu, and choose the Pattern along Path option.  In the new Pattern along Path pop up.  Select the following options:
Copies of the pattern:  “Repeated, stretched”
Deformation type: “Snake”
Space between copies: “0.0″
Normal Offset: (Leave this we will need to change this to clean up the pattern).
Tangential Offset: “0.0″
and finally select the Live preview check box.
Now to get the arc to sit on the Circle, instead of the Circle intersecting the arc increase the Normal Offset.  The bottom is now created, once again select both the arc, and circle.  Either click and shift click, or type Ctrl-A.  On the menu bar choose Object, and then Group or type Ctrl-G or right click on the new object and select Group.  Now lets make them more meaningful, with the new Group selected, Right Click, and select Object properties, or choose Object from the menu and select Object properties, or type Shift+Ctrl+o.  For the Id, and label call this object “bottom”, and click the Set button.

Now to create the top
Once again we want a circle, so constrain the height, and width by holding the Ctrl and Alt keys at the same time.
(Don’t forget to select the “Make the shape a whole ellipse …” icon).
The size of this circle should be smaller then the bottom, but size to your own taste.  Choose the Arrow icon to select and move the top circle over the bottom, just to get an idea of the size.  If the circle isn’t the correct size, select the circle, and while holding the Ctrl and Alt keys again, use any of the diagonal corner arrows to increase or decrease the size.  Lets set the stroke on this object.  Choose Object from the menu bar, then Fill and Stroke, or the Shift+Crtl+F keys, or right click and choose Fill and Stroke from the popup menu.  Click once again on the Stroke style, and set the width to “5.00″.  Move the top circle away from the bottom circle.

Creating the pointer
The pointer ultimately will revolve with the top.  To create the pointer the easiest tools to use are the guidelines, and create a square the size of the arrow you are looking to create.  Accessing the guidelines involves left clicking on the ruler measuring bar on top and pulling it down.  This guideline will be useful in creating a box, so pull two down, to have two guidelines, and do the exact same with the vertical ruler measuring bar on the left side.  This will allow you to create visual box, to create pointer in.  Another option that is helpful is to use the grid.

The grid is located under the View item on the menu bar.  (For those that prefer to use accurate measures you can configure the Grid under the File menu item, there is the Document Properties option.  In the Document Properties dialog select the Grid tab).  If you use the grid, you may need to disable the Snap function, located in the Menu bar under View, and then Snap.
Now the pointer can be created by making a simple triangle.
First click in the top left corner of your box, and meet on the bottom middle of the guideline. Next hold the Shift key, and click top right, and drag to meet the first line.  Select the new arrow, and click next to the word Stroke: on the bottom status panel, and the Fill and Stroke panel should open.
Click the Fill tab, and hit the ‘X’ to remove any fill, click the Stroke Paint tab, set it to a solid, and lastly click the Stroke Style, and set the style to something more like “3.0″ px.
Voila, you have an arrow, add it to the top, and you have a dial.
Drag the (just the top not the arrow) over the bottom circle, the align it by holding shift, and selecting the bottom.  Choose Object from the menu bar, and then Align and Distribute (or Ctrl + Shift + A).  Now select Center on Vertical Axis, and Center on Horizontal Axis (hint: Hover over the icons).
Now add the arrow, drag the arrow to the bottom of the top circle, and then hold shift and select the top circle.
For the last piece of the top, group the top and arrow together, by clicking the Object from the menu bar and select Group (or Ctrl+g).
Now right click on this top object, select Object Properties from this submenu, and enter in the name “top” for both Id and Label, and hit Set.
Now to finish, and keep the top on top, click the menu bar item Layer, and then Layer to top (or Shift+Ctrl+Home).Finished Inkscape Design of Dial

Whew, that was longer then I expected.  If you find it too fast, too slow, let me know.  Thanks and keep your eyes open for the next installment.

Part 2. Turning an SVG drawing into a JavaFX Dial next >

- - tekgnu - -

tekgnu General, OpenSource , , ,

Initial Entry in to Programming

January 16th, 2009

So my first order of business is well, to hit the ground running.  I would like to formally begin with a tutorial on JavaFX, and hopefully turn it into some what of a mini-series.   These tutorials are not meant to hit all of the nuances, of any language, but more to provide exposure.  That exposure, god forbid is designed to follow the same course I am using to learn JavaFX.

A little background on my infatuation with JavaFX:

First and foremost, I am not formally a programmer, I am an eternal hobbyist, except for where I can cut productivity, and write a program, script tools, or heck even create icons. For more information on me, see the About page.  I do have a working knowledge of  Java, and have written a few tools for both personal and office interests.   The issue that anyone that has worked in Java will tell you is the fundamental GUI.  If you try to create one from your text editor, you will find yourself having to copy and paste, using an Integrated developement Environment, or your inherently more knowledge-able then I.  Java started off rather clumsily with the Abstract Windowing Toolkit, then the Swing components, and of course a plethora of third party libraries.  Well amongst all of the benefits that are offered by JavaFX (some yet to be implemented as of this writing (i.e. inclusion of the Mobile platform)), the ease of use and pure beauty of both the code and graphics, make this a very welcome addition.

As for a Rich Internet Application, I was secretly praying JavaFX would be a competitor to the overwhelming predominance of Flash (with the Adobe AIR product) and now with Microsoft’s Silverlight, but I keep my expectations cautiously optimistic (One of many comparisons).  It would seem to me that the Applet might be prettier, and easier to create, but it is still an applet.  Now there is WebStart, which I honestly flounder on.  For both of these points I would be more then ecstatic to hear a good debate on how the Java 6 Update 11+ will solve them.

Now that you know where I am coming from, hopefully I will begin writing my first tutorial with in the next week.  It should feature
creating an SVG image in Inkscape and converting it to an fxz file.  From there working with the image directly using the UiStub class.

Thanks for reading !

- - - tekgnu - - -

tekgnu Programming , , , ,