/* * [ColorChooser.java] * * Summary: Simple ColorChooser for AWT use. * * Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 2.9 2009-01-23 add Kanji digits to font samples */ package com.mindprod.fontshowerawt; import com.mindprod.common18.FontFactory; import java.awt.Button; import java.awt.Choice; import java.awt.Color; import java.awt.Dialog; import java.awt.Font; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Label; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; /** * Simple ColorChooser for AWT use. *

* Reusable Dialog. Construct, then call query to trigger a pop-up and modal user * interaction. Query will return the new color selected. You can reuse the same ColorChooser Object by calling query * again. *

* Conserves RAM and time by reusing Font and Font peer objects. * * @author Roedy Green, Canadian Mind Products * @version 2.9 2009-01-23 add Kanji digits to font samples * @since 2005-08-10 */ final class ColorChooser extends Dialog { /** * Cancel request to change colour, undoes selection */ private final Button cancel; /** * OK to select colour */ private final Button ok; /** * decimal value for blue */ private final Choice blueDecimalChoice; /** * hex value for blue */ private final Choice blueHexChoice; /** * decimal value for green */ private final Choice greenDecimalChoice; /** * hex value for green */ private final Choice greenHexChoice; /** * hex value for red */ private final Choice redDecimalChoice; /** * hex value for red */ private final Choice redHexChoice; /** * label for blue */ private final Label blueLabel; /** * "decimal" */ private final Label decimalLabel; /** * label for green */ private final Label greenLabel; /** * "hex" */ private final Label hexLabel; /** * label for red */ private final Label redLabel; /** * colour swatch */ private final TextArea colorSwatch; /** * dddd */ private final TextField decimalValue; /** * #hhhh */ private final TextField hexValue; /** * original color selection before we started meddling */ private Color originalColor; /** * color the user chose */ private Color selectedColor; /** * true if choosing foreground colour */ private boolean choosingForeground; /** * constructor * * @param owner enclosing frame, unfortuately Applet is a panel, not a Frame. Chase parents to get the Frame. */ public ColorChooser( Frame owner ) { super( owner, "Choose Color", true ); decimalLabel = new Label( "Decimal", Label.LEFT ); hexLabel = new Label( "Hex", Label.RIGHT ); redDecimalChoice = new Choice(); greenDecimalChoice = new Choice(); blueDecimalChoice = new Choice(); for ( int i = 0; i <= 255; i++ ) { String decimal = Integer.toString( i ); redDecimalChoice.addItem( decimal ); greenDecimalChoice.addItem( decimal ); blueDecimalChoice.addItem( decimal ); } ItemListener theDecimalListener = new ItemListener() { public void itemStateChanged( ItemEvent e ) { int red = redDecimalChoice.getSelectedIndex(); int green = greenDecimalChoice.getSelectedIndex(); int blue = blueDecimalChoice.getSelectedIndex(); selectedColor = new Color( red, green, blue ); displayColorSwatch(); } }; redDecimalChoice.addItemListener( theDecimalListener ); greenDecimalChoice.addItemListener( theDecimalListener ); blueDecimalChoice.addItemListener( theDecimalListener ); redLabel = new Label( "Red", Label.CENTER ); redLabel.setForeground( Color.white ); redLabel.setBackground( Color.red ); greenLabel = new Label( "Green", Label.CENTER ); greenLabel.setForeground( Color.white ); greenLabel.setBackground( new Color( 0x009900 ) );// darken green a // bit blueLabel = new Label( "Blue", Label.CENTER ); blueLabel.setForeground( Color.white ); blueLabel.setBackground( Color.blue ); redHexChoice = new Choice(); greenHexChoice = new Choice(); blueHexChoice = new Choice(); for ( int i = 0; i <= 0xff; i++ ) { String hex = Integer.toHexString( i + 0x100 ).substring( 1 ); redHexChoice.addItem( hex ); greenHexChoice.addItem( hex ); blueHexChoice.addItem( hex ); } ItemListener theHexListener = new ItemListener() { public void itemStateChanged( ItemEvent e ) { int red = redHexChoice.getSelectedIndex(); int green = greenHexChoice.getSelectedIndex(); int blue = blueHexChoice.getSelectedIndex(); selectedColor = new Color( red, green, blue ); displayColorSwatch(); } }; redHexChoice.addItemListener( theHexListener ); greenHexChoice.addItemListener( theHexListener ); blueHexChoice.addItemListener( theHexListener ); decimalValue = new TextField( "16777215" ); decimalValue.setFont( FontFactory.build( "Dialog", Font.PLAIN, 15 ) ); // no such things as right justify is AWT with TextField. hexValue = new TextField( "#ffffff" ); hexValue.setFont( FontFactory.build( "Dialog", Font.PLAIN, 15 ) ); colorSwatch = new TextArea( "The quick brown fox jumps\n" + "over the lazy dog's back.", 2, 25, TextArea.SCROLLBARS_NONE ); colorSwatch.setEditable( false ); ok = new Button( "OK" ); ok.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // selectedColor has our choice ColorChooser.this.dispose(); } } ); cancel = new Button( "Cancel" ); cancel.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // backout to what we started with. selectedColor = originalColor; ColorChooser.this.dispose(); } } ); this.addWindowListener( new WindowAdapter() { /** * Handle request to close Dialog. * @param e event giving details of closing. */ public void windowClosing( WindowEvent e ) { // backout to what we started with. selectedColor = originalColor; ColorChooser.this.dispose(); } } ); this.setLayout( new GridBagLayout() ); // ---0--1-2------3---- // 0 decimal----- hex 0 // 1 rd-- red---- rh -1 // 2 gd-- green-- gh -2 // 3 bd-- blue--- bh -3 // 4 ddddd---- #xxxxx-4 // 5 ---swatch------ -5 // 6 ok -- -- -cancel-6 // x y w h wtx wty anchor fill T L B R padx pady this.add( decimalLabel, new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 10, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( hexLabel, new GridBagConstraints( 3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 10, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( redDecimalChoice, new GridBagConstraints( 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( redLabel, new GridBagConstraints( 1, 1, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 5, 20, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( redHexChoice, new GridBagConstraints( 3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( greenDecimalChoice, new GridBagConstraints( 0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( greenLabel, new GridBagConstraints( 1, 2, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 5, 20, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( greenHexChoice, new GridBagConstraints( 3, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( blueDecimalChoice, new GridBagConstraints( 0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( blueLabel, new GridBagConstraints( 1, 3, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 5, 20, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( blueHexChoice, new GridBagConstraints( 3, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( decimalValue, new GridBagConstraints( 0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( hexValue, new GridBagConstraints( 3, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( colorSwatch, new GridBagConstraints( 0, 5, 4, 1, 50.0, 50.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 10, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( ok, new GridBagConstraints( 0, 6, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 10, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady this.add( cancel, new GridBagConstraints( 2, 6, 2, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 10, 10 ), 0, 0 ) ); this.pack(); } // end constructor /** * change the colour of the display swatch to reflect the recent color change. */ private void displayColorSwatch() { redDecimalChoice.select( selectedColor.getRed() ); greenDecimalChoice.select( selectedColor.getGreen() ); blueDecimalChoice.select( selectedColor.getBlue() ); redHexChoice.select( selectedColor.getRed() ); greenHexChoice.select( selectedColor.getGreen() ); blueHexChoice.select( selectedColor.getBlue() ); int rgb = selectedColor.getRGB() & 0xffffff; decimalValue.setText( Integer.toString( rgb ) ); // pad with lead zeros as necessary hexValue.setText( '#' + Integer.toHexString( rgb + 0x1000000 ) .substring( 1 ) ); if ( choosingForeground ) { colorSwatch.setForeground( selectedColor ); } else { colorSwatch.setBackground( selectedColor ); } this.validate(); colorSwatch.repaint(); } /** * query user which color he wants. * * @param chooseForeground true if want to choose the forground colour, false if the background. * @param originalBackground background before user changes it. * @param originalForeground foreground before user changes it. * * @return new color selected. Will match original selection if hits CANCEL. */ public Color query( boolean chooseForeground, Color originalBackground, Color originalForeground ) { this.choosingForeground = chooseForeground; if ( choosingForeground ) { this.selectedColor = originalForeground; this.originalColor = originalForeground; setTitle( "Choose Foreground Color" ); } else { this.selectedColor = originalBackground; this.originalColor = originalBackground; setTitle( "Choose Background Color" ); } colorSwatch.setForeground( originalForeground ); colorSwatch.setBackground( originalBackground ); displayColorSwatch(); // won't return from setVisible until entire dialog exchange is complete // which many consist of many selections before hitting OK or cancel. setVisible( true ); return selectedColor; } }