1 7 package com.sun.java.swing.plaf.gtk; 8 9 import java.awt.*; 10 import java.awt.event.*; 11 import java.awt.image.*; 12 import javax.swing.*; 13 import javax.swing.colorchooser.*; 14 import javax.swing.event.*; 15 import javax.swing.plaf.*; 16 17 24 class GTKColorChooserPanel extends AbstractColorChooserPanel implements 25 ChangeListener { 26 private static final float PI_3 = (float)(Math.PI / 3); 27 28 private ColorTriangle triangle; 29 private JLabel lastLabel; 30 private JLabel label; 31 32 private JSpinner hueSpinner; 33 private JSpinner saturationSpinner; 34 private JSpinner valueSpinner; 35 36 private JSpinner redSpinner; 37 private JSpinner greenSpinner; 38 private JSpinner blueSpinner; 39 40 private JTextField colorNameTF; 41 42 private boolean settingColor; 43 44 private float hue; 47 private float saturation; 48 private float brightness; 49 50 51 52 55 static void compositeRequestFocus(Component component, boolean direction) { 57 if (component instanceof Container) { 58 Container container = (Container)component; 59 if (container.isFocusCycleRoot()) { 60 FocusTraversalPolicy policy = container. 61 getFocusTraversalPolicy(); 62 Component comp = policy.getDefaultComponent(container); 63 if (comp!=null) { 64 comp.requestFocus(); 65 return; 66 } 67 } 68 Container rootAncestor = container.getFocusCycleRootAncestor(); 69 if (rootAncestor!=null) { 70 FocusTraversalPolicy policy = rootAncestor. 71 getFocusTraversalPolicy(); 72 Component comp; 73 74 if (direction) { 75 comp = policy.getComponentAfter(rootAncestor, container); 76 } 77 else { 78 comp = policy.getComponentBefore(rootAncestor, container); 79 } 80 if (comp != null) { 81 comp.requestFocus(); 82 return; 83 } 84 } 85 } 86 component.requestFocus(); 87 } 88 89 90 93 public String getDisplayName() { 94 return (String )UIManager.get("GTKColorChooserPanel.nameText"); 95 } 96 97 100 public int getMnemonic() { 101 String m = (String )UIManager.get("GTKColorChooserPanel.mnemonic"); 102 103 if (m != null) { 104 try { 105 int value = Integer.parseInt(m); 106 107 return value; 108 } catch (NumberFormatException nfe) {} 109 } 110 return -1; 111 } 112 113 116 public int getDisplayedMnemonicIndex() { 117 String m = (String )UIManager.get( 118 "GTKColorChooserPanel.displayedMnemonicIndex"); 119 120 if (m != null) { 121 try { 122 int value = Integer.parseInt(m); 123 124 return value; 125 } catch (NumberFormatException nfe) {} 126 } 127 return -1; 128 } 129 130 public Icon getSmallDisplayIcon() { 131 return null; 132 } 133 134 public Icon getLargeDisplayIcon() { 135 return null; 136 } 137 138 public void uninstallChooserPanel(JColorChooser enclosingChooser) { 139 super.uninstallChooserPanel(enclosingChooser); 140 removeAll(); 141 } 142 143 146 protected void buildChooser() { 147 triangle = new ColorTriangle(); 148 triangle.setName("GTKColorChooserPanel.triangle"); 149 150 label = new OpaqueLabel(); 153 label.setName("GTKColorChooserPanel.colorWell"); 154 label.setOpaque(true); 155 label.setMinimumSize(new Dimension(67, 32)); 156 label.setPreferredSize(new Dimension(67, 32)); 157 label.setMaximumSize(new Dimension(67, 32)); 158 159 lastLabel = new OpaqueLabel(); 162 lastLabel.setName("GTKColorChooserPanel.lastColorWell"); 163 lastLabel.setOpaque(true); 164 lastLabel.setMinimumSize(new Dimension(67, 32)); 165 lastLabel.setPreferredSize(new Dimension(67, 32)); 166 lastLabel.setMaximumSize(new Dimension(67, 32)); 167 168 hueSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 360, 1)); 169 configureSpinner(hueSpinner, "GTKColorChooserPanel.hueSpinner"); 170 saturationSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1)); 171 configureSpinner(saturationSpinner, 172 "GTKColorChooserPanel.saturationSpinner"); 173 valueSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1)); 174 configureSpinner(valueSpinner, "GTKColorChooserPanel.valueSpinner"); 175 redSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1)); 176 configureSpinner(redSpinner, "GTKColorChooserPanel.redSpinner"); 177 greenSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1)); 178 configureSpinner(greenSpinner, "GTKColorChooserPanel.greenSpinner"); 179 blueSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1)); 180 configureSpinner(blueSpinner, "GTKColorChooserPanel.blueSpinner"); 181 182 colorNameTF = new JTextField(8); 183 184 setLayout(new GridBagLayout()); 185 186 add(this, "GTKColorChooserPanel.hue", hueSpinner, -1, -1); 187 add(this, "GTKColorChooserPanel.red", redSpinner, -1, -1); 188 add(this, "GTKColorChooserPanel.saturation", saturationSpinner, -1,-1); 189 add(this, "GTKColorChooserPanel.green", greenSpinner, -1, -1); 190 add(this, "GTKColorChooserPanel.value", valueSpinner, -1, -1); 191 add(this, "GTKColorChooserPanel.blue", blueSpinner, -1, -1); 192 193 add(new JSeparator(SwingConstants.HORIZONTAL), new 194 GridBagConstraints(1, 3, 4, 1, 1, 0, 195 GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, 196 new Insets(14, 0, 0, 0), 0, 0)); 197 198 add(this, "GTKColorChooserPanel.colorName", colorNameTF, 0, 4); 199 200 add(triangle, new GridBagConstraints(0, 0, 1, 5, 0, 0, 201 GridBagConstraints.LINE_START, GridBagConstraints.NONE, 202 new Insets(14, 20, 2, 9), 0, 0)); 203 204 Box hBox = Box.createHorizontalBox(); 205 hBox.add(lastLabel); 206 hBox.add(label); 207 add(hBox, new GridBagConstraints(0, 5, 1, 1, 0, 0, 208 GridBagConstraints.CENTER, GridBagConstraints.NONE, 209 new Insets(0, 0, 0, 0), 0, 0)); 210 211 add(new JSeparator(SwingConstants.HORIZONTAL), new 212 GridBagConstraints(0, 6, 5, 1, 1, 0, 213 GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, 214 new Insets(12, 0, 0, 0), 0, 0)); 215 } 216 217 220 private void configureSpinner(JSpinner spinner, String name) { 221 spinner.addChangeListener(this); 222 spinner.setName(name); 223 JComponent editor = spinner.getEditor(); 224 if (editor instanceof JSpinner.DefaultEditor) { 225 JFormattedTextField ftf = ((JSpinner.DefaultEditor)editor). 226 getTextField(); 227 228 ftf.setFocusLostBehavior(JFormattedTextField.COMMIT_OR_REVERT); 229 } 230 } 231 232 235 private void add(Container parent, String key, JComponent widget, 236 int x, int y) { 237 JLabel label = new JLabel(UIManager.getString(key + "Text", 238 getLocale())); 239 String mnemonic = (String )UIManager.get(key + "Mnemonic", getLocale()); 240 241 if (mnemonic != null) { 242 try { 243 label.setDisplayedMnemonic(Integer.parseInt(mnemonic)); 244 } catch (NumberFormatException nfe) { 245 } 246 String mnemonicIndex = (String )UIManager.get(key + "MnemonicIndex", 247 getLocale()); 248 249 if (mnemonicIndex != null) { 250 try { 251 label.setDisplayedMnemonicIndex(Integer.parseInt( 252 mnemonicIndex)); 253 } catch (NumberFormatException nfe) { 254 } 255 } 256 } 257 label.setLabelFor(widget); 258 if (x < 0) { 259 x = parent.getComponentCount() % 4; 260 } 261 if (y < 0) { 262 y = parent.getComponentCount() / 4; 263 } 264 GridBagConstraints con = new GridBagConstraints(x + 1, y, 1, 1, 0, 0, 265 GridBagConstraints.FIRST_LINE_END, GridBagConstraints.NONE, 266 new Insets(4, 0, 0, 4), 0, 0); 267 if (y == 0) { 268 con.insets.top = 14; 269 } 270 parent.add(label, con); 271 con.gridx++; 272 parent.add(widget, con); 273 } 274 275 278 public void updateChooser() { 279 if (!settingColor) { 280 lastLabel.setBackground(getColorFromModel()); 281 setColor(getColorFromModel(), true, true, false); 282 } 283 } 284 285 288 private void setRed(int red) { 289 setRGB(red << 16 | getColor().getGreen() << 8 | getColor().getBlue()); 290 } 291 292 295 private void setGreen(int green) { 296 setRGB(getColor().getRed() << 16 | green << 8 | getColor().getBlue()); 297 } 298 299 302 private void setBlue(int blue) { 303 setRGB(getColor().getRed() << 16 | getColor().getGreen() << 8 | blue); 304 } 305 306 310 private void setHue(float hue, boolean update) { 311 setHSB(hue, saturation, brightness); 312 if (update) { 313 settingColor = true; 314 hueSpinner.setValue(new Integer ((int)(hue * 360))); 315 settingColor = false; 316 } 317 } 318 319 322 private float getHue() { 323 return hue; 324 } 325 326 329 private void setSaturation(float saturation) { 330 setHSB(hue, saturation, brightness); 331 } 332 333 336 private float getSaturation() { 337 return saturation; 338 } 339 340 343 private void setBrightness(float brightness) { 344 setHSB(hue, saturation, brightness); 345 } 346 347 350 private float getBrightness() { 351 return brightness; 352 } 353 354 358 private void setSaturationAndBrightness(float s, float b, boolean update) { 359 setHSB(hue, s, b); 360 if (update) { 361 settingColor = true; 362 saturationSpinner.setValue(new Integer ((int)(s * 255))); 363 valueSpinner.setValue(new Integer ((int)(b * 255))); 364 settingColor = false; 365 } 366 } 367 368 371 private void setRGB(int rgb) { 372 Color color = new Color(rgb); 373 374 setColor(color, false, true, true); 375 376 settingColor = true; 377 hueSpinner.setValue(new Integer ((int)(hue * 360))); 378 saturationSpinner.setValue(new Integer ((int)(saturation * 255))); 379 valueSpinner.setValue(new Integer ((int)(brightness * 255))); 380 settingColor = false; 381 } 382 383 386 private void setHSB(float h, float s, float b) { 387 Color color = Color.getHSBColor(h, s, b); 388 389 this.hue = h; 390 this.saturation = s; 391 this.brightness = b; 392 setColor(color, false, false, true); 393 394 settingColor = true; 395 redSpinner.setValue(new Integer (color.getRed())); 396 greenSpinner.setValue(new Integer (color.getGreen())); 397 blueSpinner.setValue(new Integer (color.getBlue())); 398 settingColor = false; 399 } 400 401 402 411 private void setColor(Color color, boolean updateSpinners, 412 boolean updateHSB, boolean updateModel) { 413 if (color == null) { 414 color = Color.BLACK; 415 } 416 417 settingColor = true; 418 419 if (updateHSB) { 420 float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), 421 color.getBlue(), null); 422 hue = hsb[0]; 423 saturation = hsb[1]; 424 brightness = hsb[2]; 425 } 426 427 if (updateModel) { 428 getColorSelectionModel().setSelectedColor(color); 429 } 430 431 triangle.setColor(hue, saturation, brightness); 432 label.setBackground(color); 433 String hexString = Integer.toHexString( 436 (color.getRGB() & 0xFFFFFF) | 0x1000000); 437 colorNameTF.setText("#" + hexString.substring(1)); 438 439 if (updateSpinners) { 440 redSpinner.setValue(new Integer (color.getRed())); 441 greenSpinner.setValue(new Integer (color.getGreen())); 442 blueSpinner.setValue(new Integer (color.getBlue())); 443 444 hueSpinner.setValue(new Integer ((int)(hue * 360))); 445 saturationSpinner.setValue(new Integer ((int)(saturation * 255))); 446 valueSpinner.setValue(new Integer ((int)(brightness * 255))); 447 } 448 settingColor = false; 449 } 450 451 public Color getColor() { 452 return label.getBackground(); 453 } 454 455 458 public void stateChanged(ChangeEvent e) { 459 if (settingColor) { 460 return; 461 } 462 Color color = getColor(); 463 464 if (e.getSource() == hueSpinner) { 465 setHue(((Number )hueSpinner.getValue()).floatValue() / 360, false); 466 } 467 else if (e.getSource() == saturationSpinner) { 468 setSaturation(((Number )saturationSpinner.getValue()). 469 floatValue() / 255); 470 } 471 else if (e.getSource() == valueSpinner) { 472 setBrightness(((Number )valueSpinner.getValue()). 473 floatValue() / 255); 474 } 475 else if (e.getSource() == redSpinner) { 476 setRed(((Number )redSpinner.getValue()).intValue()); 477 } 478 else if (e.getSource() == greenSpinner) { 479 setGreen(((Number )greenSpinner.getValue()).intValue()); 480 } 481 else if (e.getSource() == blueSpinner) { 482 setBlue(((Number )blueSpinner.getValue()).intValue()); 483 } 484 } 485 486 487 488 492 private static final int FLAGS_CHANGED_ANGLE = 1 << 0; 493 496 private static final int FLAGS_DRAGGING = 1 << 1; 497 500 private static final int FLAGS_DRAGGING_TRIANGLE = 1 << 2; 501 504 private static final int FLAGS_SETTING_COLOR = 1 << 3; 505 508 private static final int FLAGS_FOCUSED_WHEEL = 1 << 4; 509 512 private static final int FLAGS_FOCUSED_TRIANGLE = 1 << 5; 513 514 515 518 private class ColorTriangle extends JPanel { 519 522 private Image wheelImage; 523 524 527 private Image triangleImage; 528 529 532 private double angle; 533 534 537 private int flags; 538 539 542 private int circleX; 543 546 private int circleY; 547 548 549 public ColorTriangle() { 550 enableEvents(AWTEvent.FOCUS_EVENT_MASK); 551 enableEvents(AWTEvent.MOUSE_EVENT_MASK); 552 enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK); 553 554 setMinimumSize(new Dimension(getWheelRadius() * 2 + 2, 555 getWheelRadius() * 2 + 2)); 556 setPreferredSize(new Dimension(getWheelRadius() * 2 + 2, 557 getWheelRadius() * 2 + 2)); 558 559 setFocusTraversalKeysEnabled(false); 561 562 getInputMap().put(KeyStroke.getKeyStroke("UP"), "up"); 564 getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down"); 565 getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left"); 566 getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right"); 567 568 getInputMap().put(KeyStroke.getKeyStroke("KP_UP"), "up"); 569 getInputMap().put(KeyStroke.getKeyStroke("KP_DOWN"), "down"); 570 getInputMap().put(KeyStroke.getKeyStroke("KP_LEFT"), "left"); 571 getInputMap().put(KeyStroke.getKeyStroke("KP_RIGHT"), "right"); 572 573 getInputMap().put(KeyStroke.getKeyStroke("TAB"), "focusNext"); 574 getInputMap().put(KeyStroke.getKeyStroke("shift TAB"),"focusLast"); 575 576 ActionMap map = (ActionMap)UIManager.get( 577 "GTKColorChooserPanel.actionMap"); 578 579 if (map == null) { 580 map = new ActionMapUIResource(); 581 map.put("left", new ColorAction("left", 2)); 582 map.put("right", new ColorAction("right", 3)); 583 map.put("up", new ColorAction("up", 0)); 584 map.put("down", new ColorAction("down", 1)); 585 map.put("focusNext", new ColorAction("focusNext", 4)); 586 map.put("focusLast", new ColorAction("focusLast", 5)); 587 UIManager.getLookAndFeelDefaults().put( 588 "GTKColorChooserPanel.actionMap", map); 589 } 590 SwingUtilities.replaceUIActionMap(this, map); 591 } 592 593 596 GTKColorChooserPanel getGTKColorChooserPanel() { 597 return GTKColorChooserPanel.this; 598 } 599 600 603 void focusWheel() { 604 setFocusType(1); 605 } 606 607 610 void focusTriangle() { 611 setFocusType(2); 612 } 613 614 617 boolean isWheelFocused() { 618 return isSet(FLAGS_FOCUSED_WHEEL); 619 } 620 621 624 public void setColor(float h, float s, float b) { 625 if (isSet(FLAGS_SETTING_COLOR)) { 626 return; 627 } 628 629 setAngleFromHue(h); 630 setSaturationAndBrightness(s, b); 631 } 632 633 636 public Color getColor() { 637 return GTKColorChooserPanel.this.getColor(); 638 } 639 640 643 int getColorX() { 644 return circleX + getIndicatorSize() / 2 - getWheelXOrigin(); 645 } 646 647 650 int getColorY() { 651 return circleY + getIndicatorSize() / 2 - getWheelYOrigin(); 652 } 653 654 protected void processEvent(AWTEvent e) { 655 if (e.getID() == MouseEvent.MOUSE_PRESSED || 656 ((isSet(FLAGS_DRAGGING) ||isSet(FLAGS_DRAGGING_TRIANGLE)) && 657 e.getID() == MouseEvent.MOUSE_DRAGGED)) { 658 int size = getWheelRadius(); 661 int x = ((MouseEvent)e).getX() - size; 662 int y = ((MouseEvent)e).getY() - size; 663 664 if (!hasFocus()) { 665 requestFocus(); 666 } 667 if (!isSet(FLAGS_DRAGGING_TRIANGLE) && 668 adjustHue(x, y, e.getID() == MouseEvent.MOUSE_PRESSED)) { 669 setFlag(FLAGS_DRAGGING, true); 670 setFocusType(1); 671 } 672 else if (adjustSB(x, y, e.getID() == 673 MouseEvent.MOUSE_PRESSED)) { 674 setFlag(FLAGS_DRAGGING_TRIANGLE, true); 675 setFocusType(2); 676 } 677 else { 678 setFocusType(2); 679 } 680 } 681 else if (e.getID() == MouseEvent.MOUSE_RELEASED) { 682 setFlag(FLAGS_DRAGGING_TRIANGLE, false); 684 setFlag(FLAGS_DRAGGING, false); 685 } 686 else if (e.getID() == FocusEvent.FOCUS_LOST) { 687 setFocusType(0); 689 } 690 else if (e.getID() == FocusEvent.FOCUS_GAINED) { 691 if (!isSet(FLAGS_FOCUSED_TRIANGLE) && 694 !isSet(FLAGS_FOCUSED_WHEEL)) { 695 setFlag(FLAGS_FOCUSED_WHEEL, true); 696 setFocusType(1); 697 } 698 repaint(); 699 } 700 super.processEvent(e); 701 } 702 703 public void paintComponent(Graphics g) { 704 super.paintComponent(g); 705 706 int size = getWheelRadius(); 708 int width = getWheelWidth(); 709 Image image = getImage(size); 710 g.drawImage(image, getWheelXOrigin() - size, 711 getWheelYOrigin() - size, null); 712 713 if (hasFocus() && isSet(FLAGS_FOCUSED_WHEEL)) { 715 g.setColor(Color.BLACK); 716 g.drawOval(getWheelXOrigin() - size, getWheelYOrigin() - size, 717 2 * size, 2 * size); 718 g.drawOval(getWheelXOrigin() - size + width, getWheelYOrigin()- 719 size + width, 2 * (size - width), 2 * 720 (size - width)); 721 } 722 723 if (Math.toDegrees(Math.PI * 2 - angle) <= 20 || 725 Math.toDegrees(Math.PI * 2 - angle) >= 201) { 726 g.setColor(Color.WHITE); 727 } 728 else { 729 g.setColor(Color.BLACK); 730 } 731 int lineX0 = (int)(Math.cos(angle) * size); 732 int lineY0 = (int)(Math.sin(angle) * size); 733 int lineX1 = (int)(Math.cos(angle) * (size - width)); 734 int lineY1 = (int)(Math.sin(angle) * (size - width)); 735 g.drawLine(lineX0 + size, lineY0 + size, lineX1 + size, 736 lineY1 + size); 737 738 if (hasFocus() && isSet(FLAGS_FOCUSED_TRIANGLE)) { 740 Graphics g2 = g.create(); 741 int innerR = getTriangleCircumscribedRadius(); 742 int a = (int)(3 * innerR / Math.sqrt(3)); 743 g2.translate(getWheelXOrigin(), getWheelYOrigin()); 744 ((Graphics2D)g2).rotate(angle + Math.PI / 2); 745 g2.setColor(Color.BLACK); 746 g2.drawLine(0, -innerR, a / 2, innerR / 2); 747 g2.drawLine(a / 2, innerR / 2, -a / 2, innerR / 2); 748 g2.drawLine(-a / 2, innerR / 2, 0, -innerR); 749 g2.dispose(); 750 } 751 752 g.setColor(Color.BLACK); 754 g.drawOval(circleX, circleY, getIndicatorSize() - 1, 755 getIndicatorSize() - 1); 756 g.setColor(Color.WHITE); 757 g.drawOval(circleX + 1, circleY + 1, getIndicatorSize() - 3, 758 getIndicatorSize() - 3); 759 } 760 761 764 private Image getImage(int size) { 765 if (!isSet(FLAGS_CHANGED_ANGLE) && wheelImage != null && 766 wheelImage.getWidth(null) == size * 2) { 767 return wheelImage; 768 } 769 if (wheelImage == null || wheelImage.getWidth(null) != size) { 770 wheelImage = getWheelImage(size); 771 } 772 int innerR = getTriangleCircumscribedRadius(); 773 int triangleSize = (int)(innerR * 3.0 / 2.0); 774 int a = (int)(2 * triangleSize / Math.sqrt(3)); 775 if (triangleImage == null || triangleImage.getWidth(null) != a) { 776 triangleImage = new BufferedImage(a, a, 777 BufferedImage.TYPE_INT_ARGB); 778 } 779 Graphics g = triangleImage.getGraphics(); 780 g.setColor(new Color(0, 0, 0, 0)); 781 g.fillRect(0, 0, a, a); 782 g.translate((int)(a / 2), 0); 783 paintTriangle(g, triangleSize, getColor()); 784 g.translate((int)(-a / 2), 0); 785 g.dispose(); 786 787 g = wheelImage.getGraphics(); 788 g.setColor(new Color(0, 0, 0, 0)); 789 g.fillOval(getWheelWidth(), getWheelWidth(), 790 2 * (size - getWheelWidth()), 791 2 * (size - getWheelWidth())); 792 793 double rotate = Math.toRadians(-30.0) + angle; 794 g.translate(size, size); 795 ((Graphics2D)g).rotate(rotate); 796 g.drawImage(triangleImage, -a / 2, 797 getWheelWidth() - size, null); 798 ((Graphics2D)g).rotate(-rotate); 799 g.translate(a / 2, size - getWheelWidth()); 800 801 setFlag(FLAGS_CHANGED_ANGLE, false); 802 803 return wheelImage; 804 } 805 806 private void paintTriangle(Graphics g, int size, Color color) { 807 float[] colors = Color.RGBtoHSB(color.getRed(), 808 color.getGreen(), 809 color.getBlue(), null); 810 float hue = colors[0]; 811 double dSize = (double)size; 812 for (int y = 0; y < size; y++) { 813 int maxX = (int)(y * Math.tan(Math.toRadians(30.0))); 814 float factor = maxX * 2; 815 if (maxX > 0) { 816 float value = (float)(y / dSize); 817 for (int x = -maxX; x <= maxX; x++) { 818 float saturation = (float)x / factor + .5f; 819 g.setColor(Color.getHSBColor(hue, saturation, value)); 820 g.fillRect(x, y, 1, 1); 821 } 822 } 823 else { 824 g.setColor(color); 825 g.fillRect(0, y, 1, 1); 826 } 827 } 828 } 829 830 836 private Image getWheelImage(int size) { 837 int minSize = size - getWheelWidth(); 838 int doubleSize = size * 2; 839 BufferedImage image = new BufferedImage(doubleSize, doubleSize, 840 BufferedImage.TYPE_INT_ARGB); 841 842 for (int y = -size; y < size; y++) { 843 int ySquared = y * y; 844 for (int x = -size; x < size; x++) { 845 double rad = Math.sqrt(ySquared + x * x); 846 847 if (rad < size && rad > minSize) { 848 int rgb = colorWheelLocationToRGB(x, y, rad) | 849 0xFF000000; 850 image.setRGB(x + size, y + size, rgb); 851 } 852 } 853 } 854 wheelImage = image; 855 return wheelImage; 856 } 857 858 870 boolean adjustSB(int x, int y, boolean checkLoc) { 871 int innerR = getWheelRadius() - getWheelWidth(); 872 boolean resetXY = false; 873 y = -y; 875 if (checkLoc && (x < -innerR || x > innerR || y < -innerR || 876 y > innerR)) { 877 return false; 878 } 879 int triangleSize = (int)innerR * 3 / 2; 881 double x1 = Math.cos(angle) * x - Math.sin(angle) * y; 882 double y1 = Math.sin(angle) * x + Math.cos(angle) * y; 883 if (x1 < -(innerR / 2)) { 884 if (checkLoc) { 885 return false; 886 } 887 x1 = -innerR / 2; 888 resetXY = true; 889 } 890 else if ((int)x1 > innerR) { 891 if (checkLoc) { 892 return false; 893 } 894 x1 = innerR; 895 resetXY = true; 896 } 897 int maxY = (int)((triangleSize - x1 - innerR / 2.0) * 899 Math.tan(Math.toRadians(30.0))); 900 if (y1 <= -maxY) { 901 if (checkLoc) { 902 return false; 903 } 904 y1 = -maxY; 905 resetXY = true; 906 } 907 else if (y1 > maxY) { 908 if (checkLoc) { 909 return false; 910 } 911 y1 = maxY; 912 resetXY = true; 913 } 914 double x2 = Math.cos(Math.toRadians(-30.0)) * x1 - 916 Math.sin(Math.toRadians(-30.0)) * y1; 917 double y2 = Math.sin(Math.toRadians(-30.0)) * x1 + 918 Math.cos(Math.toRadians(-30.0)) * y1; 919 float value = Math.min(1.0f, (float)((innerR - y2) / 920 (double)triangleSize)); 921 float maxX = (float)(Math.tan(Math.toRadians(30)) * (innerR - y2)); 922 float saturation = Math.min(1.0f, (float)(x2 / maxX / 2 + .5)); 923 924 setFlag(FLAGS_SETTING_COLOR, true); 925 if (resetXY) { 926 setSaturationAndBrightness(saturation, value); 927 } 928 else { 929 setSaturationAndBrightness(saturation, value, x + 930 getWheelXOrigin(),getWheelYOrigin() - y); 931 } 932 GTKColorChooserPanel.this.setSaturationAndBrightness(saturation, 933 value, true); 934 setFlag(FLAGS_SETTING_COLOR, false); 935 return true; 936 } 937 938 941 private void setSaturationAndBrightness(float s, float b) { 942 int innerR = getTriangleCircumscribedRadius(); 943 int triangleSize = (int)innerR * 3 / 2; 944 double x = b * triangleSize; 945 double maxY = x * Math.tan(Math.toRadians(30.0)); 946 double y = 2 * maxY * s - maxY; 947 x = x - innerR; 948 double x1 = Math.cos(Math.toRadians(-60.0) - angle) * 949 x - Math.sin(Math.toRadians(-60.0) - angle) * y; 950 double y1 = Math.sin(Math.toRadians(-60.0) - angle) * x + 951 Math.cos(Math.toRadians(-60.0) - angle) * y; 952 int newCircleX = (int)x1 + getWheelXOrigin(); 953 int newCircleY = getWheelYOrigin() - (int)y1; 954 955 setSaturationAndBrightness(s, b, newCircleX, newCircleY); 956 } 957 958 959 962 private void setSaturationAndBrightness(float s, float b, 963 int newCircleX, int newCircleY) { 964 newCircleX -= getIndicatorSize() / 2; 965 newCircleY -= getIndicatorSize() / 2; 966 967 int minX = Math.min(newCircleX, circleX); 968 int minY = Math.min(newCircleY, circleY); 969 970 repaint(minX, minY, Math.max(circleX, newCircleX) - minX + 971 getIndicatorSize() + 1, Math.max(circleY, newCircleY) - 972 minY + getIndicatorSize() + 1); 973 circleX = newCircleX; 974 circleY = newCircleY; 975 } 976 977 989 private boolean adjustHue(int x, int y, boolean check) { 990 double rad = Math.sqrt(x * x + y * y); 991 int size = getWheelRadius(); 992 993 if (!check || (rad >= size - getWheelWidth() && rad < size)) { 994 double angle; 996 if (x == 0) { 997 if (y > 0) { 998 angle = Math.PI / 2.0; 999 } 1000 else { 1001 angle = Math.PI + Math.PI / 2.0; 1002 } 1003 } 1004 else { 1005 angle = Math.atan((double)y / (double)x); 1006 if (x < 0) { 1007 angle += Math.PI; 1008 } 1009 else if (angle < 0) { 1010 angle += 2 * Math.PI; 1011 } 1012 } 1013 setFlag(FLAGS_SETTING_COLOR, true); 1014 setHue((float)(1.0 - angle / Math.PI / 2), true); 1015 setFlag(FLAGS_SETTING_COLOR, false); 1016 setHueAngle(angle); 1017 setSaturationAndBrightness(getSaturation(), getBrightness()); 1018 return true; 1019 } 1020 return false; 1021 } 1022 1023 1026 private void setAngleFromHue(float hue) { 1027 setHueAngle((1.0 - hue) * Math.PI * 2); 1028 } 1029 1030 1033 private void setHueAngle(double angle) { 1034 double oldAngle = this.angle; 1035 1036 this.angle = angle; 1037 if (angle != oldAngle) { 1038 setFlag(FLAGS_CHANGED_ANGLE, true); 1039 repaint(); 1040 } 1041 } 1042 1043 1046 private int getIndicatorSize() { 1047 return 8; 1048 } 1049 1050 1053 private int getTriangleCircumscribedRadius() { 1054 return 72; 1055 } 1056 1057 1060 private int getWheelXOrigin() { 1061 return 85; 1062 } 1063 1064 1067 private int getWheelYOrigin() { 1068 return 85; 1069 } 1070 1071 1074 private int getWheelWidth() { 1075 return 13; 1076 } 1077 1078 1081 private void setFocusType(int type) { 1082 if (type == 0) { 1083 setFlag(FLAGS_FOCUSED_WHEEL, false); 1084 setFlag(FLAGS_FOCUSED_TRIANGLE, false); 1085 repaint(); 1086 } 1087 else { 1088 int toSet = FLAGS_FOCUSED_WHEEL; 1089 int toUnset = FLAGS_FOCUSED_TRIANGLE; 1090 1091 if (type == 2) { 1092 toSet = FLAGS_FOCUSED_TRIANGLE; 1093 toUnset = FLAGS_FOCUSED_WHEEL; 1094 } 1095 if (!isSet(toSet)) { 1096 setFlag(toSet, true); 1097 repaint(); 1098 setFlag(toUnset, false); 1099 } 1100 } 1101 } 1102 1103 1106 private int getWheelRadius() { 1107 return 85; 1110 } 1111 1112 1115 private void setFlag(int flag, boolean value) { 1116 if (value) { 1117 flags |= flag; 1118 } 1119 else { 1120 flags &= ~flag; 1121 } 1122 } 1123 1124 1127 private boolean isSet(int flag) { 1128 return ((flags & flag) == flag); 1129 } 1130 1131 1141 private int colorWheelLocationToRGB(int x, int y, double rad) { 1142 double angle = Math.acos((double)x / rad); 1143 int rgb; 1144 1145 if (angle < PI_3) { 1146 if (y < 0) { 1147 rgb = 0xFF0000 | (int)Math.min(255, 1149 (int)(255 * angle / PI_3)) << 8; 1150 } 1151 else { 1152 rgb = 0xFF0000 | (int)Math.min(255, 1154 (int)(255 * angle / PI_3)); 1155 } 1156 } 1157 else if (angle < 2 * PI_3) { 1158 angle -= PI_3; 1159 if (y < 0) { 1160 rgb = 0x00FF00 | (int)Math.max(0, 255 - 1162 (int)(255 * angle / PI_3)) << 16; 1163 } 1164 else { 1165 rgb = 0x0000FF | (int)Math.max(0, 255 - 1167 (int)(255 * angle / PI_3)) << 16; 1168 } 1169 } 1170 else { 1171 angle -= 2 * PI_3; 1172 if (y < 0) { 1173 rgb = 0x00FF00 | (int)Math.min(255, 1175 (int)(255 * angle / PI_3)); 1176 } 1177 else { 1178 rgb = 0x0000FF | (int)Math.min(255, 1180 (int)(255 * angle / PI_3)) << 8; 1181 } 1182 } 1183 return rgb; 1184 } 1185 1186 1189 void incrementHue(boolean positive) { 1190 float hue = triangle.getGTKColorChooserPanel().getHue(); 1191 1192 if (positive) { 1193 hue += 1.0f / 360.0f; 1194 } 1195 else { 1196 hue -= 1.0f / 360.0f; 1197 } 1198 if (hue > 1) { 1199 hue -= 1; 1200 } 1201 else if (hue < 0) { 1202 hue += 1; 1203 } 1204 getGTKColorChooserPanel().setHue(hue, true); 1205 } 1206 } 1207 1208 1209 1212 private static class ColorAction extends AbstractAction { 1213 private int type; 1214 1215 ColorAction(String name, int type) { 1216 super(name); 1217 this.type = type; 1218 } 1219 1220 public void actionPerformed(ActionEvent e) { 1221 ColorTriangle triangle = (ColorTriangle)e.getSource(); 1222 1223 if (triangle.isWheelFocused()) { 1224 float hue = triangle.getGTKColorChooserPanel().getHue(); 1225 1226 switch (type) { 1227 case 0: 1228 case 2: 1229 triangle.incrementHue(true); 1230 break; 1231 case 1: 1232 case 3: 1233 triangle.incrementHue(false); 1234 break; 1235 case 4: 1236 triangle.focusTriangle(); 1237 break; 1238 case 5: 1239 compositeRequestFocus(triangle, false); 1240 break; 1241 } 1242 } 1243 else { 1244 int xDelta = 0; 1245 int yDelta = 0; 1246 1247 switch (type) { 1248 case 0: 1249 yDelta--; 1251 break; 1252 case 1: 1253 yDelta++; 1255 break; 1256 case 2: 1257 xDelta--; 1259 break; 1260 case 3: 1261 xDelta++; 1263 break; 1264 case 4: 1265 compositeRequestFocus(triangle, true); 1266 return; 1267 case 5: 1268 triangle.focusWheel(); 1269 return; 1270 } 1271 triangle.adjustSB(triangle.getColorX() + xDelta, 1272 triangle.getColorY() + yDelta, true); 1273 } 1274 } 1275 } 1276 1277 1278 private class OpaqueLabel extends JLabel { 1279 public boolean isOpaque() { 1280 return true; 1281 } 1282 } 1283} 1284 | Popular Tags |