src/demo/share/jfc/J2Ddemo/java2d/demos/Mix/Stars3D.java
changeset 50146 0bb0e464ee76
child 52252 de9486d74a74
equal deleted inserted replaced
50145:752645a158ff 50146:0bb0e464ee76
       
     1 /*
       
     2  *
       
     3  * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
       
     4  *
       
     5  * Redistribution and use in source and binary forms, with or without
       
     6  * modification, are permitted provided that the following conditions
       
     7  * are met:
       
     8  *
       
     9  *   - Redistributions of source code must retain the above copyright
       
    10  *     notice, this list of conditions and the following disclaimer.
       
    11  *
       
    12  *   - Redistributions in binary form must reproduce the above copyright
       
    13  *     notice, this list of conditions and the following disclaimer in the
       
    14  *     documentation and/or other materials provided with the distribution.
       
    15  *
       
    16  *   - Neither the name of Oracle nor the names of its
       
    17  *     contributors may be used to endorse or promote products derived
       
    18  *     from this software without specific prior written permission.
       
    19  *
       
    20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       
    21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       
    24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       
    28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       
    29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    31  */
       
    32 package java2d.demos.Mix;
       
    33 
       
    34 
       
    35 import static java.awt.Color.BLACK;
       
    36 import static java.awt.Color.BLUE;
       
    37 import static java.awt.Color.GREEN;
       
    38 import static java.awt.Color.RED;
       
    39 import static java.awt.Color.WHITE;
       
    40 import java.awt.AlphaComposite;
       
    41 import java.awt.Color;
       
    42 import java.awt.Component;
       
    43 import java.awt.Dimension;
       
    44 import java.awt.Font;
       
    45 import java.awt.Graphics2D;
       
    46 import java.awt.Rectangle;
       
    47 import java.awt.Shape;
       
    48 import java.awt.event.ActionEvent;
       
    49 import java.awt.event.ActionListener;
       
    50 import java.awt.font.FontRenderContext;
       
    51 import java.awt.geom.AffineTransform;
       
    52 import java.awt.geom.GeneralPath;
       
    53 import java.awt.geom.Line2D;
       
    54 import java.awt.geom.Path2D;
       
    55 import java.awt.geom.PathIterator;
       
    56 import java.awt.geom.Rectangle2D;
       
    57 import java2d.ControlsSurface;
       
    58 import java2d.CustomControls;
       
    59 import javax.swing.JLabel;
       
    60 import javax.swing.JTextField;
       
    61 
       
    62 
       
    63 /**
       
    64  * Generate a 3D text shape with GeneralPath, render a number of small
       
    65  * multi-colored rectangles and then render the 3D text shape.
       
    66  */
       
    67 @SuppressWarnings("serial")
       
    68 public class Stars3D extends ControlsSurface {
       
    69 
       
    70     private static Color colors[] = { RED, GREEN, WHITE };
       
    71     private static AffineTransform at = AffineTransform.getTranslateInstance(-5,
       
    72             -5);
       
    73     private Shape shape, tshape;
       
    74     private Shape ribbon;
       
    75     protected int fontSize = 72;
       
    76     protected String text = "OpenJDK";
       
    77     protected int numStars = 300;
       
    78 
       
    79     public Stars3D() {
       
    80         setBackground(BLACK);
       
    81         setControls(new Component[] { new DemoControls(this) });
       
    82     }
       
    83 
       
    84     @Override
       
    85     public void render(int w, int h, Graphics2D g2) {
       
    86 
       
    87         Rectangle2D rect = new Rectangle2D.Double();
       
    88         for (int i = 0; i < numStars; i++) {
       
    89             g2.setColor(colors[i % 3]);
       
    90             g2.setComposite(AlphaComposite.getInstance(
       
    91                     AlphaComposite.SRC_OVER, (float) Math.random()));
       
    92             rect.setRect(w * Math.random(), h * Math.random(), 2, 2);
       
    93             g2.fill(rect);
       
    94         }
       
    95 
       
    96         FontRenderContext frc = g2.getFontRenderContext();
       
    97         Font font = new Font(Font.SERIF, Font.BOLD|Font.ITALIC, fontSize);
       
    98         shape = font.createGlyphVector(frc, text).getOutline();
       
    99         tshape = at.createTransformedShape(shape);
       
   100         PathIterator pi = shape.getPathIterator(null);
       
   101 
       
   102         float seg[] = new float[6];
       
   103         float tseg[] = new float[6];
       
   104 
       
   105         GeneralPath working = new GeneralPath(Path2D.WIND_NON_ZERO);
       
   106         float x = 0, y = 0; // Current point on the path
       
   107         float tx = 0, ty = 0; // Transformed path point
       
   108         float cx = 0, cy = 0; // Last moveTo point, for SEG_CLOSE
       
   109         float tcx = 0, tcy = 0; // Transformed last moveTo point
       
   110 
       
   111         //
       
   112         // Iterate through the Shape and build the ribbon
       
   113         // by adding general path objects.
       
   114         //
       
   115         while (!pi.isDone()) {
       
   116             int segType = pi.currentSegment(seg);
       
   117             switch (segType) {
       
   118                 case PathIterator.SEG_MOVETO:
       
   119                     at.transform(seg, 0, tseg, 0, 1);
       
   120                     x = seg[0];
       
   121                     y = seg[1];
       
   122                     tx = tseg[0];
       
   123                     ty = tseg[1];
       
   124                     cx = x;
       
   125                     cy = y;
       
   126                     tcx = tx;
       
   127                     tcy = ty;
       
   128                     break;
       
   129                 case PathIterator.SEG_LINETO:
       
   130                     at.transform(seg, 0, tseg, 0, 1);
       
   131                     if (Line2D.relativeCCW(x, y, tx, ty, seg[0], seg[1]) < 0) {
       
   132                         working.moveTo(x, y);
       
   133                         working.lineTo(seg[0], seg[1]);
       
   134                         working.lineTo(tseg[0], tseg[1]);
       
   135                         working.lineTo(tx, ty);
       
   136                         working.lineTo(x, y);
       
   137                     } else {
       
   138                         working.moveTo(x, y);
       
   139                         working.lineTo(tx, ty);
       
   140                         working.lineTo(tseg[0], tseg[1]);
       
   141                         working.lineTo(seg[0], seg[1]);
       
   142                         working.lineTo(x, y);
       
   143                     }
       
   144 
       
   145                     x = seg[0];
       
   146                     y = seg[1];
       
   147                     tx = tseg[0];
       
   148                     ty = tseg[1];
       
   149                     break;
       
   150 
       
   151                 case PathIterator.SEG_QUADTO:
       
   152                     at.transform(seg, 0, tseg, 0, 2);
       
   153                     if (Line2D.relativeCCW(x, y, tx, ty, seg[2], seg[3]) < 0) {
       
   154                         working.moveTo(x, y);
       
   155                         working.quadTo(seg[0], seg[1],
       
   156                                 seg[2], seg[3]);
       
   157                         working.lineTo(tseg[2], tseg[3]);
       
   158                         working.quadTo(tseg[0], tseg[1],
       
   159                                 tx, ty);
       
   160                         working.lineTo(x, y);
       
   161                     } else {
       
   162                         working.moveTo(x, y);
       
   163                         working.lineTo(tx, ty);
       
   164                         working.quadTo(tseg[0], tseg[1],
       
   165                                 tseg[2], tseg[3]);
       
   166                         working.lineTo(seg[2], seg[3]);
       
   167                         working.quadTo(seg[0], seg[1],
       
   168                                 x, y);
       
   169                     }
       
   170 
       
   171                     x = seg[2];
       
   172                     y = seg[3];
       
   173                     tx = tseg[2];
       
   174                     ty = tseg[3];
       
   175                     break;
       
   176 
       
   177                 case PathIterator.SEG_CUBICTO:
       
   178                     at.transform(seg, 0, tseg, 0, 3);
       
   179                     if (Line2D.relativeCCW(x, y, tx, ty, seg[4], seg[5]) < 0) {
       
   180                         working.moveTo(x, y);
       
   181                         working.curveTo(seg[0], seg[1],
       
   182                                 seg[2], seg[3],
       
   183                                 seg[4], seg[5]);
       
   184                         working.lineTo(tseg[4], tseg[5]);
       
   185                         working.curveTo(tseg[2], tseg[3],
       
   186                                 tseg[0], tseg[1],
       
   187                                 tx, ty);
       
   188                         working.lineTo(x, y);
       
   189                     } else {
       
   190                         working.moveTo(x, y);
       
   191                         working.lineTo(tx, ty);
       
   192                         working.curveTo(tseg[0], tseg[1],
       
   193                                 tseg[2], tseg[3],
       
   194                                 tseg[4], tseg[5]);
       
   195                         working.lineTo(seg[4], seg[5]);
       
   196                         working.curveTo(seg[2], seg[3],
       
   197                                 seg[0], seg[1],
       
   198                                 x, y);
       
   199                     }
       
   200 
       
   201                     x = seg[4];
       
   202                     y = seg[5];
       
   203                     tx = tseg[4];
       
   204                     ty = tseg[5];
       
   205                     break;
       
   206 
       
   207                 case PathIterator.SEG_CLOSE:
       
   208                     if (Line2D.relativeCCW(x, y, tx, ty, cx, cy) < 0) {
       
   209                         working.moveTo(x, y);
       
   210                         working.lineTo(cx, cy);
       
   211                         working.lineTo(tcx, tcy);
       
   212                         working.lineTo(tx, ty);
       
   213                         working.lineTo(x, y);
       
   214                     } else {
       
   215                         working.moveTo(x, y);
       
   216                         working.lineTo(tx, ty);
       
   217                         working.lineTo(tcx, tcy);
       
   218                         working.lineTo(cx, cy);
       
   219                         working.lineTo(x, y);
       
   220                     }
       
   221                     x = cx;
       
   222                     y = cy;
       
   223                     tx = tcx;
       
   224                     ty = tcy;
       
   225             }
       
   226             pi.next();
       
   227         } // while
       
   228         ribbon = working;
       
   229 
       
   230         if (composite != null) {
       
   231             g2.setComposite(composite);
       
   232         } else {
       
   233             g2.setComposite(AlphaComposite.SrcOver);
       
   234         }
       
   235         Rectangle r = shape.getBounds();
       
   236         g2.translate(w * .5 - r.width * .5, h * .5 + r.height * .5);
       
   237 
       
   238         g2.setColor(BLUE);
       
   239         g2.fill(tshape);
       
   240         g2.setColor(new Color(255, 255, 255, 200));
       
   241         g2.fill(ribbon);
       
   242 
       
   243         g2.setColor(WHITE);
       
   244         g2.fill(shape);
       
   245 
       
   246         g2.setColor(BLUE);
       
   247         g2.draw(shape);
       
   248     }
       
   249 
       
   250     public static void main(String argv[]) {
       
   251         createDemoFrame(new Stars3D());
       
   252     }
       
   253 
       
   254 
       
   255     static class DemoControls extends CustomControls implements ActionListener {
       
   256 
       
   257         Stars3D demo;
       
   258         JTextField tf1, tf2;
       
   259 
       
   260         @SuppressWarnings("LeakingThisInConstructor")
       
   261         public DemoControls(Stars3D demo) {
       
   262             super(demo.name);
       
   263             this.demo = demo;
       
   264             JLabel l = new JLabel("  Text:");
       
   265             l.setForeground(BLACK);
       
   266             add(l);
       
   267             add(tf1 = new JTextField(demo.text));
       
   268             tf1.setPreferredSize(new Dimension(60, 20));
       
   269             tf1.addActionListener(this);
       
   270             l = new JLabel("  Size:");
       
   271             l.setForeground(BLACK);
       
   272             add(l);
       
   273             add(tf2 = new JTextField(String.valueOf(demo.fontSize)));
       
   274             tf2.setPreferredSize(new Dimension(30, 20));
       
   275             tf2.addActionListener(this);
       
   276         }
       
   277 
       
   278         @Override
       
   279         public void actionPerformed(ActionEvent e) {
       
   280             try {
       
   281                 if (e.getSource().equals(tf1)) {
       
   282                     demo.text = tf1.getText().trim();
       
   283                 } else if (e.getSource().equals(tf2)) {
       
   284                     demo.fontSize = Integer.parseInt(tf2.getText().trim());
       
   285                     if (demo.fontSize < 10) {
       
   286                         demo.fontSize = 10;
       
   287                     }
       
   288                 }
       
   289                 demo.repaint();
       
   290             } catch (Exception ignored) {
       
   291             }
       
   292         }
       
   293 
       
   294         @Override
       
   295         public Dimension getPreferredSize() {
       
   296             return new Dimension(200, 37);
       
   297         }
       
   298 
       
   299         @Override
       
   300         @SuppressWarnings("SleepWhileHoldingLock")
       
   301         public void run() {
       
   302             Thread me = Thread.currentThread();
       
   303             try {
       
   304                 Thread.sleep(999);
       
   305             } catch (Exception e) {
       
   306                 return;
       
   307             }
       
   308             int length = getSize().width / 4;
       
   309             int size[] = { length, length };
       
   310             String str[] = { "OpenJDK", "J2D" };
       
   311             while (thread == me) {
       
   312                 for (int i = 0; i < str.length; i++) {
       
   313                     demo.fontSize = size[i];
       
   314                     tf2.setText(String.valueOf(demo.fontSize));
       
   315                     tf1.setText(demo.text = str[i]);
       
   316                     demo.repaint();
       
   317                     try {
       
   318                         Thread.sleep(5555);
       
   319                     } catch (InterruptedException e) {
       
   320                         return;
       
   321                     }
       
   322                 }
       
   323             }
       
   324             thread = null;
       
   325         }
       
   326     } // End DemoControls
       
   327 } // End Stars3D
       
   328