Archive

Posts Tagged ‘Inkscape’

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 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 , , , ,