1 36 37 40 41 import java.applet.Applet ; 42 import java.awt.event.*; 43 import java.awt.*; 44 import java.awt.image.ColorModel ; 45 import java.awt.image.MemoryImageSource ; 46 47 public class DitherTest extends Applet implements Runnable { 48 final private static int NOOP = 0; 49 final private static int RED = 1; 50 final private static int GREEN = 2; 51 final private static int BLUE = 3; 52 final private static int ALPHA = 4; 53 final private static int SATURATION = 5; 54 55 private Thread runner; 56 57 private DitherControls XControls; 58 private DitherControls YControls; 59 private DitherCanvas canvas; 60 61 public static void main(String args[]) { 62 Frame f = new Frame("DitherTest"); 63 DitherTest ditherTest = new DitherTest(); 64 ditherTest.init(); 65 f.add("Center", ditherTest); 66 f.pack(); 67 f.setVisible(true); 68 ditherTest.start(); 69 } 70 71 public void init() { 72 String xspec = null, yspec = null; 73 int xvals[] = new int[2]; 74 int yvals[] = new int[2]; 75 76 try { 77 xspec = getParameter("xaxis"); 78 yspec = getParameter("yaxis"); 79 } catch (NullPointerException npe) { 80 } 82 83 if (xspec == null) { 84 xspec = "red"; 85 } 86 if (yspec == null) { 87 yspec = "blue"; 88 } 89 int xmethod = colormethod(xspec, xvals); 90 int ymethod = colormethod(yspec, yvals); 91 92 setLayout(new BorderLayout()); 93 XControls = new DitherControls(this, xvals[0], xvals[1], 94 xmethod, false); 95 YControls = new DitherControls(this, yvals[0], yvals[1], 96 ymethod, true); 97 YControls.addRenderButton(); 98 add("North", XControls); 99 add("South", YControls); 100 add("Center", canvas = new DitherCanvas()); 101 } 102 103 private int colormethod(String s, int vals[]) { 104 int method = NOOP; 105 if (s == null) { 106 s = ""; 107 } 108 String lower = s.toLowerCase(); 109 int len = 0; 110 if (lower.startsWith("red")) { 111 method = RED; 112 lower = lower.substring(3); 113 } else if (lower.startsWith("green")) { 114 method = GREEN; 115 lower = lower.substring(5); 116 } else if (lower.startsWith("blue")) { 117 method = BLUE; 118 lower = lower.substring(4); 119 } else if (lower.startsWith("alpha")) { 120 method = ALPHA; 121 lower = lower.substring(5); 122 } else if (lower.startsWith("saturation")) { 123 method = SATURATION; 124 lower = lower.substring(10); 125 } 126 if (method == NOOP) { 127 vals[0] = 0; 128 vals[1] = 0; 129 return method; 130 } 131 int begval = 0; 132 int endval = 255; 133 try { 134 int dash = lower.indexOf('-'); 135 if (dash < 0) { 136 endval = Integer.parseInt(lower); 137 } else { 138 begval = Integer.parseInt(lower.substring(0, dash)); 139 endval = Integer.parseInt(lower.substring(dash + 1)); 140 } 141 } catch (NumberFormatException nfe) { 142 } 143 144 if (begval < 0) { 145 begval = 0; 146 } else if (begval > 255) { 147 begval = 255; 148 } 149 150 if (endval < 0) { 151 endval = 0; 152 } else if (endval > 255) { 153 endval = 255; 154 } 155 156 vals[0] = begval; 157 vals[1] = endval; 158 return method; 159 } 160 161 165 private Image calculateImage() { 166 Thread me = Thread.currentThread(); 167 168 int width = canvas.getSize().width; 169 int height = canvas.getSize().height; 170 int xvals[] = new int[2]; 171 int yvals[] = new int[2]; 172 int xmethod = XControls.getParams(xvals); 173 int ymethod = YControls.getParams(yvals); 174 int pixels[] = new int[width * height]; 175 int c[] = new int[4]; int index = 0; 177 for (int j = 0; j < height; j++) { 178 for (int i = 0; i < width; i++) { 179 c[0] = c[1] = c[2] = 0; 180 c[3] = 255; 181 if (xmethod < ymethod) { 182 applymethod(c, xmethod, i, width, xvals); 183 applymethod(c, ymethod, j, height, yvals); 184 } else { 185 applymethod(c, ymethod, j, height, yvals); 186 applymethod(c, xmethod, i, width, xvals); 187 } 188 pixels[index++] = ((c[3] << 24) | 189 (c[0] << 16) | 190 (c[1] << 8) | 191 c[2]); 192 } 193 194 if (runner != me) { 196 return null; 197 } 198 } 199 return createImage(new MemoryImageSource (width, height, 200 ColorModel.getRGBdefault(), pixels, 0, width)); 201 } 202 203 private void applymethod(int c[], int method, int step, 204 int total, int vals[]) { 205 if (method == NOOP) { 206 return; 207 } 208 int val = ((total < 2) 209 ? vals[0] 210 : vals[0] + ((vals[1] - vals[0]) * step / (total - 1))); 211 switch (method) { 212 case RED: 213 c[0] = val; 214 break; 215 case GREEN: 216 c[1] = val; 217 break; 218 case BLUE: 219 c[2] = val; 220 break; 221 case ALPHA: 222 c[3] = val; 223 break; 224 case SATURATION: 225 int max = Math.max(Math.max(c[0], c[1]), c[2]); 226 int min = max * (255 - val) / 255; 227 if (c[0] == 0) { 228 c[0] = min; 229 } 230 if (c[1] == 0) { 231 c[1] = min; 232 } 233 if (c[2] == 0) { 234 c[2] = min; 235 } 236 break; 237 } 238 } 239 240 public void start() { 241 runner = new Thread (this); 242 runner.start(); 243 } 244 245 public void run() { 246 canvas.setImage(null); Image img = calculateImage(); 248 if (img != null && runner == Thread.currentThread()) { 249 canvas.setImage(img); 250 } 251 } 252 253 public void stop() { 254 runner = null; 255 } 256 257 public void destroy() { 258 remove(XControls); 259 remove(YControls); 260 remove(canvas); 261 } 262 263 public String getAppletInfo() { 264 return "An interactive demonstration of dithering."; 265 } 266 267 public String [][] getParameterInfo() { 268 String [][] info = { 269 {"xaxis", "{RED, GREEN, BLUE, ALPHA, SATURATION}", 270 "The color of the Y axis. Default is RED."}, 271 {"yaxis", "{RED, GREEN, BLUE, ALPHA, SATURATION}", 272 "The color of the X axis. Default is BLUE."} 273 }; 274 return info; 275 } 276 } 277 278 class DitherCanvas extends Canvas { 279 private Image img; 280 private static String calcString = "Calculating..."; 281 282 public void paint(Graphics g) { 283 int w = getSize().width; 284 int h = getSize().height; 285 if (img == null) { 286 super.paint(g); 287 g.setColor(Color.black); 288 FontMetrics fm = g.getFontMetrics(); 289 int x = (w - fm.stringWidth(calcString)) / 2; 290 int y = h / 2; 291 g.drawString(calcString, x, y); 292 } else { 293 g.drawImage(img, 0, 0, w, h, this); 294 } 295 } 296 297 public void update(Graphics g) { 298 paint(g); 299 } 300 301 public Dimension getMinimumSize() { 302 return new Dimension(20, 20); 303 } 304 305 public Dimension getPreferredSize() { 306 return new Dimension(200, 200); 307 } 308 309 public Image getImage() { 310 return img; 311 } 312 313 public void setImage(Image img) { 314 this.img = img; 315 repaint(); 316 } 317 } 318 319 class DitherControls extends Panel implements ActionListener { 320 private CardinalTextField start; 321 private CardinalTextField end; 322 private Button button; 323 private Choice choice; 324 private DitherTest applet; 325 326 private static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER, 327 10, 5); 328 329 public DitherControls(DitherTest app, int s, int e, int type, 330 boolean vertical) { 331 applet = app; 332 setLayout(dcLayout); 333 add(new Label(vertical ? "Vertical" : "Horizontal")); 334 add(choice = new Choice()); 335 choice.addItem("Noop"); 336 choice.addItem("Red"); 337 choice.addItem("Green"); 338 choice.addItem("Blue"); 339 choice.addItem("Alpha"); 340 choice.addItem("Saturation"); 341 choice.select(type); 342 add(start = new CardinalTextField(Integer.toString(s), 4)); 343 add(end = new CardinalTextField(Integer.toString(e), 4)); 344 } 345 346 347 public void addRenderButton() { 348 add(button = new Button("New Image")); 349 button.addActionListener(this); 350 } 351 352 353 public int getParams(int vals[]) { 354 try { 355 vals[0] = scale(Integer.parseInt(start.getText())); 356 } catch (NumberFormatException nfe) { 357 vals[0] = 0; 358 } 359 try { 360 vals[1] = scale(Integer.parseInt(end.getText())); 361 } catch (NumberFormatException nfe) { 362 vals[1] = 255; 363 } 364 return choice.getSelectedIndex(); 365 } 366 367 368 private int scale(int number) { 369 if (number < 0) { 370 number = 0; 371 } else if (number > 255) { 372 number = 255; 373 } 374 return number; 375 } 376 377 378 public void actionPerformed(ActionEvent e) { 379 if (e.getSource() == button) { 380 applet.start(); 381 } 382 } 383 } 384 385 class CardinalTextField extends TextField { 386 387 String oldText = null; 388 389 public CardinalTextField(String text, int columns) { 390 super(text, columns); 391 enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.TEXT_EVENT_MASK); 392 oldText = getText(); 393 } 394 395 protected void processEvent(AWTEvent evt) { 401 int id = evt.getID(); 402 if (id != KeyEvent.KEY_TYPED) { 403 super.processEvent(evt); 404 return; 405 } 406 407 KeyEvent kevt = (KeyEvent) evt; 408 char c = kevt.getKeyChar(); 409 410 if (Character.isDigit(c) || (c == '\b') || (c == '\u007f')) { 413 super.processEvent(evt); 414 return; 415 } 416 417 Toolkit.getDefaultToolkit().beep(); 418 kevt.consume(); 419 } 420 421 protected void processTextEvent(TextEvent te) { 430 String newText = getText(); 432 if (newText.equals("") || textIsCardinal(newText)) { 433 oldText = newText; 434 super.processTextEvent(te); 435 return; 436 } 437 438 Toolkit.getDefaultToolkit().beep(); 439 setText(oldText); 440 } 441 442 private boolean textIsCardinal(String textToCheck) { 445 int value = -1; 446 447 try { 448 value = Integer.parseInt(textToCheck, 10); 449 return (value >= 0); 450 } catch (NumberFormatException nfe) { 451 return false; 452 } 453 } 454 } 455 456 | Popular Tags |