vendredi 25 juin 2010
mercredi 16 juin 2010
Slimshady:D5- JavaFX
I don’t know what is Slimshady :D5- JavaFX in comparison with the actual JavaFX, but I think it should be a great technology ! :)
See yourself http://blogs.sun.com/ant/
And if you have some information about Slimshady:D5, let me know ;)
[Update: October 6, 2010]
I don't know why (may be because of that) , but the Anthony Rogers's blog is down...
However, you could always see some videos of Slimshady on YouTube you could always see some videos of Slimshady on YouTube
See yourself http://blogs.sun.com/ant/
And if you have some information about Slimshady:D5, let me know ;)
[Update: October 6, 2010]
I don't know why (may be because of that) , but the Anthony Rogers's blog is down...
However, you could always see some videos of Slimshady on YouTube you could always see some videos of Slimshady on YouTube
Libellés :
javaFX,
Slimshady:D5,
Slimshady:D5- JavaFX
mercredi 26 mai 2010
Distortion effect
After the simple scrolltexts and scrolltexts with a sinusoidal effect, here is just another old bitmap effect used in the demos written for home computers in the 1980s.
For standalone mode
For standalone mode
If you want to try with a bigger image, you can use the glassfish.jpg image instead of the fc-barcelone-logo.jpg and, for a better effect with a bigger image, use this lines
var factor = (6 * Math.PI) / imageHeight; var v = (Math.sin(j * factor) * 20) + 20;instead of this lines
var factor = (2 * Math.PI) / imageHeight; var v = (Math.sin(j * factor) * 10) + 20;
Distortion.fx |
package distortion; import javafx.scene.image.Image; import javafx.geometry.Rectangle2D; import javafx.scene.image.ImageView; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.util.Math; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.runtime.ConditionalFeature; import javafx.runtime.Platform; import javafx.scene.shape.Rectangle; import javafx.scene.paint.Color; /** * @author paddy */ println("Effect enabled: {Platform.isSupported(ConditionalFeature.EFFECT)}"); println("Input Method enabled: {Platform.isSupported(ConditionalFeature.INPUT_METHOD)}"); println("Scene 3D enabled: {Platform.isSupported(ConditionalFeature.SCENE3D)}"); println("Shape Clip enabled: {Platform.isSupported(ConditionalFeature.SHAPE_CLIP)}"); var img = Image { //url: "{__DIR__}images/glassfish.jpg" url: "{__DIR__}images/fc-barcelone-logo.jpg" } def imageWidth = bind img.width as Integer; def imageHeight = bind img.height as Integer; def lineWidth = imageWidth; def lineHeight = 1; var distortionMap: Float[]; var index = 0; for (j in [0..<imageHeight * 2]) { var factor = (2 * Math.PI) / imageHeight; var v = (Math.sin(j * factor) * 10) + 20; //var factor = (6 * Math.PI) / imageHeight; //var v = (Math.sin(j * factor) * 20) + 20; insert v into distortionMap; } def lineViewports = for (row in [0..imageHeight]) { Rectangle2D { minX: 0, minY: row, width: lineWidth, height: lineHeight } } var distortionImg = bind for (row in [0..imageHeight]) { ImageView { x: bind distortionMap[row + index] y: row viewport: bind lineViewports[row] image: img } } var t = Timeline { repeatCount: Timeline.INDEFINITE keyFrames: KeyFrame { time: 8ms canSkip: true action: function (): Void { index = index + 1; if (index > imageHeight) { index = 0; } } } } t.play(); Stage { title: "Application title" scene: Scene { width: imageWidth +40 height: imageHeight + 1 content: [ Rectangle { x: 0, y: 0 width: imageWidth +40 , height: imageHeight + 1 fill: Color.BLACK //fill: Color.GHOSTWHITE } distortionImg ] } }
Note : The scrolltexts and the scrolltexts with sinusoidal effect work without migration on JavaFX 1.3 with AWT/Java2D/Swing toolkit.
On prism toolkit the animation is very fluid but you have to use a jpeg image instead of png for the font because the png is not supported in this early version of prism
On prism toolkit the animation is very fluid but you have to use a jpeg image instead of png for the font because the png is not supported in this early version of prism
samedi 8 mai 2010
JavaFX custom component in JavaFX 1.3
In JavaFX 1.2, Control extended CustomNode then we could override the create function to customize an existing component.
With JavaFX 1.3, Control now extends Parent directly then we do not have any more the create function and my custom component doesn’t compile any more … (because I used the create function to customize my components)
Then, to customize an existing component in JavaFX 1.3, I tried another way
I use the initBlock to create the nodes that I want to add to the existing component to customize it
and then I add these nodes to the children sequence of the existing component.
With JavaFX 1.3, Control now extends Parent directly then we do not have any more the create function and my custom component doesn’t compile any more … (because I used the create function to customize my components)
Then, to customize an existing component in JavaFX 1.3, I tried another way
I use the initBlock to create the nodes that I want to add to the existing component to customize it
and then I add these nodes to the children sequence of the existing component.
... init { var g = Group { content: [ Group { ... content: [ Circle { ... } Rectangle { .... } ... ] ... ] } insert g into children; } ...
Now, I have a problem with the css, I want to have a default css for my SearchTextBox which is loaded by default by my component (not in the Scene by the developer) and which can be overridden by the developer.
If you have a solution, please let me know!
This example works on: Windows (Seven), Linux (Ubuntu 10.04) and Mac OS X (10.6.3) with the Default toolkit and the Prism toolkit (JVM argument: -Xtoolkit prism) but there is one bug when you run it as an applet on Mac OS X.
The button have a wrong size, the text is too long….
The button have a wrong size, the text is too long….
[update August 8, 2010]this issue is fixed in JavaFX 1.3.1
SearchTextBox.fx |
package customcomponent; import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; import javafx.scene.input.MouseEvent; import javafx.scene.control.TextBox; import javafx.scene.input.KeyEvent; /** * @author Patrick */ public class SearchTextBox extends TextBox { public var onResetSearch: function(): Void; public var onSearch: function(s: String): Void; override var style = "-fx-padding: 0 16 0 0; "; //override var styleClass = "searchTextBox text-box"; //override var styleClass = "searchTextBox"; override var onKeyTyped = function(event:KeyEvent){ if (this.rawText!=""){ onSearch(this.rawText); }else{ onResetSearch(); } } init { var g = Group { content: [ Group { var crossWidth = bind this.layoutBounds.height * 0.45; var crossHeight = bind this.layoutBounds.height * 0.05; visible: bind this.rawText.length() > 0 layoutX: bind this.layoutBounds.width - (this.layoutBounds.height / 2.0) layoutY: bind this.layoutBounds.height / 2.0 content: [ Circle { fill: Color.GRAY radius: bind this.layoutBounds.height * 0.325 // 65% of the texbox height and div 2 for the radius } Rectangle { width: bind crossWidth height: bind crossHeight translateX: bind 0 - crossWidth / 2.0 translateY: bind 0 - crossHeight / 2.0 fill: Color.WHITE rotate: 45 } Rectangle { width: bind crossWidth height: bind crossHeight translateX: bind 0 - crossWidth / 2.0 translateY: bind 0 - crossHeight / 2.0 fill: Color.WHITE rotate: -45 } ] onMouseClicked: function (event: MouseEvent) { this.commit(); this.text = ""; onResetSearch(); } } ] } insert g into children; } }
Main.fx |
package searchtextbox; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.text.Text; import javafx.scene.text.Font; import javafx.scene.control.Button; import javafx.scene.control.RadioButton; import javafx.scene.control.ToggleGroup; import customcomponent.SearchTextBox; /** * @author Patrick */ class ExtRadioButton extends RadioButton { public var action:function(); override public var selected on replace { if (selected) { action(); } } } def macStyleSheet="{__DIR__}resources/mac.css"; def defaultStyleSheet = "/customcomponent/stbcaspian.css"; var stylesheets:String = macStyleSheet; Stage { title: "Application title" width: 250 height: 200 var cssToggleGroup = ToggleGroup {}; scene: Scene { stylesheets : bind stylesheets content: [ Text { font : Font { size : 16 } x: 10 y: 30 content: "Search " } SearchTextBox { styleClass : "searchTextBox" translateX :10 translateY :40 onResetSearch:function(){ println("reset !"); } onSearch:function(s: String){ println("Search of : {s}"); } } Button { text: "just a button to change focus" translateX :10 translateY :80 action: function() { println("Hello !") } } ExtRadioButton { text: "use the default CSS" translateX :10 translateY :110 toggleGroup: cssToggleGroup action: function() { stylesheets = defaultStyleSheet; } } ExtRadioButton { text: "use the mac CSS" translateX :10 translateY :130 toggleGroup: cssToggleGroup selected: true action: function() { stylesheets = macStyleSheet; } } ] } }
Libellés :
Custom component,
JavaFX 1.3,
Search TextBox
mardi 27 avril 2010
Duke Anim in JavaFX 1.3
In JavaFX 1.3 the evaluation of the KeyValues in the Timeline changed. Now, the KeyValues are evaluated once before the Timeline starts (see "Animation: Changed semantics of
KeyValue
evaluation"
in Java FX 1.3 Migration Guide) and thus my Duke Anim doesn’t work in Java FX 1.3 :(.To correct it, the function Timeline.evaluateKeyValues() has been added. This function has to be used for re-evaluates all the keyValues when it is called.
Now, let us correct Duke Anim :)
To correct Duke Anim, I have made only 2 changes:
· I call the function Timeline.evaluateKeyValues() at the end of the action function of KeyFrame at 1s.
anim.evaluateKeyValues();
anim.evaluateKeyValues();
· And I declare the variable anim with his type to be able to call the function Timeline.evaluateKeyValues() in the action function of the KeyFrame.
public var anim:Timeline = Timeline { …
public var anim:Timeline = Timeline { …
This Duke Anim's version works on : Windows (Seven), Linux (Ubuntu 9.10) and Mac OS X (10.6.3) with the Default toolkit and the Prism toolkit (JVM argument: -Xtoolkit prism)
Main.fx |
package dukeanim; import java.util.Random; import javafx.animation.Interpolator; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.Scene; import javafx.scene.transform.Translate; import javafx.runtime.ConditionalFeature; import javafx.runtime.Platform; import javafx.stage.Stage; class DukeAnimModel { public var imageURL = "{__DIR__}images/duke.png"; public var x = 0; public var y = 0; var xTarget = 0; var yTarget = 0; var xTemp = 0; var yTemp = 0; public var anim:Timeline = Timeline { autoReverse: false keyFrames: [ KeyFrame { time: 0s values: [x => xTemp, y => yTemp] }, KeyFrame { time: 1s values: [x => xTarget tween Interpolator.SPLINE(0,.5,.5,1),y => yTarget tween Interpolator.SPLINE(0,.5,.5,1)] action: function(): Void{ var generator = new Random(); xTarget = (generator.nextFloat() * 240 + 1) as Integer; yTarget = (generator.nextFloat() * 320 + 1) as Integer; xTemp=x; yTemp=y; anim.evaluateKeyValues(); } }, ] repeatCount: Timeline.INDEFINITE }; } println("Effect enabled: {Platform.isSupported(ConditionalFeature.EFFECT)}"); println("Input Method enabled: {Platform.isSupported(ConditionalFeature.INPUT_METHOD)}"); println("Scene 3D enabled: {Platform.isSupported(ConditionalFeature.SCENE3D)}"); println("Shape Clip enabled: {Platform.isSupported(ConditionalFeature.SHAPE_CLIP)}"); var dukeAnimModel = DukeAnimModel {} dukeAnimModel.anim.play(); Stage { title: "Application title" width: 240 height: 320 scene: Scene { content: ImageView { transforms: Translate { x: bind dukeAnimModel.x y: bind dukeAnimModel.y } image: Image { url: dukeAnimModel.imageURL } } } onClose: function(){ println("exit"); } }
Libellés :
Duke Anim,
evaluateKeyValues,
JavaFX 1.3,
timeline
jeudi 22 avril 2010
JavaFX 1.3 is there!!!!
JavaFX 1.3 is there!!!!
I haven’t tested it yet, but visibly we have some 3D functions, new UI components, CSS, the performance and user experience are improved, etc…
Some interesting links :
jeudi 15 avril 2010
EJB 3.1 Asynchronous Session Beans
Before EJB 3.1, if you want to execute an asynchronous processing you had to use JMS and a MDB, not so easy and rather heavy in most cases.
Now with EJB 3.1, you can use a simple session EJB with the @Asynchronous annotation on the method which must be called asynchronously.
Now with EJB 3.1, you can use a simple session EJB with the @Asynchronous annotation on the method which must be called asynchronously.
@Stateless @Remote(HelloEjbAsynchronousRemote.class) public class HelloEjbAsynchronous implements HelloEjbAsynchronousRemote { @Asynchronous @Override public Future<String> ejbAsynchronousSayHello(String name){
If your method has a return value, your method has to return an AsyncResult object which is an implementation of Future.
return new AsyncResult<String>("Hello "+name);For the client, you just have to call the remote ejbAsynchronousSayHello by using the new portable global JNDI names.
The EJB container returns the control to the client immediately, in my case with a Future object in return, and then executes the method.
HelloEjbAsynchronousRemote ha = (HelloEjbAsynchronousRemote)ic.lookup("java:global/EjbAsynchronous/HelloEjbAsynchronous"); Future future = ha.ejbAsynchronousSayHello("Patrick");The client can retrieve the result value with Future.get() and can get the state of the processing with Future.isDone().
String ret = (String)future.get();
Full source code of the EJB - HelloEjbAsynchronous.java |
package fr.paddy.ejb31; import java.util.Date; import java.util.concurrent.Future; import javax.ejb.AsyncResult; import javax.ejb.Asynchronous; import javax.ejb.Remote; import javax.ejb.Stateless; @Stateless @Remote(HelloEjbAsynchronousRemote.class) public class HelloEjbAsynchronous implements HelloEjbAsynchronousRemote { @Asynchronous @Override public Future<String> ejbAsynchronousSayHello(String name){ System.out.println(new Date().toString()+" - Begin - HelloEjbAsynchronos->ejbAsynchronousSayHello "+name); try{ Thread.sleep(5*1000); }catch (Exception e){ e.printStackTrace(); } System.out.println(new Date().toString()+" - End - HelloEjbAsynchronos->ejbAsynchronousSayHello "+name); return new AsyncResult<String>("Hello "+name); } }The ejbAsynchronousSayHello method, which is declared asynchronous, just wait 5 seconds to simulate a long processing and return the String "Hello "+name, the variable name being passed as parameter.
Full source code of the remote interface - HelloEjbAsynchronousRemote.java |
package fr.paddy.ejb31; import java.util.concurrent.Future; public interface HelloEjbAsynchronousRemote { public Future<String> ejbAsynchronousSayHello(String name); }
Full source code of the EJB Client - ClientMain.java |
import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import javax.naming.InitialContext; import javax.naming.NamingException; import fr.paddy.ejb31.HelloEjbAsynchronousRemote; import java.util.Date; public class ClientMain { public static void main(String[] args) { Properties props = new Properties(); props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory"); props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming"); props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl"); props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost"); props.setProperty("org.omg.CORBA.ORBInitialPort", "3700"); try{ InitialContext ic = new InitialContext(props); String ret=""; HelloEjbAsynchronousRemote ha = (HelloEjbAsynchronousRemote)ic.lookup("java:global/EjbAsynchronous/HelloEjbAsynchronous"); Future future = ha.ejbAsynchronousSayHello("Patrick"); while (!future.isDone()){ Thread.sleep(1000); System.out.println(new Date().toString()+" - I do other things ..."); } ret = (String)future.get(); System.out.println(new Date().toString()+" - ret : "+ret); }catch (NamingException ne){ ne.printStackTrace(); }catch (InterruptedException ie){ ie.printStackTrace(); }catch (ExecutionException ee){ ee.printStackTrace(); } } }
Because of this issue, you must use GlassFish V3.0.1 promoted build 12 to test this example.
Or used this workaround
Or used this workaround
while (!future.isDone()){ Thread.sleep(1000); System.out.println(new Date().toString()+" - I do other things ..."); // System.out.println("futur.isDone"+future.isDone()); // just a hack, because at the moment future.isDone doesn't work ! try{ Object o = future.get(10,TimeUnit.MILLISECONDS); }catch (TimeoutException te){ // te.printStackTrace(); } // end of the hack // System.out.println("futur.isDone"+future.isDone()); }
Libellés :
Asynchronous,
Asynchronous Session Beans,
EJB 3.1
Inscription à :
Articles (Atom)