| /* |
| * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Sun designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Sun in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| * CA 95054 USA or visit www.sun.com if you need additional information or |
| * have any questions. |
| */ |
| |
| package javax.swing.plaf.synth; |
| |
| import java.awt.*; |
| import java.awt.event.*; |
| import java.lang.reflect.*; |
| import javax.swing.*; |
| import javax.accessibility.*; |
| import javax.swing.FocusManager; |
| import javax.swing.plaf.*; |
| import javax.swing.border.*; |
| import javax.swing.text.*; |
| import javax.swing.event.*; |
| import javax.swing.plaf.basic.*; |
| import java.beans.PropertyChangeListener; |
| import java.beans.PropertyChangeEvent; |
| import sun.awt.AppContext; |
| import sun.swing.plaf.synth.SynthUI; |
| |
| /** |
| * Synth's ComboBoxUI. |
| * |
| * @author Scott Violet |
| */ |
| class SynthComboBoxUI extends BasicComboBoxUI implements |
| PropertyChangeListener, SynthUI { |
| private SynthStyle style; |
| private boolean useListColors; |
| |
| public static ComponentUI createUI(JComponent c) { |
| return new SynthComboBoxUI(); |
| } |
| |
| protected void installDefaults() { |
| updateStyle(comboBox); |
| } |
| |
| private void updateStyle(JComboBox comboBox) { |
| SynthStyle oldStyle = style; |
| SynthContext context = getContext(comboBox, ENABLED); |
| |
| style = SynthLookAndFeel.updateStyle(context, this); |
| if (style != oldStyle) { |
| useListColors = style.getBoolean(context, |
| "ComboBox.rendererUseListColors", true); |
| if (oldStyle != null) { |
| uninstallKeyboardActions(); |
| installKeyboardActions(); |
| } |
| } |
| context.dispose(); |
| |
| if(listBox != null) { |
| SynthLookAndFeel.updateStyles(listBox); |
| } |
| } |
| |
| protected void installListeners() { |
| comboBox.addPropertyChangeListener(this); |
| super.installListeners(); |
| } |
| |
| protected void uninstallDefaults() { |
| SynthContext context = getContext(comboBox, ENABLED); |
| |
| style.uninstallDefaults(context); |
| context.dispose(); |
| style = null; |
| } |
| |
| protected void uninstallListeners() { |
| comboBox.removePropertyChangeListener(this); |
| super.uninstallListeners(); |
| } |
| |
| public SynthContext getContext(JComponent c) { |
| return getContext(c, getComponentState(c)); |
| } |
| |
| private SynthContext getContext(JComponent c, int state) { |
| return SynthContext.getContext(SynthContext.class, c, |
| SynthLookAndFeel.getRegion(c), style, state); |
| } |
| |
| private Region getRegion(JComponent c) { |
| return SynthLookAndFeel.getRegion(c); |
| } |
| |
| private int getComponentState(JComponent c) { |
| return SynthLookAndFeel.getComponentState(c); |
| } |
| |
| protected ComboPopup createPopup() { |
| SynthComboPopup popup = new SynthComboPopup( comboBox ); |
| return popup; |
| } |
| |
| protected ListCellRenderer createRenderer() { |
| return new SynthComboBoxRenderer(); |
| } |
| |
| protected ComboBoxEditor createEditor() { |
| return new SynthComboBoxEditor(); |
| } |
| |
| // |
| // end UI Initialization |
| //====================== |
| |
| |
| public void propertyChange(PropertyChangeEvent e) { |
| if (SynthLookAndFeel.shouldUpdateStyle(e)) { |
| updateStyle(comboBox); |
| } |
| } |
| |
| protected JButton createArrowButton() { |
| SynthArrowButton button = new SynthArrowButton(SwingConstants.SOUTH); |
| button.setName("ComboBox.arrowButton"); |
| return button; |
| } |
| |
| //================================= |
| // begin ComponentUI Implementation |
| |
| public void update(Graphics g, JComponent c) { |
| SynthContext context = getContext(c); |
| |
| SynthLookAndFeel.update(context, g); |
| context.getPainter().paintComboBoxBackground(context, g, 0, 0, |
| c.getWidth(), c.getHeight()); |
| paint(context, g); |
| context.dispose(); |
| } |
| |
| public void paint(Graphics g, JComponent c) { |
| SynthContext context = getContext(c); |
| |
| paint(context, g); |
| context.dispose(); |
| } |
| |
| protected void paint(SynthContext context, Graphics g) { |
| hasFocus = comboBox.hasFocus(); |
| if ( !comboBox.isEditable() ) { |
| Rectangle r = rectangleForCurrentValue(); |
| paintCurrentValue(g,r,hasFocus); |
| } |
| } |
| |
| public void paintBorder(SynthContext context, Graphics g, int x, |
| int y, int w, int h) { |
| context.getPainter().paintComboBoxBorder(context, g, x, y, w, h); |
| } |
| |
| |
| /** |
| * Paints the currently selected item. |
| */ |
| public void paintCurrentValue(Graphics g,Rectangle bounds,boolean hasFocus) { |
| ListCellRenderer renderer = comboBox.getRenderer(); |
| Component c; |
| |
| if ( hasFocus && !isPopupVisible(comboBox) ) { |
| c = renderer.getListCellRendererComponent( listBox, |
| comboBox.getSelectedItem(), |
| -1, |
| false, |
| false ); |
| } |
| else { |
| c = renderer.getListCellRendererComponent( listBox, |
| comboBox.getSelectedItem(), |
| -1, |
| false, |
| false ); |
| } |
| // Fix for 4238829: should lay out the JPanel. |
| boolean shouldValidate = false; |
| if (c instanceof JPanel) { |
| shouldValidate = true; |
| } |
| |
| if (c instanceof UIResource) { |
| c.setName("ComboBox.renderer"); |
| currentValuePane.paintComponent(g,c,comboBox,bounds.x,bounds.y, |
| bounds.width,bounds.height, shouldValidate); |
| } |
| else { |
| currentValuePane.paintComponent(g,c,comboBox,bounds.x,bounds.y, |
| bounds.width,bounds.height, shouldValidate); |
| } |
| } |
| |
| /** |
| * From BasicComboBoxRenderer v 1.18. |
| */ |
| private class SynthComboBoxRenderer extends JLabel implements ListCellRenderer, UIResource { |
| public SynthComboBoxRenderer() { |
| super(); |
| setText(" "); |
| } |
| |
| public String getName() { |
| // As SynthComboBoxRenderer's are asked for a size BEFORE they |
| // are parented getName is overriden to force the name to be |
| // ComboBox.renderer if it isn't set. If we didn't do this the |
| // wrong style could be used for size calculations. |
| String name = super.getName(); |
| if (name == null) { |
| return "ComboBox.renderer"; |
| } |
| return name; |
| } |
| |
| public Component getListCellRendererComponent(JList list, Object value, |
| int index, boolean isSelected, boolean cellHasFocus) { |
| setName("ComboBox.listRenderer"); |
| SynthLookAndFeel.resetSelectedUI(); |
| if (isSelected) { |
| setBackground(list.getSelectionBackground()); |
| setForeground(list.getSelectionForeground()); |
| if (!useListColors) { |
| SynthLookAndFeel.setSelectedUI( |
| (SynthLabelUI)SynthLookAndFeel.getUIOfType(getUI(), |
| SynthLabelUI.class), isSelected, cellHasFocus, |
| list.isEnabled(), false); |
| } |
| } |
| else { |
| setBackground(list.getBackground()); |
| setForeground(list.getForeground()); |
| } |
| |
| setFont(list.getFont()); |
| |
| if (value instanceof Icon) { |
| setIcon((Icon)value); |
| setText(""); |
| } |
| else { |
| String text = (value == null) ? " " : value.toString(); |
| |
| if ("".equals(text)) { |
| text = " "; |
| } |
| setText(text); |
| } |
| |
| // The renderer component should inherit the enabled and |
| // orientation state of its parent combobox. This is |
| // especially needed for GTK comboboxes, where the |
| // ListCellRenderer's state determines the visual state |
| // of the combobox. |
| setEnabled(comboBox.isEnabled()); |
| setComponentOrientation(comboBox.getComponentOrientation()); |
| |
| return this; |
| } |
| |
| public void paint(Graphics g) { |
| super.paint(g); |
| SynthLookAndFeel.resetSelectedUI(); |
| } |
| } |
| |
| |
| /** |
| * From BasicCombBoxEditor v 1.24. |
| */ |
| private static class SynthComboBoxEditor implements |
| ComboBoxEditor, UIResource { |
| protected JTextField editor; |
| private Object oldValue; |
| |
| public SynthComboBoxEditor() { |
| editor = new JTextField("",9); |
| editor.setName("ComboBox.textField"); |
| } |
| |
| public Component getEditorComponent() { |
| return editor; |
| } |
| |
| /** |
| * Sets the item that should be edited. |
| * |
| * @param anObject the displayed value of the editor |
| */ |
| public void setItem(Object anObject) { |
| String text; |
| |
| if ( anObject != null ) { |
| text = anObject.toString(); |
| oldValue = anObject; |
| } else { |
| text = ""; |
| } |
| // workaround for 4530952 |
| if (!text.equals(editor.getText())) { |
| editor.setText(text); |
| } |
| } |
| |
| public Object getItem() { |
| Object newValue = editor.getText(); |
| |
| if (oldValue != null && !(oldValue instanceof String)) { |
| // The original value is not a string. Should return the value in it's |
| // original type. |
| if (newValue.equals(oldValue.toString())) { |
| return oldValue; |
| } else { |
| // Must take the value from the editor and get the value and cast it to the new type. |
| Class<?> cls = oldValue.getClass(); |
| try { |
| Method method = cls.getMethod("valueOf", new Class[]{String.class}); |
| newValue = method.invoke(oldValue, new Object[] { editor.getText()}); |
| } catch (Exception ex) { |
| // Fail silently and return the newValue (a String object) |
| } |
| } |
| } |
| return newValue; |
| } |
| |
| public void selectAll() { |
| editor.selectAll(); |
| editor.requestFocus(); |
| } |
| |
| public void addActionListener(ActionListener l) { |
| editor.addActionListener(l); |
| } |
| |
| public void removeActionListener(ActionListener l) { |
| editor.removeActionListener(l); |
| } |
| } |
| } |