Hatena::ブログ(Diary)

tomoTakaの日記

2013-01-19

I have got the different result on Mac

I just want to share two results I have got on My Mac. I transcribed all of this article. Creating Visual Effects in JavaFX: About This Document | JavaFX 2 Tutorials and Documentation Also the article is written by @skrb using InvalidationListener.
The result that I saw was different from what I had expected. The one is blend mode and another is InvalidationListener.

  • The environment is Mac OS X 10.7.4 with JDK7

f:id:tomoTaka:20130114083520p:image:w240
f:id:tomoTaka:20130114083553p:image:w480

  • Figure 1(Blend Mode)

f:id:tomoTaka:20130116081804p:image:w360

  • Code 1

This code shows using 3 type of blend mode. But Figure 1 shows the same result...
It seems like BlendMode.SRC_ATOP does not work on Mac?
(see Creating Visual Effects in JavaFX: Blending Objects | JavaFX 2 Tutorials and Documentation)

public class BlendSample extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        HBox root = new HBox();
        root.setPadding(new Insets(10));
        root.setSpacing(8);
        // Blending
        Node node1 = getBlendMode(BlendMode.MULTIPLY, Color.BLUE);
        Node node2 = getBlendMode(BlendMode.SRC_ATOP, Color.ORANGE); // This has the different result
        Node node3 = getBlendMode(BlendMode.SRC_OVER, Color.AQUA);
        root.getChildren().addAll(node1, node2, node3);
        stage.setScene(new Scene(root, 500, 300));
        stage.show();
    }

    static Node getBlendMode(BlendMode mode, Color color) {
        Rectangle r = new Rectangle();
        r.setX(590);
        r.setY(50);
        r.setWidth(50);
        r.setHeight(50);
        r.setFill(color);

        Circle c = new Circle();
        c.setFill(Color.rgb(255, 0, 0, 0.5f));
        c.setCenterX(590);
        c.setCenterY(50);
        c.setRadius(25);

        Group g = new Group();
        g.setBlendMode(mode);
        g.getChildren().add(r);
        g.getChildren().add(c);
        return g;
    }
  • Figure 2(InvalidationListener)

InvalidationListener called only once but it should be twice.
f:id:tomoTaka:20130114083620p:image:w480

  • Code 2
package javaapplication22;

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.SimpleIntegerProperty;

public class BindDemo {
    public static void main(String[] args) {
        SimpleIntegerProperty x = new SimpleIntegerProperty(0);
        SimpleIntegerProperty y = new SimpleIntegerProperty();
        y.bind(x);
        y.addListener(new InvalidationListener() {
            @Override
            public void invalidated(Observable o) {
                System.out.println("Invalidate:" + o);
            }
        });
        System.out.println(y.get());  // This code works without invalidationListener?
        x.set(10);
        x.set(20);
        System.out.println(y.get());
    }
}

When I run any JavaFX programs and maximize the screen then quit the application, the error message as follows appears on NetBeans.

  • The Error message

Glass detected outstanding Java exception at -[GlassApplication runLoop:]:src/com/sun/mat/ui/GlassApplication.m:566
Exception in thread "JavaFX Application Thread" java.util.concurrent.RejectedExecutionException: Task com.sun.prism.render.RenderJob@343d0d2b rejected from com.sun.javafx.tk.quantum.QuantumRenderer@142b9cd8[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 53]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2013)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:816)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1337)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:110)
at com.sun.javafx.tk.quantum.QuantumRenderer.disposePresentable(QuantumRenderer.java:176)
at com.sun.javafx.tk.quantum.WindowStage.setScene(WindowStage.java:186)
at javafx.stage.Window$10.invalidated(Window.java:751)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:127)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:161)
at javafx.stage.Window.setShowing(Window.java:782)
at javafx.stage.Window.hide(Window.java:807)
at com.sun.javafx.stage.WindowCloseRequestHandler.dispatchBubblingEvent(WindowCloseRequestHandler.java:45)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at com.sun.javafx.stage.WindowPeerListener.closing(WindowPeerListener.java:82)
at com.sun.javafx.tk.quantum.GlassStage.requestClosingAllWindows(GlassStage.java:203)
at com.sun.javafx.tk.quantum.QuantumToolkit$11.handleQuitAction(QuantumToolkit.java:347)
at com.sun.glass.ui.mac.MacApplication$4.action(MacApplication.java:104)

I would appreciate any advice since I am very beginner of JavaFX.
keep coding....

tomoTakatomoTaka 2013/01/20 08:12 I just put the code here(https://github.com/tomoTaka01/EffectSample)

MartinMartin 2013/01/21 01:01 In the second example, you are running your UI code outside of JavaFX application thread. Your class must extend Application. Then override start(). If you want to run another thread, then from the new thread always use Platform.runLater(); to update the UI code which MUST be accessed from JavaFX thread.

regards
Martin

MartinMartin 2013/01/21 01:20 With the first example my only guess is that the blending is applied to the scene and not the circle...

"A blending mode defines the manner in which the inputs of a Blend effect are composited together or how a Node is blended into the background of a scene."

tomoTakatomoTaka 2013/01/21 08:25 Dear Mr.Martin
Thank you for your comments.
The first example the blending is applied to the group. And I do not think the scene has setEffect method...
The second one, I amended the code as you suggested.
But I still have the same result.
The code(BindDemo.java) is here
(https://github.com/tomoTaka01/EffectSample/tree/master/src/effectsample)
Thank you again!

MartinMartin 2013/01/21 14:15 Yes, the first one might be a bug...

Please check http://javafx-jira.kenai.com/ and eventually file it as a bug.

And the second one:

You get only one invalidation, because the Observable is invalidated only once and that is how it should work!

Here the observable is invalidated:
x.set(10);

But here it is already invalid! So it will not fire another event.
x.set(20);

But if you do validate the value before invalidating again, for example by getting the value from it, you get 2 separate events ex:

Try getting the value of "y" inside the event listener:

public void invalidated(Observable o) {
System.out.println("Invalidate:" + o);
if (o instanceof IntegerProperty) {
IntegerProperty yFromObservable = (IntegerProperty) o;
System.out.println("Changing to: " + yFromObservable.get());
}
}

Now it should say:
0
Invalidate:IntegerProperty [bound, invalid]
Changing to: 10
Invalidate:IntegerProperty [bound, invalid]
Changing to: 20
20


Hope this helps. And I am not from oracle in case you wonder :) But I love JavaFX and this is fun.
You might want to check
stackoverflow.com - helped me alot.

regards
Martin

tomoTakatomoTaka 2013/01/21 22:33 Dear Mr.Martin

Thank you so much for your kind helps.
I put this result (http://javafx-jira.kenai.com/browse/RT-27815)
When I read your comment, I was very happy.

Best wishes

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/tomoTaka/20130119/1358580757