103 }
104
105 /**
106 * {@inheritDoc}
107 *
108 * Overridden to ensure that ButtonHandler is created prior to any of
109 * the other installXXX methods, since several of them reference
110 * buttonHandler.
111 */
112 @Override
113 public void installUI(JComponent c) {
114 buttonHandler = new ButtonHandler();
115 super.installUI(c);
116 }
117
118 @Override
119 protected void installDefaults() {
120 updateStyle(comboBox);
121 }
122
123 private void updateStyle(JComboBox comboBox) {
124 SynthStyle oldStyle = style;
125 SynthContext context = getContext(comboBox, ENABLED);
126
127 style = SynthLookAndFeel.updateStyle(context, this);
128 if (style != oldStyle) {
129 padding = (Insets) style.get(context, "ComboBox.padding");
130 popupInsets = (Insets)style.get(context, "ComboBox.popupInsets");
131 useListColors = style.getBoolean(context,
132 "ComboBox.rendererUseListColors", true);
133 buttonWhenNotEditable = style.getBoolean(context,
134 "ComboBox.buttonWhenNotEditable", false);
135 pressedWhenPopupVisible = style.getBoolean(context,
136 "ComboBox.pressedWhenPopupVisible", false);
137 squareButton = style.getBoolean(context,
138 "ComboBox.squareButton", true);
139
140 if (oldStyle != null) {
141 uninstallKeyboardActions();
142 installKeyboardActions();
143 }
203 * {@inheritDoc}
204 */
205 @Override
206 public SynthContext getContext(JComponent c) {
207 return getContext(c, getComponentState(c));
208 }
209
210 private SynthContext getContext(JComponent c, int state) {
211 return SynthContext.getContext(c, style, state);
212 }
213
214 private int getComponentState(JComponent c) {
215 // currently we have a broken situation where if a developer
216 // takes the border from a JComboBox and sets it on a JTextField
217 // then the codepath will eventually lead back to this method
218 // but pass in a JTextField instead of JComboBox! In case this
219 // happens, we just return the normal synth state for the component
220 // instead of doing anything special
221 if (!(c instanceof JComboBox)) return SynthLookAndFeel.getComponentState(c);
222
223 JComboBox box = (JComboBox)c;
224 if (shouldActLikeButton()) {
225 int state = ENABLED;
226 if ((!c.isEnabled())) {
227 state = DISABLED;
228 }
229 if (buttonHandler.isPressed()) {
230 state |= PRESSED;
231 }
232 if (buttonHandler.isRollover()) {
233 state |= MOUSE_OVER;
234 }
235 if (box.isFocusOwner()) {
236 state |= FOCUSED;
237 }
238 return state;
239 } else {
240 // for editable combos the editor component has the focus not the
241 // combo box its self, so we should make the combo paint focused
242 // when its editor has focus
243 int basicState = SynthLookAndFeel.getComponentState(c);
246 basicState |= FOCUSED;
247 }
248 return basicState;
249 }
250 }
251
252 /**
253 * {@inheritDoc}
254 */
255 @Override
256 protected ComboPopup createPopup() {
257 SynthComboPopup p = new SynthComboPopup(comboBox);
258 p.addPopupMenuListener(buttonHandler);
259 return p;
260 }
261
262 /**
263 * {@inheritDoc}
264 */
265 @Override
266 protected ListCellRenderer createRenderer() {
267 return new SynthComboBoxRenderer();
268 }
269
270 /**
271 * {@inheritDoc}
272 */
273 @Override
274 protected ComboBoxEditor createEditor() {
275 return new SynthComboBoxEditor();
276 }
277
278 //
279 // end UI Initialization
280 //======================
281
282 /**
283 * {@inheritDoc}
284 */
285 @Override
286 public void propertyChange(PropertyChangeEvent e) {
355 if ( !comboBox.isEditable() ) {
356 Rectangle r = rectangleForCurrentValue();
357 paintCurrentValue(g,r,hasFocus);
358 }
359 }
360
361 /**
362 * {@inheritDoc}
363 */
364 @Override
365 public void paintBorder(SynthContext context, Graphics g, int x,
366 int y, int w, int h) {
367 context.getPainter().paintComboBoxBorder(context, g, x, y, w, h);
368 }
369
370 /**
371 * Paints the currently selected item.
372 */
373 @Override
374 public void paintCurrentValue(Graphics g,Rectangle bounds,boolean hasFocus) {
375 ListCellRenderer renderer = comboBox.getRenderer();
376 Component c;
377
378 c = renderer.getListCellRendererComponent(
379 listBox, comboBox.getSelectedItem(), -1, false, false );
380
381 // Fix for 4238829: should lay out the JPanel.
382 boolean shouldValidate = false;
383 if (c instanceof JPanel) {
384 shouldValidate = true;
385 }
386
387 if (c instanceof UIResource) {
388 c.setName("ComboBox.renderer");
389 }
390
391 boolean force = forceOpaque && c instanceof JComponent;
392 if (force) {
393 ((JComponent)c).setOpaque(false);
394 }
395
693 * present. If so, remove the if() block
694 */
695 @Override
696 public void popupMenuCanceled(PopupMenuEvent e) {
697 if (shouldActLikeButton() || pressedWhenPopupVisible) {
698 comboBox.repaint();
699 }
700 }
701
702 @Override
703 public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
704 @Override
705 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
706 }
707
708 /**
709 * Handler for repainting combo when editor component gains/looses focus
710 */
711 private static class EditorFocusHandler implements FocusListener,
712 PropertyChangeListener {
713 private JComboBox comboBox;
714 private ComboBoxEditor editor = null;
715 private Component editorComponent = null;
716
717 private EditorFocusHandler(JComboBox comboBox) {
718 this.comboBox = comboBox;
719 editor = comboBox.getEditor();
720 if (editor != null){
721 editorComponent = editor.getEditorComponent();
722 if (editorComponent != null){
723 editorComponent.addFocusListener(this);
724 }
725 }
726 comboBox.addPropertyChangeListener("editor",this);
727 }
728
729 public void unregister(){
730 comboBox.removePropertyChangeListener(this);
731 if (editorComponent!=null){
732 editorComponent.removeFocusListener(this);
733 }
734 }
735
736 /** Invoked when a component gains the keyboard focus. */
737 public void focusGained(FocusEvent e) {
|
103 }
104
105 /**
106 * {@inheritDoc}
107 *
108 * Overridden to ensure that ButtonHandler is created prior to any of
109 * the other installXXX methods, since several of them reference
110 * buttonHandler.
111 */
112 @Override
113 public void installUI(JComponent c) {
114 buttonHandler = new ButtonHandler();
115 super.installUI(c);
116 }
117
118 @Override
119 protected void installDefaults() {
120 updateStyle(comboBox);
121 }
122
123 private void updateStyle(JComboBox<?> comboBox) {
124 SynthStyle oldStyle = style;
125 SynthContext context = getContext(comboBox, ENABLED);
126
127 style = SynthLookAndFeel.updateStyle(context, this);
128 if (style != oldStyle) {
129 padding = (Insets) style.get(context, "ComboBox.padding");
130 popupInsets = (Insets)style.get(context, "ComboBox.popupInsets");
131 useListColors = style.getBoolean(context,
132 "ComboBox.rendererUseListColors", true);
133 buttonWhenNotEditable = style.getBoolean(context,
134 "ComboBox.buttonWhenNotEditable", false);
135 pressedWhenPopupVisible = style.getBoolean(context,
136 "ComboBox.pressedWhenPopupVisible", false);
137 squareButton = style.getBoolean(context,
138 "ComboBox.squareButton", true);
139
140 if (oldStyle != null) {
141 uninstallKeyboardActions();
142 installKeyboardActions();
143 }
203 * {@inheritDoc}
204 */
205 @Override
206 public SynthContext getContext(JComponent c) {
207 return getContext(c, getComponentState(c));
208 }
209
210 private SynthContext getContext(JComponent c, int state) {
211 return SynthContext.getContext(c, style, state);
212 }
213
214 private int getComponentState(JComponent c) {
215 // currently we have a broken situation where if a developer
216 // takes the border from a JComboBox and sets it on a JTextField
217 // then the codepath will eventually lead back to this method
218 // but pass in a JTextField instead of JComboBox! In case this
219 // happens, we just return the normal synth state for the component
220 // instead of doing anything special
221 if (!(c instanceof JComboBox)) return SynthLookAndFeel.getComponentState(c);
222
223 JComboBox<?> box = (JComboBox)c;
224 if (shouldActLikeButton()) {
225 int state = ENABLED;
226 if ((!c.isEnabled())) {
227 state = DISABLED;
228 }
229 if (buttonHandler.isPressed()) {
230 state |= PRESSED;
231 }
232 if (buttonHandler.isRollover()) {
233 state |= MOUSE_OVER;
234 }
235 if (box.isFocusOwner()) {
236 state |= FOCUSED;
237 }
238 return state;
239 } else {
240 // for editable combos the editor component has the focus not the
241 // combo box its self, so we should make the combo paint focused
242 // when its editor has focus
243 int basicState = SynthLookAndFeel.getComponentState(c);
246 basicState |= FOCUSED;
247 }
248 return basicState;
249 }
250 }
251
252 /**
253 * {@inheritDoc}
254 */
255 @Override
256 protected ComboPopup createPopup() {
257 SynthComboPopup p = new SynthComboPopup(comboBox);
258 p.addPopupMenuListener(buttonHandler);
259 return p;
260 }
261
262 /**
263 * {@inheritDoc}
264 */
265 @Override
266 protected ListCellRenderer<Object> createRenderer() {
267 return new SynthComboBoxRenderer();
268 }
269
270 /**
271 * {@inheritDoc}
272 */
273 @Override
274 protected ComboBoxEditor createEditor() {
275 return new SynthComboBoxEditor();
276 }
277
278 //
279 // end UI Initialization
280 //======================
281
282 /**
283 * {@inheritDoc}
284 */
285 @Override
286 public void propertyChange(PropertyChangeEvent e) {
355 if ( !comboBox.isEditable() ) {
356 Rectangle r = rectangleForCurrentValue();
357 paintCurrentValue(g,r,hasFocus);
358 }
359 }
360
361 /**
362 * {@inheritDoc}
363 */
364 @Override
365 public void paintBorder(SynthContext context, Graphics g, int x,
366 int y, int w, int h) {
367 context.getPainter().paintComboBoxBorder(context, g, x, y, w, h);
368 }
369
370 /**
371 * Paints the currently selected item.
372 */
373 @Override
374 public void paintCurrentValue(Graphics g,Rectangle bounds,boolean hasFocus) {
375 ListCellRenderer<Object> renderer = comboBox.getRenderer();
376 Component c;
377
378 c = renderer.getListCellRendererComponent(
379 listBox, comboBox.getSelectedItem(), -1, false, false );
380
381 // Fix for 4238829: should lay out the JPanel.
382 boolean shouldValidate = false;
383 if (c instanceof JPanel) {
384 shouldValidate = true;
385 }
386
387 if (c instanceof UIResource) {
388 c.setName("ComboBox.renderer");
389 }
390
391 boolean force = forceOpaque && c instanceof JComponent;
392 if (force) {
393 ((JComponent)c).setOpaque(false);
394 }
395
693 * present. If so, remove the if() block
694 */
695 @Override
696 public void popupMenuCanceled(PopupMenuEvent e) {
697 if (shouldActLikeButton() || pressedWhenPopupVisible) {
698 comboBox.repaint();
699 }
700 }
701
702 @Override
703 public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
704 @Override
705 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
706 }
707
708 /**
709 * Handler for repainting combo when editor component gains/looses focus
710 */
711 private static class EditorFocusHandler implements FocusListener,
712 PropertyChangeListener {
713 private JComboBox<?> comboBox;
714 private ComboBoxEditor editor = null;
715 private Component editorComponent = null;
716
717 private EditorFocusHandler(JComboBox<?> comboBox) {
718 this.comboBox = comboBox;
719 editor = comboBox.getEditor();
720 if (editor != null){
721 editorComponent = editor.getEditorComponent();
722 if (editorComponent != null){
723 editorComponent.addFocusListener(this);
724 }
725 }
726 comboBox.addPropertyChangeListener("editor",this);
727 }
728
729 public void unregister(){
730 comboBox.removePropertyChangeListener(this);
731 if (editorComponent!=null){
732 editorComponent.removeFocusListener(this);
733 }
734 }
735
736 /** Invoked when a component gains the keyboard focus. */
737 public void focusGained(FocusEvent e) {
|