001package com.ganteater.ae.desktop.ui; 002 003import java.awt.BorderLayout; 004import java.awt.Color; 005import java.awt.event.FocusEvent; 006import java.awt.event.FocusListener; 007 008import javax.swing.JLabel; 009import javax.swing.border.EmptyBorder; 010import javax.swing.event.DocumentEvent; 011import javax.swing.event.DocumentListener; 012import javax.swing.text.Document; 013import javax.swing.text.JTextComponent; 014 015/** 016 * The TextPrompt class will display a prompt over top of a text component when 017 * the Document of the text field is empty. The Show property is used to 018 * determine the visibility of the prompt. 019 * 020 * The Font and foreground Color of the prompt will default to those properties 021 * of the parent text component. You are free to change the properties after 022 * class construction. 023 */ 024public class TextPrompt extends JLabel 025 implements FocusListener, DocumentListener 026{ 027 public enum Show 028 { 029 ALWAYS, 030 FOCUS_GAINED, 031 FOCUS_LOST; 032 } 033 034 private JTextComponent component; 035 private Document document; 036 037 private Show show; 038 private boolean showPromptOnce; 039 private int focusLost; 040 041 public TextPrompt(String text, JTextComponent component) 042 { 043 this(text, component, Show.ALWAYS); 044 } 045 046 public TextPrompt(String text, JTextComponent component, Show show) 047 { 048 this.component = component; 049 setShow( show ); 050 document = component.getDocument(); 051 052 setText( text ); 053 setForeground( component.getForeground().brighter().brighter() ); 054 setFont( component.getFont() ); 055 setBorder( new EmptyBorder(component.getInsets()) ); 056 setHorizontalAlignment(JLabel.LEADING); 057 058 component.addFocusListener( this ); 059 document.addDocumentListener( this ); 060 061 component.setLayout( new BorderLayout() ); 062 component.add( this ); 063 checkForPrompt(); 064 } 065 066 /** 067 * Convenience method to change the alpha value of the current foreground 068 * Color to the specifice value. 069 * 070 * @param alpha value in the range of 0 - 1.0. 071 */ 072 public void changeAlpha(float alpha) 073 { 074 changeAlpha( (int)(alpha * 255) ); 075 } 076 077 /** 078 * Convenience method to change the alpha value of the current foreground 079 * Color to the specifice value. 080 * 081 * @param alpha value in the range of 0 - 255. 082 */ 083 public void changeAlpha(int alpha) 084 { 085 alpha = alpha > 255 ? 255 : alpha < 0 ? 0 : alpha; 086 087 Color foreground = getForeground(); 088 int red = foreground.getRed(); 089 int green = foreground.getGreen(); 090 int blue = foreground.getBlue(); 091 092 Color withAlpha = new Color(red, green, blue, alpha); 093 super.setForeground( withAlpha ); 094 } 095 096 /** 097 * Convenience method to change the style of the current Font. The style 098 * values are found in the Font class. Common values might be: 099 * Font.BOLD, Font.ITALIC and Font.BOLD + Font.ITALIC. 100 * 101 * @param style value representing the the new style of the Font. 102 */ 103 public void changeStyle(int style) 104 { 105 setFont( getFont().deriveFont( style ) ); 106 } 107 108 /** 109 * Get the Show property 110 * 111 * @return the Show property. 112 */ 113 public Show getShow() 114 { 115 return show; 116 } 117 118 /** 119 * Set the prompt Show property to control when the promt is shown. 120 * Valid values are: 121 * 122 * Show.AWLAYS (default) - always show the prompt 123 * Show.Focus_GAINED - show the prompt when the component gains focus 124 * (and hide the prompt when focus is lost) 125 * Show.Focus_LOST - show the prompt when the component loses focus 126 * (and hide the prompt when focus is gained) 127 * 128 * @param show a valid Show enum 129 */ 130 public void setShow(Show show) 131 { 132 this.show = show; 133 } 134 135 /** 136 * Get the showPromptOnce property 137 * 138 * @return the showPromptOnce property. 139 */ 140 public boolean getShowPromptOnce() 141 { 142 return showPromptOnce; 143 } 144 145 /** 146 * Show the prompt once. Once the component has gained/lost focus 147 * once, the prompt will not be shown again. 148 * 149 * @param showPromptOnce when true the prompt will only be shown once, 150 * otherwise it will be shown repeatedly. 151 */ 152 public void setShowPromptOnce(boolean showPromptOnce) 153 { 154 this.showPromptOnce = showPromptOnce; 155 } 156 157 /** 158 * Check whether the prompt should be visible or not. The visibility 159 * will change on updates to the Document and on focus changes. 160 */ 161 private void checkForPrompt() 162 { 163 // Text has been entered, remove the prompt 164 165 if (document.getLength() > 0) 166 { 167 setVisible( false ); 168 return; 169 } 170 171 // Prompt has already been shown once, remove it 172 173 if (showPromptOnce && focusLost > 0) 174 { 175 setVisible(false); 176 return; 177 } 178 179 // Check the Show property and component focus to determine if the 180 // prompt should be displayed. 181 182 if (component.hasFocus()) 183 { 184 if (show == Show.ALWAYS 185 || show == Show.FOCUS_GAINED) 186 setVisible( true ); 187 else 188 setVisible( false ); 189 } 190 else 191 { 192 if (show == Show.ALWAYS 193 || show == Show.FOCUS_LOST) 194 setVisible( true ); 195 else 196 setVisible( false ); 197 } 198 } 199 200// Implement FocusListener 201 202 public void focusGained(FocusEvent e) 203 { 204 checkForPrompt(); 205 } 206 207 public void focusLost(FocusEvent e) 208 { 209 focusLost++; 210 checkForPrompt(); 211 } 212 213// Implement DocumentListener 214 215 public void insertUpdate(DocumentEvent e) 216 { 217 checkForPrompt(); 218 } 219 220 public void removeUpdate(DocumentEvent e) 221 { 222 checkForPrompt(); 223 } 224 225 public void changedUpdate(DocumentEvent e) {} 226}