1 /* DefaultHSBChooserPanel.java -- 2 Copyright (C) 2004, 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package javax.swing.colorchooser; 40 41 import java.awt.BorderLayout; 42 import java.awt.Color; 43 import java.awt.Container; 44 import java.awt.Dimension; 45 import java.awt.Graphics; 46 import java.awt.GridLayout; 47 import java.awt.Image; 48 import java.awt.Point; 49 import java.awt.event.MouseAdapter; 50 import java.awt.event.MouseEvent; 51 import java.awt.event.MouseMotionListener; 52 import java.awt.image.MemoryImageSource; 53 54 import javax.swing.AbstractButton; 55 import javax.swing.ButtonGroup; 56 import javax.swing.Icon; 57 import javax.swing.JColorChooser; 58 import javax.swing.JLabel; 59 import javax.swing.JPanel; 60 import javax.swing.JRadioButton; 61 import javax.swing.JSlider; 62 import javax.swing.JSpinner; 63 import javax.swing.SpinnerNumberModel; 64 import javax.swing.SwingConstants; 65 import javax.swing.event.ChangeEvent; 66 import javax.swing.event.ChangeListener; 67 68 /** 69 * This is the Default HSB Panel displayed in the JColorChooser. 70 */ 71 class DefaultHSBChooserPanel extends AbstractColorChooserPanel 72 { 73 /** The gradient image displayed. 74 * This is package-private to avoid an accessor method. */ 75 transient Image gradientImage; 76 77 /** The Panel that holds the gradient image. */ 78 private transient JPanel gradientPanel; 79 80 /** The track gradient image. 81 * This is package-private to avoid an accessor method. */ 82 transient Image trackImage; 83 84 /** The panel that holds the track. */ 85 private transient JPanel trackPanel; 86 87 /** The slider for the locked HSB value. 88 * This is package-private to avoid an accessor method. */ 89 transient JSlider slider; 90 91 /** The RadioButton that controls the Hue. 92 * This is package-private to avoid an accessor method. */ 93 transient JRadioButton hRadio; 94 95 /** The RadioButton that controls the Saturation. 96 * This is package-private to avoid an accessor method. */ 97 transient JRadioButton sRadio; 98 99 /** The RadioButton that controls the Brightness. 100 * This is package-private to avoid an accessor method. */ 101 transient JRadioButton bRadio; 102 103 /** The JSpinner that controls the Hue. 104 * This is package-private to avoid an accessor method. */ 105 transient JSpinner hSpinner; 106 107 /** The JSpinner that controls the Saturation. 108 * This is package-private to avoid an accessor method. */ 109 transient JSpinner sSpinner; 110 111 /** The JSpinner that controls the Brightness. 112 * This is package-private to avoid an accessor method. */ 113 transient JSpinner bSpinner; 114 115 /** The default width of the gradient image. */ 116 private static final int imgWidth = 200; 117 118 /** The default height of the gradient image. */ 119 private static final int imgHeight = 200; 120 121 /** The default width of the track gradient. */ 122 private static final int trackWidth = 30; 123 124 /** The JLabel for Red. */ 125 private static final JLabel R = new JLabel("R"); 126 127 /** The JLabel for Green. */ 128 private static final JLabel G = new JLabel("G"); 129 130 /** The JLabel for Blue. */ 131 private static final JLabel B = new JLabel("B"); 132 133 // FIXME: Should be textfields. 134 135 /** The JLabel that displays the value of Red. */ 136 private transient JLabel rFull; 137 138 /** The JLabel that displays the value of Green. */ 139 private transient JLabel gFull; 140 141 /** The JLabel that displays the value of Blue. */ 142 private transient JLabel bFull; 143 144 /** The point that is displayed in the gradient image. 145 * Package-private to avoid an accessor method. 146 */ 147 transient Point gradientPoint = new Point(); 148 149 /** 150 * This indicates that the change to the slider or point is triggered 151 * internally. 152 * This is package-private to avoid an accessor method. 153 */ 154 transient boolean internalChange = false; 155 156 /** This indicates that the change to the spinner is triggered 157 * internally. 158 * This is package-private to avoid an accessor method. */ 159 transient boolean spinnerTrigger = false; 160 161 /** This int identifies which spinner is currently locked. 162 * This is package-private to avoid an accessor method. */ 163 transient int locked = -1; 164 165 /** This value indicates that the Hue spinner is locked. */ 166 static final int HLOCKED = 0; 167 168 /** This value indicates that the Saturation spinner is locked. */ 169 static final int SLOCKED = 1; 170 171 /** This value indicates that the Brightness spinner is locked. */ 172 static final int BLOCKED = 2; 173 174 /** 175 * This method indicates that the mouse event is in the process of being 176 * handled. 177 * This is package-private to avoid an accessor method. 178 */ 179 transient boolean handlingMouse; 180 181 /** 182 * This helper class handles mouse events on the gradient image. 183 */ 184 class MainGradientMouseListener extends MouseAdapter 185 implements MouseMotionListener 186 { 187 /** 188 * This method is called when the mouse is pressed over the gradient 189 * image. The JColorChooser is then updated with new HSB values. 190 * 191 * @param e The MouseEvent. 192 */ mousePressed(MouseEvent e)193 public void mousePressed(MouseEvent e) 194 { 195 gradientPoint = e.getPoint(); 196 update(e.getPoint()); 197 } 198 199 /** 200 * This method is called when the mouse is dragged over the gradient 201 * image. The JColorChooser is then updated with the new HSB values. 202 * 203 * @param e The MouseEvent. 204 */ mouseDragged(MouseEvent e)205 public void mouseDragged(MouseEvent e) 206 { 207 Point p = e.getPoint(); 208 if (p.x < 0 || p.y < 0 || p.y > imgHeight || p.x > imgWidth) 209 return; 210 211 gradientPoint = p; 212 update(p); 213 } 214 215 /** 216 * This method is called when the mouse is moved over the gradient image. 217 * 218 * @param e The MouseEvent. 219 */ mouseMoved(MouseEvent e)220 public void mouseMoved(MouseEvent e) 221 { 222 // Do nothing. 223 } 224 225 /** 226 * This method updates the JColorChooser with the new values. 227 * 228 * @param p The Point where the MouseEvent occurred. 229 */ update(Point p)230 private void update(Point p) 231 { 232 handlingMouse = true; 233 if (hSpinner.isEnabled()) 234 updateH(p); 235 else if (sSpinner.isEnabled()) 236 updateS(p); 237 else 238 updateB(p); 239 handlingMouse = false; 240 } 241 242 /** 243 * This method updates the SB values if Hue is locked. 244 * 245 * @param p The point where the MouseEvent occurred. 246 */ updateH(Point p)247 private void updateH(Point p) 248 { 249 float s = (imgWidth - p.x * 1f) / imgWidth; 250 float b = (imgHeight - p.y * 1f) / imgHeight; 251 252 // Avoid two changes to the model by changing internalChange to true. 253 internalChange = true; 254 sSpinner.setValue(new Integer((int) (s * 100))); 255 internalChange = false; 256 bSpinner.setValue(new Integer((int) (b * 100))); 257 258 revalidate(); 259 } 260 261 /** 262 * This method updates the HB values if Saturation is locked. 263 * 264 * @param p The point where the MouseEvent occurred. 265 */ updateS(Point p)266 private void updateS(Point p) 267 { 268 float h = p.x * 1f / imgWidth; 269 float b = (imgHeight - p.y * 1f) / imgHeight; 270 271 internalChange = true; 272 hSpinner.setValue(new Integer((int) (h * 365))); 273 internalChange = false; 274 bSpinner.setValue(new Integer((int) (b * 100))); 275 276 revalidate(); 277 } 278 279 /** 280 * This method updates the HS values if Brightness is locked. 281 * 282 * @param p The point where the MouseEvent occurred. 283 */ updateB(Point p)284 private void updateB(Point p) 285 { 286 float h = p.x * 1f / imgWidth; 287 float s = (imgHeight - p.y * 1f) / imgHeight; 288 289 internalChange = true; 290 hSpinner.setValue(new Integer((int) (h * 365))); 291 internalChange = false; 292 sSpinner.setValue(new Integer((int) (s * 100))); 293 294 revalidate(); 295 } 296 } 297 298 /** 299 * This method listens for slider value changes. 300 */ 301 class SliderChangeListener implements ChangeListener 302 { 303 /** 304 * This method is called when the slider value changes. It should change 305 * the color of the JColorChooser. 306 * 307 * @param e The ChangeEvent. 308 */ stateChanged(ChangeEvent e)309 public void stateChanged(ChangeEvent e) 310 { 311 if (internalChange) 312 return; 313 314 Integer value = new Integer(slider.getValue()); 315 316 switch (locked) 317 { 318 case HLOCKED: 319 hSpinner.setValue(value); 320 break; 321 case SLOCKED: 322 sSpinner.setValue(value); 323 break; 324 case BLOCKED: 325 bSpinner.setValue(value); 326 break; 327 } 328 } 329 } 330 331 /** 332 * This helper class determines the active JSpinner. 333 */ 334 class RadioStateListener implements ChangeListener 335 { 336 /** 337 * This method is called when there is a new JRadioButton that was 338 * selected. As a result, it should activate the associated JSpinner. 339 * 340 * @param e The ChangeEvent. 341 */ stateChanged(ChangeEvent e)342 public void stateChanged(ChangeEvent e) 343 { 344 JSpinner change; 345 if (e.getSource() == hRadio) 346 { 347 locked = HLOCKED; 348 change = hSpinner; 349 } 350 else if (e.getSource() == sRadio) 351 { 352 locked = SLOCKED; 353 change = sSpinner; 354 } 355 else 356 { 357 locked = BLOCKED; 358 change = bSpinner; 359 } 360 361 change.setEnabled(((AbstractButton) e.getSource()).isSelected()); 362 updateSlider(); 363 updateTrack(); 364 updateImage(); 365 repaint(); 366 } 367 } 368 369 /** 370 * This class listens to the JSpinners for changes. 371 */ 372 class ImageScrollListener implements ChangeListener 373 { 374 /** 375 * This method is called whenever one of the JSpinner values change. The 376 * JColorChooser should be updated with the new HSB values. 377 * 378 * @param e The ChangeEvent. 379 */ stateChanged(ChangeEvent e)380 public void stateChanged(ChangeEvent e) 381 { 382 if (internalChange) 383 return; 384 385 float h = ((Number) hSpinner.getValue()).intValue() / 360f; 386 float s = ((Number) sSpinner.getValue()).intValue() / 100f; 387 float b = ((Number) bSpinner.getValue()).intValue() / 100f; 388 389 spinnerTrigger = true; 390 getColorSelectionModel().setSelectedColor(new Color(Color.HSBtoRGB(h, s, 391 b))); 392 spinnerTrigger = false; 393 394 if (! handlingMouse && slider != null && ! slider.getValueIsAdjusting()) 395 { 396 updateImage(); 397 updateTrack(); 398 } 399 repaint(); 400 } 401 } 402 403 /** 404 * Creates a new DefaultHSBChooserPanel object. 405 */ DefaultHSBChooserPanel()406 DefaultHSBChooserPanel() 407 { 408 super(); 409 } 410 411 /** 412 * This method returns the name displayed by the JColorChooser tab that 413 * holds this panel. 414 * 415 * @return The name displayed in the JColorChooser tab. 416 */ getDisplayName()417 public String getDisplayName() 418 { 419 return "HSB"; 420 } 421 422 /** 423 * This method updates the various components inside the HSBPanel (the 424 * JSpinners, the JSlider, and the gradient image point) with updated 425 * values when the JColorChooser color value changes. 426 */ updateChooser()427 public void updateChooser() 428 { 429 Color c = getColorSelectionModel().getSelectedColor(); 430 431 float[] hsbVals = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), 432 null); 433 434 internalChange = true; 435 436 if (! spinnerTrigger) 437 { 438 hSpinner.setValue(new Integer((int) (hsbVals[0] * 360))); 439 sSpinner.setValue(new Integer((int) (hsbVals[1] * 100))); 440 bSpinner.setValue(new Integer((int) (hsbVals[2] * 100))); 441 } 442 443 switch (locked) 444 { 445 case HLOCKED: 446 if (slider != null) 447 slider.setValue(((Number) hSpinner.getValue()).intValue()); 448 if (! handlingMouse) 449 { 450 gradientPoint.x = (int) ((1 451 - ((Number) sSpinner.getValue()).intValue() / 100f) * imgWidth); 452 gradientPoint.y = (int) ((1 453 - ((Number) bSpinner.getValue()).intValue() / 100f) * imgHeight); 454 } 455 break; 456 case SLOCKED: 457 if (slider != null) 458 slider.setValue(((Number) sSpinner.getValue()).intValue()); 459 if (! handlingMouse) 460 { 461 gradientPoint.x = (int) (((Number) hSpinner.getValue()).intValue() / 360f * imgWidth); 462 gradientPoint.y = (int) ((1 463 - ((Number) bSpinner.getValue()).intValue() / 100f) * imgHeight); 464 } 465 break; 466 case BLOCKED: 467 if (slider != null) 468 slider.setValue(((Number) bSpinner.getValue()).intValue()); 469 if (! handlingMouse) 470 { 471 gradientPoint.x = (int) (((Number) hSpinner.getValue()).intValue() / 360f * imgWidth); 472 gradientPoint.y = (int) ((1 473 - ((Number) sSpinner.getValue()).intValue() / 100f) * imgHeight); 474 } 475 break; 476 } 477 internalChange = false; 478 479 if (! handlingMouse && slider != null && ! slider.getValueIsAdjusting()) 480 updateImage(); 481 482 if (! handlingMouse || locked != HLOCKED) 483 updateTrack(); 484 updateTextFields(); 485 } 486 487 /** 488 * This method builds the DefaultHSBChooserPanel. 489 */ buildChooser()490 protected void buildChooser() 491 { 492 setLayout(new BorderLayout()); 493 494 add(buildRightPanel(), BorderLayout.EAST); 495 496 JPanel container = new JPanel(); 497 container.setLayout(new BorderLayout()); 498 499 gradientPanel = new JPanel() 500 { 501 public Dimension getPreferredSize() 502 { 503 return new Dimension(imgWidth, imgHeight); 504 } 505 506 public void paint(Graphics g) 507 { 508 if (gradientImage != null) 509 g.drawImage(gradientImage, 0, 0, this); 510 511 Color saved = g.getColor(); 512 g.setColor(Color.WHITE); 513 g.drawOval(gradientPoint.x - 3, gradientPoint.y - 3, 6, 6); 514 g.setColor(saved); 515 } 516 }; 517 518 MouseAdapter ml = new MainGradientMouseListener(); 519 gradientPanel.addMouseListener(ml); 520 gradientPanel.addMouseMotionListener((MouseMotionListener) ml); 521 522 trackPanel = new JPanel() 523 { 524 public Dimension getPreferredSize() 525 { 526 return new Dimension(trackWidth, imgHeight); 527 } 528 529 public void paint(Graphics g) 530 { 531 if (trackImage != null) 532 g.drawImage(trackImage, 0, 0, this); 533 } 534 }; 535 536 slider = new JSlider(); 537 slider.setPaintTrack(false); 538 slider.setPaintTicks(false); 539 540 slider.setOrientation(SwingConstants.VERTICAL); 541 542 updateSlider(); 543 544 container.add(gradientPanel, BorderLayout.WEST); 545 container.add(slider, BorderLayout.CENTER); 546 container.add(trackPanel, BorderLayout.EAST); 547 548 add(container, BorderLayout.WEST); 549 slider.addChangeListener(new SliderChangeListener()); 550 repaint(); 551 } 552 553 /** 554 * This method uninstalls the DefaultHSBPanel. 555 * 556 * @param chooser The JColorChooser to remove this panel from. 557 */ uninstallChooserPanel(JColorChooser chooser)558 public void uninstallChooserPanel(JColorChooser chooser) 559 { 560 trackImage = null; 561 gradientImage = null; 562 gradientPanel = null; 563 slider = null; 564 565 hSpinner = null; 566 sSpinner = null; 567 bSpinner = null; 568 569 hRadio = null; 570 sRadio = null; 571 bRadio = null; 572 573 removeAll(); 574 super.uninstallChooserPanel(chooser); 575 } 576 577 /** 578 * This helper method creates the right side panel (the panel with the 579 * Spinners and TextFields). 580 * 581 * @return The right side panel. 582 */ buildRightPanel()583 private Container buildRightPanel() 584 { 585 JPanel container = new JPanel(); 586 container.setLayout(new GridLayout(6, 2)); 587 588 hRadio = new JRadioButton("H"); 589 sRadio = new JRadioButton("S"); 590 bRadio = new JRadioButton("B"); 591 592 ButtonGroup group = new ButtonGroup(); 593 group.add(hRadio); 594 group.add(sRadio); 595 group.add(bRadio); 596 597 hSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 359, 1)); 598 sSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1)); 599 bSpinner = new JSpinner(new SpinnerNumberModel(100, 0, 100, 1)); 600 601 hSpinner.setEnabled(false); 602 sSpinner.setEnabled(false); 603 bSpinner.setEnabled(false); 604 605 ChangeListener cl = new RadioStateListener(); 606 ChangeListener scroll = new ImageScrollListener(); 607 608 hRadio.addChangeListener(cl); 609 sRadio.addChangeListener(cl); 610 bRadio.addChangeListener(cl); 611 612 hSpinner.addChangeListener(scroll); 613 sSpinner.addChangeListener(scroll); 614 bSpinner.addChangeListener(scroll); 615 616 hRadio.setSelected(true); 617 618 container.add(hRadio); 619 container.add(hSpinner); 620 621 container.add(sRadio); 622 container.add(sSpinner); 623 624 container.add(bRadio); 625 container.add(bSpinner); 626 627 rFull = new JLabel("red full"); 628 gFull = new JLabel("green full"); 629 bFull = new JLabel("blue full"); 630 631 container.add(R); 632 container.add(rFull); 633 634 container.add(G); 635 container.add(gFull); 636 637 container.add(B); 638 container.add(bFull); 639 640 return container; 641 } 642 643 /** 644 * This method returns the small display icon. 645 * 646 * @return The small display icon. 647 */ getSmallDisplayIcon()648 public Icon getSmallDisplayIcon() 649 { 650 return null; 651 } 652 653 /** 654 * This method returns the large display icon. 655 * 656 * @return The large display icon. 657 */ getLargeDisplayIcon()658 public Icon getLargeDisplayIcon() 659 { 660 return null; 661 } 662 663 /** 664 * This method paints the chooser panel. 665 * 666 * @param g The graphics object to paint with. 667 */ paint(Graphics g)668 public void paint(Graphics g) 669 { 670 super.paint(g); 671 } 672 673 /** 674 * This method updates the gradient image with a new one taking the Hue 675 * value as the constant. 676 */ updateHLockImage()677 private void updateHLockImage() 678 { 679 int index = 0; 680 int[] pix = new int[imgWidth * imgHeight]; 681 float hValue = ((Number) hSpinner.getValue()).intValue() / 360f; 682 683 for (int j = 0; j < imgHeight; j++) 684 for (int i = 0; i < imgWidth; i++) 685 pix[index++] = Color.HSBtoRGB(hValue, (imgWidth - i * 1f) / imgWidth, 686 (imgHeight - j * 1f) / imgHeight) 687 | (255 << 24); 688 689 gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight, 690 pix, 0, imgWidth)); 691 } 692 693 /** 694 * This method updates the gradient image with a new one taking the 695 * Brightness value as the constant. 696 */ updateBLockImage()697 private void updateBLockImage() 698 { 699 int[] pix = new int[imgWidth * imgHeight]; 700 float bValue = ((Number) bSpinner.getValue()).intValue() / 100f; 701 702 int index = 0; 703 for (int j = 0; j < imgHeight; j++) 704 for (int i = 0; i < imgWidth; i++) 705 pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth, 706 (imgHeight - j * 1f) / imgHeight, bValue) 707 | (255 << 24); 708 709 gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight, 710 pix, 0, imgWidth)); 711 } 712 713 /** 714 * This method updates the gradient image with a new one taking the 715 * Saturation value as the constant. 716 */ updateSLockImage()717 private void updateSLockImage() 718 { 719 int[] pix = new int[imgWidth * imgHeight]; 720 float sValue = ((Number) sSpinner.getValue()).intValue() / 100f; 721 722 int index = 0; 723 for (int j = 0; j < imgHeight; j++) 724 for (int i = 0; i < imgWidth; i++) 725 pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth, sValue, 726 (imgHeight - j * 1f) / imgHeight) 727 | (255 << 24); 728 gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight, 729 pix, 0, imgWidth)); 730 } 731 732 /** 733 * This method calls the appropriate method to update the gradient image 734 * depending on which HSB value is constant. 735 * This is package-private to avoid an accessor method. 736 */ updateImage()737 void updateImage() 738 { 739 switch (locked) 740 { 741 case HLOCKED: 742 updateHLockImage(); 743 break; 744 case SLOCKED: 745 updateSLockImage(); 746 break; 747 case BLOCKED: 748 updateBLockImage(); 749 break; 750 } 751 } 752 753 /** 754 * This method updates the TextFields with the correct RGB values. 755 */ updateTextFields()756 private void updateTextFields() 757 { 758 int c = getColorSelectionModel().getSelectedColor().getRGB(); 759 760 rFull.setText("" + (c >> 16 & 0xff)); 761 gFull.setText("" + (c >> 8 & 0xff)); 762 bFull.setText("" + (c & 0xff)); 763 764 repaint(); 765 } 766 767 /** 768 * This method updates the slider in response to making a different HSB 769 * property the constant. 770 * This is package-private to avoid an accessor method. 771 */ updateSlider()772 void updateSlider() 773 { 774 if (slider == null) 775 return; 776 777 slider.setMinimum(0); 778 if (locked == HLOCKED) 779 { 780 slider.setMaximum(359); 781 slider.setValue(((Number) hSpinner.getValue()).intValue()); 782 slider.setInverted(true); 783 } 784 else 785 { 786 slider.setMaximum(100); 787 slider.setInverted(false); 788 if (sRadio.isSelected()) 789 slider.setValue(((Number) sSpinner.getValue()).intValue()); 790 else 791 slider.setValue(((Number) bSpinner.getValue()).intValue()); 792 } 793 repaint(); 794 } 795 796 /** 797 * This method updates the track gradient image depending on which HSB 798 * property is constant. 799 * This is package-private to avoid an accessor method. 800 */ updateTrack()801 void updateTrack() 802 { 803 switch (locked) 804 { 805 case HLOCKED: 806 updateHTrack(); 807 break; 808 case SLOCKED: 809 updateSTrack(); 810 break; 811 case BLOCKED: 812 updateBTrack(); 813 break; 814 } 815 } 816 817 /** 818 * This method updates the track gradient image if the Hue value is allowed 819 * to change (according to the JRadioButtons). 820 */ updateHTrack()821 private void updateHTrack() 822 { 823 int trackIndex = 0; 824 int[] trackPix = new int[trackWidth * imgHeight]; 825 826 for (int j = 0; j < imgHeight; j++) 827 for (int i = 0; i < trackWidth; i++) 828 trackPix[trackIndex++] = Color.HSBtoRGB(j * 1f / imgHeight, 1f, 1f) 829 | (255 << 24); 830 831 trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight, 832 trackPix, 0, trackWidth)); 833 } 834 835 /** 836 * This method updates the track gradient image if the Saturation value is 837 * allowed to change (according to the JRadioButtons). 838 */ updateSTrack()839 private void updateSTrack() 840 { 841 int[] trackPix = new int[trackWidth * imgHeight]; 842 843 float hValue = ((Number) hSpinner.getValue()).intValue() / 360f; 844 float bValue = ((Number) bSpinner.getValue()).intValue() / 100f; 845 846 int trackIndex = 0; 847 for (int j = 0; j < imgHeight; j++) 848 for (int i = 0; i < trackWidth; i++) 849 trackPix[trackIndex++] = Color.HSBtoRGB(hValue, 850 (imgHeight - j * 1f) / imgHeight, 851 bValue) | (255 << 24); 852 853 trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight, 854 trackPix, 0, trackWidth)); 855 } 856 857 /** 858 * This method updates the track gradient image if the Brightness value is 859 * allowed to change (according to the JRadioButtons). 860 */ updateBTrack()861 private void updateBTrack() 862 { 863 int[] trackPix = new int[trackWidth * imgHeight]; 864 865 float hValue = ((Number) hSpinner.getValue()).intValue() / 360f; 866 float sValue = ((Number) sSpinner.getValue()).intValue() / 100f; 867 868 int trackIndex = 0; 869 for (int j = 0; j < imgHeight; j++) 870 for (int i = 0; i < trackWidth; i++) 871 trackPix[trackIndex++] = Color.HSBtoRGB(hValue, sValue, 872 (imgHeight - j * 1f) / imgHeight) 873 | (255 << 24); 874 875 trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight, 876 trackPix, 0, trackWidth)); 877 } 878 879 /** 880 * This method returns the HSB values for the currently selected color. 881 * 882 * @return The HSB values for the currently selected color. 883 */ getHSBValues()884 private float[] getHSBValues() 885 { 886 Color c = getColorFromModel(); 887 float[] f = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null); 888 return f; 889 } 890 } 891