home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / JBuilder8.iso / Solaris / resource / jre / demo / plugin / applets / DitherTest / DitherTest.java < prev    next >
Encoding:
Java Source  |  2002-09-06  |  11.6 KB  |  383 lines

  1. /*
  2.  * Copyright (c) 2002 Sun Microsystems, Inc. All  Rights Reserved.
  3.  * 
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  * 
  8.  * -Redistributions of source code must retain the above copyright
  9.  *  notice, this list of conditions and the following disclaimer.
  10.  * 
  11.  * -Redistribution in binary form must reproduct the above copyright
  12.  *  notice, this list of conditions and the following disclaimer in
  13.  *  the documentation and/or other materials provided with the distribution.
  14.  * 
  15.  * Neither the name of Sun Microsystems, Inc. or the names of contributors
  16.  * may be used to endorse or promote products derived from this software
  17.  * without specific prior written permission.
  18.  * 
  19.  * This software is provided "AS IS," without a warranty of any kind. ALL
  20.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
  21.  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
  22.  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT
  23.  * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
  24.  * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
  25.  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
  26.  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
  27.  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
  28.  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
  29.  * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  30.  * 
  31.  * You acknowledge that Software is not designed, licensed or intended for
  32.  * use in the design, construction, operation or maintenance of any nuclear
  33.  * facility.
  34.  */
  35.  
  36. /*
  37.  * @(#)DitherTest.java    1.11 02/06/13
  38.  */
  39.  
  40. import java.applet.Applet;
  41. import java.awt.event.*;
  42. import java.awt.*;
  43. import java.awt.image.ColorModel;
  44. import java.awt.image.MemoryImageSource;
  45.  
  46. public class DitherTest extends Applet implements Runnable {
  47.     final private static int NOOP = 0;
  48.     final private static int RED = 1;
  49.     final private static int GREEN = 2;
  50.     final private static int BLUE = 3;
  51.     final private static int ALPHA = 4;
  52.     final private static int SATURATION = 5;
  53.  
  54.     private Thread runner;
  55.  
  56.     private DitherControls XControls;
  57.     private DitherControls YControls;
  58.     private DitherCanvas canvas;
  59.  
  60.     public static void main(String args[]) {
  61.         Frame f = new Frame("DitherTest");
  62.         DitherTest ditherTest = new DitherTest();
  63.         ditherTest.init();
  64.         f.add("Center", ditherTest);
  65.         f.pack();
  66.         f.setVisible(true);
  67.         ditherTest.start();
  68.     }
  69.  
  70.     public void init() {
  71.         String xspec = null, yspec = null;
  72.         int xvals[] = new int[2];
  73.         int yvals[] = new int[2];
  74.         
  75.         try {
  76.             xspec = getParameter("xaxis");
  77.             yspec = getParameter("yaxis");
  78.         } catch (NullPointerException npe) {
  79.             //only occurs if run as application
  80.         }
  81.         
  82.         if (xspec == null) {
  83.             xspec = "red";
  84.         }
  85.         if (yspec == null) {
  86.             yspec = "blue";
  87.         }
  88.         int xmethod = colormethod(xspec, xvals);
  89.         int ymethod = colormethod(yspec, yvals);
  90.  
  91.         setLayout(new BorderLayout());
  92.         XControls = new DitherControls(this, xvals[0], xvals[1],
  93.                                        xmethod, false);
  94.         YControls = new DitherControls(this, yvals[0], yvals[1],
  95.                                        ymethod, true);
  96.         YControls.addRenderButton();
  97.         add("North", XControls);
  98.         add("South", YControls);
  99.         add("Center", canvas = new DitherCanvas());
  100.     }
  101.  
  102.     private int colormethod(String s, int vals[]) {
  103.         int method = NOOP;
  104.         if (s == null) {
  105.             s = "";
  106.         }
  107.         String lower = s.toLowerCase();
  108.         int len = 0;
  109.         if (lower.startsWith("red")) {
  110.             method = RED;
  111.             lower = lower.substring(3);
  112.         } else if (lower.startsWith("green")) {
  113.             method = GREEN;
  114.             lower = lower.substring(5);
  115.         } else if (lower.startsWith("blue")) {
  116.             method = BLUE;
  117.             lower = lower.substring(4);
  118.         } else if (lower.startsWith("alpha")) {
  119.             method = ALPHA;
  120.             lower = lower.substring(5);
  121.         } else if (lower.startsWith("saturation")) {
  122.             method = SATURATION;
  123.             lower = lower.substring(10);
  124.         }
  125.         if (method == NOOP) {
  126.             vals[0] = 0;
  127.             vals[1] = 0;
  128.             return method;
  129.         }
  130.         int begval = 0;
  131.         int endval = 255;
  132.         try {
  133.             int dash = lower.indexOf('-');
  134.             if (dash < 0) {
  135.                 endval = Integer.parseInt(lower);
  136.             } else {
  137.                 begval = Integer.parseInt(lower.substring(0, dash));
  138.                 endval = Integer.parseInt(lower.substring(dash + 1));
  139.             }
  140.         } catch (NumberFormatException e) {
  141.         }
  142.  
  143.         if (begval < 0) {
  144.             begval = 0;
  145.         } else if (begval > 255) {
  146.             begval = 255;
  147.         }
  148.         
  149.         if (endval < 0) {
  150.             endval = 0;
  151.         } else if (endval > 255) {
  152.             endval = 255;
  153.         }
  154.  
  155.         vals[0] = begval;
  156.         vals[1] = endval;
  157.         return method;
  158.     }
  159.  
  160.     /**
  161.      * Calculates and returns the image.  Halts the calculation and returns
  162.      * null if the Applet is stopped during the calculation.
  163.      */
  164.     private Image calculateImage() {
  165.         Thread me = Thread.currentThread();
  166.         
  167.         int width = canvas.getSize().width;
  168.         int height = canvas.getSize().height;
  169.         int xvals[] = new int[2];
  170.         int yvals[] = new int[2];
  171.         int xmethod = XControls.getParams(xvals);
  172.         int ymethod = YControls.getParams(yvals);
  173.         int pixels[] = new int[width * height];
  174.         int c[] = new int[4];   //temporarily holds R,G,B,A information
  175.         int index = 0;
  176.         for (int j = 0; j < height; j++) {
  177.             for (int i = 0; i < width; i++) {
  178.                 c[0] = c[1] = c[2] = 0;
  179.                 c[3] = 255;
  180.                 if (xmethod < ymethod) {
  181.                     applymethod(c, xmethod, i, width, xvals);
  182.                     applymethod(c, ymethod, j, height, yvals);
  183.                 } else {
  184.                     applymethod(c, ymethod, j, height, yvals);
  185.                     applymethod(c, xmethod, i, width, xvals);
  186.                 }
  187.                 pixels[index++] = ((c[3] << 24) |
  188.                                    (c[0] << 16) |
  189.                                    (c[1] << 8) |
  190.                                    c[2]);
  191.             }
  192.  
  193.             // Poll once per row to see if we've been told to stop.
  194.             if (runner != me) {
  195.                 return null;
  196.             }
  197.         }
  198.         return createImage(new MemoryImageSource(width, height,
  199.                             ColorModel.getRGBdefault(), pixels, 0, width));
  200.     }
  201.  
  202.     private void applymethod(int c[], int method, int step, 
  203.                              int total, int vals[]) {
  204.         if (method == NOOP) {
  205.             return;
  206.         }
  207.         int val = ((total < 2)
  208.                    ? vals[0]
  209.                    : vals[0] + ((vals[1] - vals[0]) * step / (total - 1)));
  210.         switch (method) {
  211.         case RED:
  212.             c[0] = val;
  213.             break;
  214.         case GREEN:
  215.             c[1] = val;
  216.             break;
  217.         case BLUE:
  218.             c[2] = val;
  219.             break;
  220.         case ALPHA:
  221.             c[3] = val;
  222.             break;
  223.         case SATURATION:
  224.             int max = Math.max(Math.max(c[0], c[1]), c[2]);
  225.             int min = max * (255 - val) / 255;
  226.             if (c[0] == 0) {
  227.                 c[0] = min;
  228.             }
  229.             if (c[1] == 0) {
  230.                 c[1] = min;
  231.             }
  232.             if (c[2] == 0) {
  233.                 c[2] = min;
  234.             }
  235.             break;
  236.         }
  237.     }
  238.  
  239.     public void start() {
  240.         runner = new Thread(this);
  241.         runner.start();
  242.     }
  243.  
  244.     public void run() {
  245.         canvas.setImage(null);  // Wipe previous image
  246.         Image img = calculateImage();
  247.         if (img != null && runner == Thread.currentThread()) {
  248.             canvas.setImage(img);
  249.         }
  250.     }
  251.  
  252.     public void stop() {
  253.         runner = null;
  254.     }
  255.  
  256.     public void destroy() {
  257.         remove(XControls);
  258.         remove(YControls);
  259.         remove(canvas);
  260.     }
  261.  
  262.     public String getAppletInfo() {
  263.         return "An interactive demonstration of dithering.";
  264.     }
  265.  
  266.     public String[][] getParameterInfo() {
  267.         String[][] info = {
  268.             {"xaxis", "{RED, GREEN, BLUE, ALPHA, SATURATION}",
  269.              "The color of the Y axis.  Default is RED."},
  270.             {"yaxis", "{RED, GREEN, BLUE, ALPHA, SATURATION}", 
  271.              "The color of the X axis.  Default is BLUE."}
  272.         };
  273.         return info;
  274.     }
  275. }
  276.  
  277. class DitherCanvas extends Canvas {
  278.     private Image img;
  279.     private static String calcString = "Calculating...";
  280.  
  281.     public void paint(Graphics g) {
  282.         int w = getSize().width;
  283.         int h = getSize().height;
  284.         if (img == null) {
  285.             super.paint(g);
  286.             g.setColor(Color.black);
  287.             FontMetrics fm = g.getFontMetrics();
  288.             int x = (w - fm.stringWidth(calcString)) / 2;
  289.             int y = h / 2;
  290.             g.drawString(calcString, x, y);
  291.         } else {
  292.             g.drawImage(img, 0, 0, w, h, this);
  293.         }
  294.     }
  295.  
  296.     public void update(Graphics g) {
  297.         paint(g);
  298.     }
  299.  
  300.     public Dimension getMinimumSize() {
  301.         return new Dimension(20, 20);
  302.     }
  303.  
  304.     public Dimension getPreferredSize() {
  305.         return new Dimension(200, 200);
  306.     }
  307.  
  308.     public Image getImage() {
  309.         return img;
  310.     }
  311.  
  312.     public void setImage(Image img) {
  313.         this.img = img;
  314.         repaint();
  315.     }
  316. }
  317.  
  318. class DitherControls extends Panel implements ActionListener {
  319.     private TextField start;
  320.     private TextField end;
  321.     private Button button;
  322.     private Choice choice;
  323.     private DitherTest applet;
  324.  
  325.     private static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER,
  326.                                                            10, 5);
  327.  
  328.     public DitherControls(DitherTest app, int s, int e, int type,
  329.                           boolean vertical) {
  330.         applet = app;
  331.         setLayout(dcLayout);
  332.         add(new Label(vertical ? "Vertical" : "Horizontal"));
  333.         add(choice = new Choice());
  334.         choice.addItem("Noop");
  335.         choice.addItem("Red");
  336.         choice.addItem("Green");
  337.         choice.addItem("Blue");
  338.         choice.addItem("Alpha");
  339.         choice.addItem("Saturation");
  340.         choice.select(type);
  341.         add(start = new TextField(Integer.toString(s), 4));
  342.         add(end = new TextField(Integer.toString(e), 4));
  343.     }
  344.  
  345.     /* puts on the button */
  346.     public void addRenderButton() {
  347.         add(button = new Button("New Image"));
  348.         button.addActionListener(this);
  349.     }
  350.  
  351.     /* retrieves data from the user input fields */
  352.     public int getParams(int vals[]) {
  353.         try {
  354.             vals[0] = scale(Integer.parseInt(start.getText()));
  355.         } catch (NumberFormatException e) {
  356.             vals[0] = 0;
  357.         }
  358.         try {
  359.             vals[1] = scale(Integer.parseInt(end.getText()));
  360.         } catch (NumberFormatException e) {
  361.             vals[1] = 255;
  362.         }
  363.         return choice.getSelectedIndex();
  364.     }
  365.     
  366.     /* fits the number between 0 and 255 inclusive */
  367.     private int scale(int number) {
  368.         if (number < 0) {
  369.             number = 0;
  370.         } else if (number > 255) {
  371.             number = 255;
  372.         }
  373.         return number;
  374.     }
  375.  
  376.     /* called when user clicks the button */
  377.     public void actionPerformed(ActionEvent e) {
  378.         if (e.getSource() == button) {
  379.             applet.start();
  380.         }
  381.     }
  382. }
  383.