Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.effect;
027
028import javafx.beans.property.BooleanProperty;
029import javafx.beans.property.DoubleProperty;
030import javafx.beans.property.DoublePropertyBase;
031import javafx.beans.property.ObjectProperty;
032import javafx.beans.property.ObjectPropertyBase;
033import javafx.beans.property.SimpleBooleanProperty;
034import javafx.scene.paint.Color;
035
036import com.sun.javafx.Utils;
037import com.sun.javafx.tk.Toolkit;
038
039/**
040 * The abstract base class for all light implementations.
041 */
042public abstract class Light {
043
044    /**
045     * Creates a new Light.
046     */
047    protected Light() {
048        impl_markDirty();
049    }
050
051    abstract com.sun.scenario.effect.light.Light impl_createImpl();
052    private com.sun.scenario.effect.light.Light peer;
053
054    com.sun.scenario.effect.light.Light impl_getImpl() {
055        if (peer == null) {
056            peer = impl_createImpl();
057        }
058        return peer;
059    }
060    /**
061     * The color of the light source.
062     * <pre>
063     *       Min: n/a
064     *       Max: n/a
065     *   Default: Color.WHITE
066     *  Identity: n/a
067     * </pre>
068     * @defaultValue WHITE
069     */
070    private ObjectProperty<Color> color;
071
072    public final void setColor(Color value) {
073        colorProperty().set(value);
074    }
075
076    public final Color getColor() {
077        return color == null ? Color.WHITE : color.get();
078    }
079
080    public final ObjectProperty<Color> colorProperty() {
081        if (color == null) {
082            color = new ObjectPropertyBase<Color>(Color.WHITE) {
083
084                @Override
085                public void invalidated() {
086                    impl_markDirty();
087                }
088
089                @Override
090                public Object getBean() {
091                    return Light.this;
092                }
093
094                @Override
095                public String getName() {
096                    return "color";
097                }
098            };
099        }
100        return color;
101    }
102
103    void impl_sync() {
104        if (impl_isEffectDirty()) {
105            impl_update();
106            impl_clearDirty();
107        }
108    }
109
110   private Color getColorInternal() {
111        Color c = getColor();
112        return c == null ? Color.WHITE : c;
113    }
114
115    void impl_update() {
116        impl_getImpl().setColor(Toolkit.getToolkit().toColor4f(getColorInternal()));
117    }
118
119    private BooleanProperty effectDirty;
120
121    private void setEffectDirty(boolean value) {
122        effectDirtyProperty().set(value);
123    }
124
125    final BooleanProperty effectDirtyProperty() {
126        if (effectDirty == null) {
127            effectDirty = new SimpleBooleanProperty(this, "effectDirty");
128        }
129        return effectDirty;
130    }
131
132    boolean impl_isEffectDirty() {
133        return effectDirty == null ? false : effectDirty.get();
134    }
135
136    final void impl_markDirty() {
137        setEffectDirty(true);
138    }
139
140    final void impl_clearDirty() {
141        setEffectDirty(false);
142    }
143
144    /**
145     * Represents a distant light source.
146     *
147     * <p>
148     * Example:
149     * <pre><code>
150     * Light.Distant light = new Light.Distant();
151     * light.setAzimuth(45.0);
152     * light.setElevation(30.0);
153     *
154     * Lighting lighting = new Lighting();
155     * lighting.setLight(light);
156     * lighting.setSurfaceScale(5.0);
157     *
158     * Text text = new Text();
159     * text.setText("Distant");
160     * text.setFill(Color.STEELBLUE);
161     * text.setFont(Font.font("null", FontWeight.BOLD, 80));
162     * text.setX(10.0f);
163     * text.setY(10.0f);
164     * text.setTextOrigin(VPos.TOP);
165     * text.setEffect(lighting);
166     *
167     * Rectangle rect = new Rectangle(300,150);
168     * rect.setFill(Color.ALICEBLUE);
169     * rect.setEffect(lighting);
170     * </pre></code>
171     *
172     * <p> The code above produces the following: </p> 
173     * <p> <img src="doc-files/lightdistant.png"/> </p>
174     */
175    public static class Distant extends Light {
176       /**
177        * Creates a new instance of Distant light with default parameters.
178        */
179        public Distant() {}
180
181       /**
182        * Creates a new instance of Distant light with the specified azimuth,
183        * elevation, and color.
184        * @param azimuth the azimuth of the light
185        * @param elevation the elevation of the light
186        * @param color the color of the light
187        */
188        public Distant(double azimuth, double elevation, Color color) {
189           setAzimuth(azimuth);
190           setElevation(elevation);
191           setColor(color);
192        }
193    
194        @Override
195        com.sun.scenario.effect.light.DistantLight impl_createImpl() {
196            return new com.sun.scenario.effect.light.DistantLight();
197        }
198        /**
199         * The azimuth of the light.  The azimuth is the direction angle
200         * for the light source on the XY plane, in degrees.
201         * <pre>
202         *       Min:  n/a
203         *       Max:  n/a
204         *   Default: 45.0
205         *  Identity:  n/a
206         * </pre>
207         * @defaultValue 45.0
208         */
209        private DoubleProperty azimuth;
210
211        public final void setAzimuth(double value) {
212            azimuthProperty().set(value);
213        }
214
215        public final double getAzimuth() {
216            return azimuth == null ? 45 : azimuth.get();
217        }
218
219        public final DoubleProperty azimuthProperty() {
220            if (azimuth == null) {
221                azimuth = new DoublePropertyBase(45) {
222
223                    @Override
224                    public void invalidated() {
225                        impl_markDirty();
226                    }
227
228                    @Override
229                    public Object getBean() {
230                        return Distant.this;
231                    }
232
233                    @Override
234                    public String getName() {
235                        return "azimuth";
236                    }
237                };
238            }
239            return azimuth;
240        }
241        /**
242         * The elevation of the light.  The elevation is the
243         * direction angle for the light source on the YZ plane, in degrees.
244         * <pre>
245         *       Min:  n/a
246         *       Max:  n/a
247         *   Default: 45.0
248         *  Identity:  n/a
249         * </pre>
250         * @defaultValue 45.0
251         */
252        private DoubleProperty elevation;
253
254        public final void setElevation(double value) {
255            elevationProperty().set(value);
256        }
257
258        public final double getElevation() {
259            return elevation == null ? 45 : elevation.get();
260        }
261
262        public final DoubleProperty elevationProperty() {
263            if (elevation == null) {
264                elevation = new DoublePropertyBase(45) {
265
266                    @Override
267                    public void invalidated() {
268                        impl_markDirty();
269                    }
270
271                    @Override
272                    public Object getBean() {
273                        return Distant.this;
274                    }
275
276                    @Override
277                    public String getName() {
278                        return "elevation";
279                    }
280                };
281            }
282            return elevation;
283        }
284
285        @Override
286        void impl_update() {
287            super.impl_update();
288            com.sun.scenario.effect.light.DistantLight peer =
289                    (com.sun.scenario.effect.light.DistantLight) impl_getImpl();
290            peer.setAzimuth((float) getAzimuth());
291            peer.setElevation((float) getElevation());
292        }
293    }
294
295    /**
296     * Represents a light source at a given position in 3D space.
297     *
298     * <p>
299     * Example:
300     * <pre><code>
301     * Light.Point light = new Light.Point();
302     * light.setX(100);
303     * light.setY(100);
304     * light.setZ(50);
305     *
306     * Lighting lighting = new Lighting();
307     * lighting.setLight(light);
308     * lighting.setSurfaceScale(5.0);
309     *
310     * Text text = new Text();
311     * text.setText("Point");
312     * text.setFill(Color.STEELBLUE);
313     * text.setFont(Font.font(null, FontWeight.BOLD, 80));
314     * text.setX(10.0);
315     * text.setY(10.0);
316     * text.setTextOrigin(VPos.TOP);
317     *
318     * Rectangle rect = new Rectangle(250, 150);
319     * rect.setFill(Color.ALICEBLUE);
320     * rect.setEffect(lighting);
321     * text.setEffect(lighting);
322     * </pre></code>
323     *
324     * <p> The code above produces the following: </p> 
325     * <p> <img src="doc-files/lightpoint.png"/> </p>
326     */
327    public static class Point extends Light {
328       /**
329        * Creates a new instance of Point light with default parameters.
330        */
331        public Point() {}
332
333       /**
334        * Creates a new instance of Point light with the specified x, y, x, and
335        * color.
336        * @param x the x coordinate of the light position
337        * @param y the y coordinate of the light position
338        * @param z the z coordinate of the light position
339        * @param color the color of the light
340        */
341        public Point(double x, double y, double z, Color color) {
342           setX(x);
343           setY(y);
344           setZ(z);
345           setColor(color);
346        }
347
348        /**
349         * @treatAsPrivate implementation detail
350         * @deprecated This is an internal API that is not intended for use and will be removed in the next version
351         */
352        @Deprecated
353        @Override
354        com.sun.scenario.effect.light.PointLight impl_createImpl() {
355            return new com.sun.scenario.effect.light.PointLight();
356        }
357        /**
358         * The x coordinate of the light position.
359         * <pre>
360         *       Min: n/a
361         *       Max: n/a
362         *   Default: 0.0
363         *  Identity: n/a
364         * </pre>
365         * @defaultValue 0.0
366         */
367        private DoubleProperty x;
368
369        public final void setX(double value) {
370            xProperty().set(value);
371        }
372
373        public final double getX() {
374            return x == null ? 0 : x.get();
375        }
376
377        public final DoubleProperty xProperty() {
378            if (x == null) {
379                x = new DoublePropertyBase() {
380
381                    @Override
382                    public void invalidated() {
383                        impl_markDirty();
384                    }
385
386                    @Override
387                    public Object getBean() {
388                        return Point.this;
389                    }
390
391                    @Override
392                    public String getName() {
393                        return "x";
394                    }
395                };
396            }
397            return x;
398        }
399        /**
400         * The y coordinate of the light position.
401         * <pre>
402         *       Min: n/a
403         *       Max: n/a
404         *   Default: 0.0
405         *  Identity: n/a
406         * </pre>
407         * @defaultValue 0.0
408         */
409        private DoubleProperty y;
410
411        public final void setY(double value) {
412            yProperty().set(value);
413        }
414
415        public final double getY() {
416            return y == null ? 0 : y.get();
417        }
418
419        public final DoubleProperty yProperty() {
420            if (y == null) {
421                y = new DoublePropertyBase() {
422
423                    @Override
424                    public void invalidated() {
425                        impl_markDirty();
426                    }
427
428                    @Override
429                    public Object getBean() {
430                        return Point.this;
431                    }
432
433                    @Override
434                    public String getName() {
435                        return "y";
436                    }
437                };
438            }
439            return y;
440        }
441        /**
442         * The z coordinate of the light position.
443         * <pre>
444         *       Min: n/a
445         *       Max: n/a
446         *   Default: 0.0
447         *  Identity: n/a
448         * </pre>
449         * @defaultValue 0.0
450         */
451        private DoubleProperty z;
452
453        public final void setZ(double value) {
454            zProperty().set(value);
455        }
456
457        public final double getZ() {
458            return z == null ? 0 : z.get();
459        }
460
461        public final DoubleProperty zProperty() {
462            if (z == null) {
463                z = new DoublePropertyBase() {
464
465                    @Override
466                    public void invalidated() {
467                        impl_markDirty();
468                    }
469
470                    @Override
471                    public Object getBean() {
472                        return Point.this;
473                    }
474
475                    @Override
476                    public String getName() {
477                        return "z";
478                    }
479                };
480            }
481            return z;
482        }
483
484        @Override
485        void impl_update() {
486            super.impl_update();
487            com.sun.scenario.effect.light.PointLight peer =
488                    (com.sun.scenario.effect.light.PointLight) impl_getImpl();
489            peer.setX((float) getX());
490            peer.setY((float) getY());
491            peer.setZ((float) getZ());
492        }
493    }
494
495    /**
496     * Represents a spot light source at a given position in 3D space, with
497     * configurable direction and focus.
498     *
499     * <p>
500     * Example:
501     * <pre><code>        
502     * Light.Spot light = new Light.Spot();
503     * light.setX(150);
504     * light.setY(100);
505     * light.setZ(80);
506     * light.setPointsAtX(0);
507     * light.setPointsAtY(0);
508     * light.setPointsAtZ(-50);
509     * light.setSpecularExponent(2);
510     *
511     * Lighting lighting = new Lighting();
512     * lighting.setLight(light);
513     * lighting.setSurfaceScale(5.0);
514     *
515     * Text text = new Text();
516     * text.setText("Spot");
517     * text.setFill(Color.STEELBLUE);
518     * text.setFont(Font.font(null, FontWeight.BOLD, 80));
519     * text.setX(10.0);
520     * text.setY(10.0);
521     * text.setTextOrigin(VPos.TOP);
522     * text.setEffect(lighting);
523     *
524     * Rectangle rect = new Rectangle(200, 150);
525     * rect.setFill(Color.ALICEBLUE);
526     * rect.setEffect(lighting);
527     * </pre></code>
528     *
529     * <p> The code above produces the following: </p> 
530     * <p> <img src="doc-files/lightspot.png"/> </p>
531     *
532     */
533    public static class Spot extends Light.Point {
534       /**
535        * Creates a new instance of Spot light with default parameters.
536        */
537        public Spot() {}
538
539       /**
540        * Creates a new instance of Spot light with the specified x, y, z,
541        * specularExponent, and color.
542        * @param x the x coordinate of the light position
543        * @param y the y coordinate of the light position
544        * @param z the z coordinate of the light position
545        * @param specularExponent the specular exponent, which controls the 
546        * focus of the light source
547        * @param color the color of the light
548        */
549        public Spot(double x, double y, double z, double specularExponent, Color color) {
550           setX(x);
551           setY(y);
552           setZ(z);
553           setSpecularExponent(specularExponent);
554           setColor(color);
555        }
556
557        /**
558         * @treatAsPrivate implementation detail
559         * @deprecated This is an internal API that is not intended for use and will be removed in the next version
560         */
561        @Deprecated
562        @Override
563        com.sun.scenario.effect.light.SpotLight impl_createImpl() {
564            return new com.sun.scenario.effect.light.SpotLight();
565        }
566        /**
567         * The x coordinate of the direction vector for this light.
568         * <pre>
569         *       Min: n/a
570         *       Max: n/a
571         *   Default: 0.0
572         *  Identity: n/a
573         * </pre>
574         * @defaultValue 0.0
575         */
576        private DoubleProperty pointsAtX;
577
578        public final void setPointsAtX(double value) {
579            pointsAtXProperty().set(value);
580        }
581
582        public final double getPointsAtX() {
583            return pointsAtX == null ? 0 : pointsAtX.get();
584        }
585
586        public final DoubleProperty pointsAtXProperty() {
587            if (pointsAtX == null) {
588                pointsAtX = new DoublePropertyBase() {
589
590                    @Override
591                    public void invalidated() {
592                        impl_markDirty();
593                    }
594
595                    @Override
596                    public Object getBean() {
597                        return Spot.this;
598                    }
599
600                    @Override
601                    public String getName() {
602                        return "pointsAtX";
603                    }
604                };
605            }
606            return pointsAtX;
607        }
608        /**
609         * The y coordinate of the direction vector for this light.
610         * <pre>
611         *       Min: n/a
612         *       Max: n/a
613         *   Default: 0.0
614         *  Identity: n/a
615         * </pre>
616         * @defaultValue 0.0
617         */
618        private DoubleProperty pointsAtY;
619
620        public final void setPointsAtY(double value) {
621            pointsAtYProperty().set(value);
622        }
623
624        public final double getPointsAtY() {
625            return pointsAtY == null ? 0 : pointsAtY.get();
626        }
627
628        public final DoubleProperty pointsAtYProperty() {
629            if (pointsAtY == null) {
630                pointsAtY = new DoublePropertyBase() {
631
632                    @Override
633                    public void invalidated() {
634                        impl_markDirty();
635                    }
636
637                    @Override
638                    public Object getBean() {
639                        return Spot.this;
640                    }
641
642                    @Override
643                    public String getName() {
644                        return "pointsAtY";
645                    }
646                };
647            }
648            return pointsAtY;
649        }
650        /**
651         * The z coordinate of the direction vector for this light.
652         * <pre>
653         *       Min: n/a
654         *       Max: n/a
655         *   Default: 0.0
656         *  Identity: n/a
657         * </pre>
658         * @defaultValue 0.0
659         */
660        private DoubleProperty pointsAtZ;
661
662        public final void setPointsAtZ(double value) {
663            pointsAtZProperty().set(value);
664        }
665
666        public final double getPointsAtZ() {
667            return pointsAtZ == null ? 0 : pointsAtZ.get();
668        }
669
670        public final DoubleProperty pointsAtZProperty() {
671            if (pointsAtZ == null) {
672                pointsAtZ = new DoublePropertyBase() {
673
674                    @Override
675                    public void invalidated() {
676                        impl_markDirty();
677                    }
678
679                    @Override
680                    public Object getBean() {
681                        return Spot.this;
682                    }
683
684                    @Override
685                    public String getName() {
686                        return "pointsAtZ";
687                    }
688                };
689            }
690            return pointsAtZ;
691        }
692        /**
693         * The specular exponent, which controls the focus of this
694         * light source.
695         * <pre>
696         *       Min: 0.0
697         *       Max: 4.0
698         *   Default: 1.0
699         *  Identity: 1.0
700         * </pre>
701         * @defaultValue 1.0
702         */
703        private DoubleProperty specularExponent;
704
705        public final void setSpecularExponent(double value) {
706            specularExponentProperty().set(value);
707        }
708
709        public final double getSpecularExponent() {
710            return specularExponent == null ? 1 : specularExponent.get();
711        }
712
713        public final DoubleProperty specularExponentProperty() {
714            if (specularExponent == null) {
715                specularExponent = new DoublePropertyBase(1) {
716
717                    @Override
718                    public void invalidated() {
719                        impl_markDirty();
720                    }
721
722                    @Override
723                    public Object getBean() {
724                        return Spot.this;
725                    }
726
727                    @Override
728                    public String getName() {
729                        return "specularExponent";
730                    }
731                };
732            }
733            return specularExponent;
734        }
735
736        @Override
737        void impl_update() {
738            super.impl_update();
739            com.sun.scenario.effect.light.SpotLight peer =
740                    (com.sun.scenario.effect.light.SpotLight) impl_getImpl();
741            peer.setPointsAtX((float) getPointsAtX());
742            peer.setPointsAtY((float) getPointsAtY());
743            peer.setPointsAtZ((float) getPointsAtZ());
744            peer.setSpecularExponent((float) Utils.clamp(0, getSpecularExponent(), 4));
745        }
746    }
747}