feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
141
jdkSrc/jdk8/javax/swing/plaf/synth/ColorType.java
Normal file
141
jdkSrc/jdk8/javax/swing/plaf/synth/ColorType.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2005, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
/**
|
||||
* A typesafe enumeration of colors that can be fetched from a style.
|
||||
* <p>
|
||||
* Each <code>SynthStyle</code> has a set of <code>ColorType</code>s that
|
||||
* are accessed by way of the
|
||||
* {@link SynthStyle#getColor(SynthContext, ColorType)} method.
|
||||
* <code>SynthStyle</code>'s <code>installDefaults</code> will install
|
||||
* the <code>FOREGROUND</code> color
|
||||
* as the foreground of
|
||||
* the Component, and the <code>BACKGROUND</code> color to the background of
|
||||
* the component (assuming that you have not explicitly specified a
|
||||
* foreground and background color). Some components
|
||||
* support more color based properties, for
|
||||
* example <code>JList</code> has the property
|
||||
* <code>selectionForeground</code> which will be mapped to
|
||||
* <code>FOREGROUND</code> with a component state of
|
||||
* <code>SynthConstants.SELECTED</code>.
|
||||
* <p>
|
||||
* The following example shows a custom <code>SynthStyle</code> that returns
|
||||
* a red Color for the <code>DISABLED</code> state, otherwise a black color.
|
||||
* <pre>
|
||||
* class MyStyle extends SynthStyle {
|
||||
* private Color disabledColor = new ColorUIResource(Color.RED);
|
||||
* private Color color = new ColorUIResource(Color.BLACK);
|
||||
* protected Color getColorForState(SynthContext context, ColorType type){
|
||||
* if (context.getComponentState() == SynthConstants.DISABLED) {
|
||||
* return disabledColor;
|
||||
* }
|
||||
* return color;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Scott Violet
|
||||
*/
|
||||
public class ColorType {
|
||||
/**
|
||||
* ColorType for the foreground of a region.
|
||||
*/
|
||||
public static final ColorType FOREGROUND = new ColorType("Foreground");
|
||||
|
||||
/**
|
||||
* ColorType for the background of a region.
|
||||
*/
|
||||
public static final ColorType BACKGROUND = new ColorType("Background");
|
||||
|
||||
/**
|
||||
* ColorType for the foreground of a region.
|
||||
*/
|
||||
public static final ColorType TEXT_FOREGROUND = new ColorType(
|
||||
"TextForeground");
|
||||
|
||||
/**
|
||||
* ColorType for the background of a region.
|
||||
*/
|
||||
public static final ColorType TEXT_BACKGROUND =new ColorType(
|
||||
"TextBackground");
|
||||
|
||||
/**
|
||||
* ColorType for the focus.
|
||||
*/
|
||||
public static final ColorType FOCUS = new ColorType("Focus");
|
||||
|
||||
/**
|
||||
* Maximum number of <code>ColorType</code>s.
|
||||
*/
|
||||
public static final int MAX_COUNT;
|
||||
|
||||
private static int nextID;
|
||||
|
||||
private String description;
|
||||
private int index;
|
||||
|
||||
static {
|
||||
MAX_COUNT = Math.max(FOREGROUND.getID(), Math.max(
|
||||
BACKGROUND.getID(), FOCUS.getID())) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ColorType with the specified description.
|
||||
*
|
||||
* @param description String description of the ColorType.
|
||||
*/
|
||||
protected ColorType(String description) {
|
||||
if (description == null) {
|
||||
throw new NullPointerException(
|
||||
"ColorType must have a valid description");
|
||||
}
|
||||
this.description = description;
|
||||
synchronized(ColorType.class) {
|
||||
this.index = nextID++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique id, as an integer, for this ColorType.
|
||||
*
|
||||
* @return a unique id, as an integer, for this ColorType.
|
||||
*/
|
||||
public final int getID() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the textual description of this <code>ColorType</code>.
|
||||
* This is the same value that the <code>ColorType</code> was created
|
||||
* with.
|
||||
*
|
||||
* @return the description of the string
|
||||
*/
|
||||
public String toString() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
209
jdkSrc/jdk8/javax/swing/plaf/synth/DefaultSynthStyleFactory.java
Normal file
209
jdkSrc/jdk8/javax/swing/plaf/synth/DefaultSynthStyleFactory.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import java.awt.Font;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
import sun.swing.plaf.synth.*;
|
||||
import sun.swing.BakedArrayList;
|
||||
|
||||
/**
|
||||
* Factory used for obtaining styles. Supports associating a style based on
|
||||
* the name of the component as returned by <code>Component.getName()</code>,
|
||||
* and the <code>Region</code> associated with the <code>JComponent</code>.
|
||||
* Lookup is done using regular expressions.
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class DefaultSynthStyleFactory extends SynthStyleFactory {
|
||||
/**
|
||||
* Used to indicate the lookup should be done based on Component name.
|
||||
*/
|
||||
public static final int NAME = 0;
|
||||
/**
|
||||
* Used to indicate the lookup should be done based on region.
|
||||
*/
|
||||
public static final int REGION = 1;
|
||||
|
||||
/**
|
||||
* List containing set of StyleAssociations used in determining matching
|
||||
* styles.
|
||||
*/
|
||||
private List<StyleAssociation> _styles;
|
||||
/**
|
||||
* Used during lookup.
|
||||
*/
|
||||
private BakedArrayList _tmpList;
|
||||
|
||||
/**
|
||||
* Maps from a List (BakedArrayList to be precise) to the merged style.
|
||||
*/
|
||||
private Map<BakedArrayList, SynthStyle> _resolvedStyles;
|
||||
|
||||
/**
|
||||
* Used if there are no styles matching a widget.
|
||||
*/
|
||||
private SynthStyle _defaultStyle;
|
||||
|
||||
|
||||
DefaultSynthStyleFactory() {
|
||||
_tmpList = new BakedArrayList(5);
|
||||
_styles = new ArrayList<StyleAssociation>();
|
||||
_resolvedStyles = new HashMap<BakedArrayList, SynthStyle>();
|
||||
}
|
||||
|
||||
public synchronized void addStyle(DefaultSynthStyle style,
|
||||
String path, int type) throws PatternSyntaxException {
|
||||
if (path == null) {
|
||||
// Make an empty path match all.
|
||||
path = ".*";
|
||||
}
|
||||
if (type == NAME) {
|
||||
_styles.add(StyleAssociation.createStyleAssociation(
|
||||
path, style, type));
|
||||
}
|
||||
else if (type == REGION) {
|
||||
_styles.add(StyleAssociation.createStyleAssociation(
|
||||
path.toLowerCase(), style, type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the style for the specified Component.
|
||||
*
|
||||
* @param c Component asking for
|
||||
* @param id ID of the Component
|
||||
*/
|
||||
public synchronized SynthStyle getStyle(JComponent c, Region id) {
|
||||
BakedArrayList matches = _tmpList;
|
||||
|
||||
matches.clear();
|
||||
getMatchingStyles(matches, c, id);
|
||||
|
||||
if (matches.size() == 0) {
|
||||
return getDefaultStyle();
|
||||
}
|
||||
// Use a cached Style if possible, otherwise create a new one.
|
||||
matches.cacheHashCode();
|
||||
SynthStyle style = getCachedStyle(matches);
|
||||
|
||||
if (style == null) {
|
||||
style = mergeStyles(matches);
|
||||
|
||||
if (style != null) {
|
||||
cacheStyle(matches, style);
|
||||
}
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the style to use if there are no matching styles.
|
||||
*/
|
||||
private SynthStyle getDefaultStyle() {
|
||||
if (_defaultStyle == null) {
|
||||
_defaultStyle = new DefaultSynthStyle();
|
||||
((DefaultSynthStyle)_defaultStyle).setFont(
|
||||
new FontUIResource(Font.DIALOG, Font.PLAIN,12));
|
||||
}
|
||||
return _defaultStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches any styles that match the passed into arguments into
|
||||
* <code>matches</code>.
|
||||
*/
|
||||
private void getMatchingStyles(List matches, JComponent c,
|
||||
Region id) {
|
||||
String idName = id.getLowerCaseName();
|
||||
String cName = c.getName();
|
||||
|
||||
if (cName == null) {
|
||||
cName = "";
|
||||
}
|
||||
for (int counter = _styles.size() - 1; counter >= 0; counter--){
|
||||
StyleAssociation sa = _styles.get(counter);
|
||||
String path;
|
||||
|
||||
if (sa.getID() == NAME) {
|
||||
path = cName;
|
||||
}
|
||||
else {
|
||||
path = idName;
|
||||
}
|
||||
|
||||
if (sa.matches(path) && matches.indexOf(sa.getStyle()) == -1) {
|
||||
matches.add(sa.getStyle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches the specified style.
|
||||
*/
|
||||
private void cacheStyle(List styles, SynthStyle style) {
|
||||
BakedArrayList cachedStyles = new BakedArrayList(styles);
|
||||
|
||||
_resolvedStyles.put(cachedStyles, style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cached style from the passed in arguments.
|
||||
*/
|
||||
private SynthStyle getCachedStyle(List styles) {
|
||||
if (styles.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return _resolvedStyles.get(styles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single Style from the passed in styles. The passed in List
|
||||
* is reverse sorted, that is the most recently added style found to
|
||||
* match will be first.
|
||||
*/
|
||||
private SynthStyle mergeStyles(List styles) {
|
||||
int size = styles.size();
|
||||
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
else if (size == 1) {
|
||||
return (SynthStyle)((DefaultSynthStyle)styles.get(0)).clone();
|
||||
}
|
||||
// NOTE: merging is done backwards as DefaultSynthStyleFactory reverses
|
||||
// order, that is, the most specific style is first.
|
||||
DefaultSynthStyle style = (DefaultSynthStyle)styles.get(size - 1);
|
||||
|
||||
style = (DefaultSynthStyle)style.clone();
|
||||
for (int counter = size - 2; counter >= 0; counter--) {
|
||||
style = ((DefaultSynthStyle)styles.get(counter)).addTo(style);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
}
|
||||
1020
jdkSrc/jdk8/javax/swing/plaf/synth/ImagePainter.java
Normal file
1020
jdkSrc/jdk8/javax/swing/plaf/synth/ImagePainter.java
Normal file
File diff suppressed because it is too large
Load Diff
2175
jdkSrc/jdk8/javax/swing/plaf/synth/ParsedSynthStyle.java
Normal file
2175
jdkSrc/jdk8/javax/swing/plaf/synth/ParsedSynthStyle.java
Normal file
File diff suppressed because it is too large
Load Diff
577
jdkSrc/jdk8/javax/swing/plaf/synth/Region.java
Normal file
577
jdkSrc/jdk8/javax/swing/plaf/synth/Region.java
Normal file
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
/**
|
||||
* A distinct rendering area of a Swing component. A component may
|
||||
* support one or more regions. Specific component regions are defined
|
||||
* by the typesafe enumeration in this class.
|
||||
* <p>
|
||||
* Regions are typically used as a way to identify the <code>Component</code>s
|
||||
* and areas a particular style is to apply to. Synth's file format allows you
|
||||
* to bind styles based on the name of a <code>Region</code>.
|
||||
* The name is derived from the field name of the constant:
|
||||
* <ol>
|
||||
* <li>Map all characters to lowercase.
|
||||
* <li>Map the first character to uppercase.
|
||||
* <li>Map the first character after underscores to uppercase.
|
||||
* <li>Remove all underscores.
|
||||
* </ol>
|
||||
* For example, to identify the <code>SPLIT_PANE</code>
|
||||
* <code>Region</code> you would use <code>SplitPane</code>.
|
||||
* The following shows a custom <code>SynthStyleFactory</code>
|
||||
* that returns a specific style for split panes:
|
||||
* <pre>
|
||||
* public SynthStyle getStyle(JComponent c, Region id) {
|
||||
* if (id == Region.SPLIT_PANE) {
|
||||
* return splitPaneStyle;
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
* The following <a href="doc-files/synthFileFormat.html">xml</a>
|
||||
* accomplishes the same thing:
|
||||
* <pre>
|
||||
* <style id="splitPaneStyle">
|
||||
* ...
|
||||
* </style>
|
||||
* <bind style="splitPaneStyle" type="region" key="SplitPane"/>
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Scott Violet
|
||||
*/
|
||||
public class Region {
|
||||
private static final Object UI_TO_REGION_MAP_KEY = new Object();
|
||||
private static final Object LOWER_CASE_NAME_MAP_KEY = new Object();
|
||||
|
||||
/**
|
||||
* ArrowButton's are special types of buttons that also render a
|
||||
* directional indicator, typically an arrow. ArrowButtons are used by
|
||||
* composite components, for example ScrollBar's contain ArrowButtons.
|
||||
* To bind a style to this <code>Region</code> use the name
|
||||
* <code>ArrowButton</code>.
|
||||
*/
|
||||
public static final Region ARROW_BUTTON = new Region("ArrowButton", false);
|
||||
|
||||
/**
|
||||
* Button region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>Button</code>.
|
||||
*/
|
||||
public static final Region BUTTON = new Region("Button", false);
|
||||
|
||||
/**
|
||||
* CheckBox region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>CheckBox</code>.
|
||||
*/
|
||||
public static final Region CHECK_BOX = new Region("CheckBox", false);
|
||||
|
||||
/**
|
||||
* CheckBoxMenuItem region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>CheckBoxMenuItem</code>.
|
||||
*/
|
||||
public static final Region CHECK_BOX_MENU_ITEM = new Region("CheckBoxMenuItem", false);
|
||||
|
||||
/**
|
||||
* ColorChooser region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ColorChooser</code>.
|
||||
*/
|
||||
public static final Region COLOR_CHOOSER = new Region("ColorChooser", false);
|
||||
|
||||
/**
|
||||
* ComboBox region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ComboBox</code>.
|
||||
*/
|
||||
public static final Region COMBO_BOX = new Region("ComboBox", false);
|
||||
|
||||
/**
|
||||
* DesktopPane region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>DesktopPane</code>.
|
||||
*/
|
||||
public static final Region DESKTOP_PANE = new Region("DesktopPane", false);
|
||||
|
||||
/**
|
||||
* DesktopIcon region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>DesktopIcon</code>.
|
||||
*/
|
||||
public static final Region DESKTOP_ICON = new Region("DesktopIcon", false);
|
||||
|
||||
/**
|
||||
* EditorPane region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>EditorPane</code>.
|
||||
*/
|
||||
public static final Region EDITOR_PANE = new Region("EditorPane", false);
|
||||
|
||||
/**
|
||||
* FileChooser region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>FileChooser</code>.
|
||||
*/
|
||||
public static final Region FILE_CHOOSER = new Region("FileChooser", false);
|
||||
|
||||
/**
|
||||
* FormattedTextField region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>FormattedTextField</code>.
|
||||
*/
|
||||
public static final Region FORMATTED_TEXT_FIELD = new Region("FormattedTextField", false);
|
||||
|
||||
/**
|
||||
* InternalFrame region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>InternalFrame</code>.
|
||||
*/
|
||||
public static final Region INTERNAL_FRAME = new Region("InternalFrame", false);
|
||||
|
||||
/**
|
||||
* TitlePane of an InternalFrame. The TitlePane typically
|
||||
* shows a menu, title, widgets to manipulate the internal frame.
|
||||
* To bind a style to this <code>Region</code> use the name
|
||||
* <code>InternalFrameTitlePane</code>.
|
||||
*/
|
||||
public static final Region INTERNAL_FRAME_TITLE_PANE = new Region("InternalFrameTitlePane", false);
|
||||
|
||||
/**
|
||||
* Label region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>Label</code>.
|
||||
*/
|
||||
public static final Region LABEL = new Region("Label", false);
|
||||
|
||||
/**
|
||||
* List region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>List</code>.
|
||||
*/
|
||||
public static final Region LIST = new Region("List", false);
|
||||
|
||||
/**
|
||||
* Menu region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>Menu</code>.
|
||||
*/
|
||||
public static final Region MENU = new Region("Menu", false);
|
||||
|
||||
/**
|
||||
* MenuBar region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>MenuBar</code>.
|
||||
*/
|
||||
public static final Region MENU_BAR = new Region("MenuBar", false);
|
||||
|
||||
/**
|
||||
* MenuItem region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>MenuItem</code>.
|
||||
*/
|
||||
public static final Region MENU_ITEM = new Region("MenuItem", false);
|
||||
|
||||
/**
|
||||
* Accelerator region of a MenuItem. To bind a style to this
|
||||
* <code>Region</code> use the name <code>MenuItemAccelerator</code>.
|
||||
*/
|
||||
public static final Region MENU_ITEM_ACCELERATOR = new Region("MenuItemAccelerator", true);
|
||||
|
||||
/**
|
||||
* OptionPane region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>OptionPane</code>.
|
||||
*/
|
||||
public static final Region OPTION_PANE = new Region("OptionPane", false);
|
||||
|
||||
/**
|
||||
* Panel region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>Panel</code>.
|
||||
*/
|
||||
public static final Region PANEL = new Region("Panel", false);
|
||||
|
||||
/**
|
||||
* PasswordField region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>PasswordField</code>.
|
||||
*/
|
||||
public static final Region PASSWORD_FIELD = new Region("PasswordField", false);
|
||||
|
||||
/**
|
||||
* PopupMenu region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>PopupMenu</code>.
|
||||
*/
|
||||
public static final Region POPUP_MENU = new Region("PopupMenu", false);
|
||||
|
||||
/**
|
||||
* PopupMenuSeparator region. To bind a style to this <code>Region</code>
|
||||
* use the name <code>PopupMenuSeparator</code>.
|
||||
*/
|
||||
public static final Region POPUP_MENU_SEPARATOR = new Region("PopupMenuSeparator", false);
|
||||
|
||||
/**
|
||||
* ProgressBar region. To bind a style to this <code>Region</code>
|
||||
* use the name <code>ProgressBar</code>.
|
||||
*/
|
||||
public static final Region PROGRESS_BAR = new Region("ProgressBar", false);
|
||||
|
||||
/**
|
||||
* RadioButton region. To bind a style to this <code>Region</code>
|
||||
* use the name <code>RadioButton</code>.
|
||||
*/
|
||||
public static final Region RADIO_BUTTON = new Region("RadioButton", false);
|
||||
|
||||
/**
|
||||
* RegionButtonMenuItem region. To bind a style to this <code>Region</code>
|
||||
* use the name <code>RadioButtonMenuItem</code>.
|
||||
*/
|
||||
public static final Region RADIO_BUTTON_MENU_ITEM = new Region("RadioButtonMenuItem", false);
|
||||
|
||||
/**
|
||||
* RootPane region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>RootPane</code>.
|
||||
*/
|
||||
public static final Region ROOT_PANE = new Region("RootPane", false);
|
||||
|
||||
/**
|
||||
* ScrollBar region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ScrollBar</code>.
|
||||
*/
|
||||
public static final Region SCROLL_BAR = new Region("ScrollBar", false);
|
||||
|
||||
/**
|
||||
* Track of the ScrollBar. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ScrollBarTrack</code>.
|
||||
*/
|
||||
public static final Region SCROLL_BAR_TRACK = new Region("ScrollBarTrack", true);
|
||||
|
||||
/**
|
||||
* Thumb of the ScrollBar. The thumb is the region of the ScrollBar
|
||||
* that gives a graphical depiction of what percentage of the View is
|
||||
* currently visible. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ScrollBarThumb</code>.
|
||||
*/
|
||||
public static final Region SCROLL_BAR_THUMB = new Region("ScrollBarThumb", true);
|
||||
|
||||
/**
|
||||
* ScrollPane region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ScrollPane</code>.
|
||||
*/
|
||||
public static final Region SCROLL_PANE = new Region("ScrollPane", false);
|
||||
|
||||
/**
|
||||
* Separator region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>Separator</code>.
|
||||
*/
|
||||
public static final Region SEPARATOR = new Region("Separator", false);
|
||||
|
||||
/**
|
||||
* Slider region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>Slider</code>.
|
||||
*/
|
||||
public static final Region SLIDER = new Region("Slider", false);
|
||||
|
||||
/**
|
||||
* Track of the Slider. To bind a style to this <code>Region</code> use
|
||||
* the name <code>SliderTrack</code>.
|
||||
*/
|
||||
public static final Region SLIDER_TRACK = new Region("SliderTrack", true);
|
||||
|
||||
/**
|
||||
* Thumb of the Slider. The thumb of the Slider identifies the current
|
||||
* value. To bind a style to this <code>Region</code> use the name
|
||||
* <code>SliderThumb</code>.
|
||||
*/
|
||||
public static final Region SLIDER_THUMB = new Region("SliderThumb", true);
|
||||
|
||||
/**
|
||||
* Spinner region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>Spinner</code>.
|
||||
*/
|
||||
public static final Region SPINNER = new Region("Spinner", false);
|
||||
|
||||
/**
|
||||
* SplitPane region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>SplitPane</code>.
|
||||
*/
|
||||
public static final Region SPLIT_PANE = new Region("SplitPane", false);
|
||||
|
||||
/**
|
||||
* Divider of the SplitPane. To bind a style to this <code>Region</code>
|
||||
* use the name <code>SplitPaneDivider</code>.
|
||||
*/
|
||||
public static final Region SPLIT_PANE_DIVIDER = new Region("SplitPaneDivider", true);
|
||||
|
||||
/**
|
||||
* TabbedPane region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>TabbedPane</code>.
|
||||
*/
|
||||
public static final Region TABBED_PANE = new Region("TabbedPane", false);
|
||||
|
||||
/**
|
||||
* Region of a TabbedPane for one tab. To bind a style to this
|
||||
* <code>Region</code> use the name <code>TabbedPaneTab</code>.
|
||||
*/
|
||||
public static final Region TABBED_PANE_TAB = new Region("TabbedPaneTab", true);
|
||||
|
||||
/**
|
||||
* Region of a TabbedPane containing the tabs. To bind a style to this
|
||||
* <code>Region</code> use the name <code>TabbedPaneTabArea</code>.
|
||||
*/
|
||||
public static final Region TABBED_PANE_TAB_AREA = new Region("TabbedPaneTabArea", true);
|
||||
|
||||
/**
|
||||
* Region of a TabbedPane containing the content. To bind a style to this
|
||||
* <code>Region</code> use the name <code>TabbedPaneContent</code>.
|
||||
*/
|
||||
public static final Region TABBED_PANE_CONTENT = new Region("TabbedPaneContent", true);
|
||||
|
||||
/**
|
||||
* Table region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>Table</code>.
|
||||
*/
|
||||
public static final Region TABLE = new Region("Table", false);
|
||||
|
||||
/**
|
||||
* TableHeader region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>TableHeader</code>.
|
||||
*/
|
||||
public static final Region TABLE_HEADER = new Region("TableHeader", false);
|
||||
|
||||
/**
|
||||
* TextArea region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>TextArea</code>.
|
||||
*/
|
||||
public static final Region TEXT_AREA = new Region("TextArea", false);
|
||||
|
||||
/**
|
||||
* TextField region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>TextField</code>.
|
||||
*/
|
||||
public static final Region TEXT_FIELD = new Region("TextField", false);
|
||||
|
||||
/**
|
||||
* TextPane region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>TextPane</code>.
|
||||
*/
|
||||
public static final Region TEXT_PANE = new Region("TextPane", false);
|
||||
|
||||
/**
|
||||
* ToggleButton region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ToggleButton</code>.
|
||||
*/
|
||||
public static final Region TOGGLE_BUTTON = new Region("ToggleButton", false);
|
||||
|
||||
/**
|
||||
* ToolBar region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ToolBar</code>.
|
||||
*/
|
||||
public static final Region TOOL_BAR = new Region("ToolBar", false);
|
||||
|
||||
/**
|
||||
* Region of the ToolBar containing the content. To bind a style to this
|
||||
* <code>Region</code> use the name <code>ToolBarContent</code>.
|
||||
*/
|
||||
public static final Region TOOL_BAR_CONTENT = new Region("ToolBarContent", true);
|
||||
|
||||
/**
|
||||
* Region for the Window containing the ToolBar. To bind a style to this
|
||||
* <code>Region</code> use the name <code>ToolBarDragWindow</code>.
|
||||
*/
|
||||
public static final Region TOOL_BAR_DRAG_WINDOW = new Region("ToolBarDragWindow", false);
|
||||
|
||||
/**
|
||||
* ToolTip region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ToolTip</code>.
|
||||
*/
|
||||
public static final Region TOOL_TIP = new Region("ToolTip", false);
|
||||
|
||||
/**
|
||||
* ToolBar separator region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>ToolBarSeparator</code>.
|
||||
*/
|
||||
public static final Region TOOL_BAR_SEPARATOR = new Region("ToolBarSeparator", false);
|
||||
|
||||
/**
|
||||
* Tree region. To bind a style to this <code>Region</code> use the name
|
||||
* <code>Tree</code>.
|
||||
*/
|
||||
public static final Region TREE = new Region("Tree", false);
|
||||
|
||||
/**
|
||||
* Region of the Tree for one cell. To bind a style to this
|
||||
* <code>Region</code> use the name <code>TreeCell</code>.
|
||||
*/
|
||||
public static final Region TREE_CELL = new Region("TreeCell", true);
|
||||
|
||||
/**
|
||||
* Viewport region. To bind a style to this <code>Region</code> use
|
||||
* the name <code>Viewport</code>.
|
||||
*/
|
||||
public static final Region VIEWPORT = new Region("Viewport", false);
|
||||
|
||||
private static Map<String, Region> getUItoRegionMap() {
|
||||
AppContext context = AppContext.getAppContext();
|
||||
Map<String, Region> map = (Map<String, Region>) context.get(UI_TO_REGION_MAP_KEY);
|
||||
if (map == null) {
|
||||
map = new HashMap<String, Region>();
|
||||
map.put("ArrowButtonUI", ARROW_BUTTON);
|
||||
map.put("ButtonUI", BUTTON);
|
||||
map.put("CheckBoxUI", CHECK_BOX);
|
||||
map.put("CheckBoxMenuItemUI", CHECK_BOX_MENU_ITEM);
|
||||
map.put("ColorChooserUI", COLOR_CHOOSER);
|
||||
map.put("ComboBoxUI", COMBO_BOX);
|
||||
map.put("DesktopPaneUI", DESKTOP_PANE);
|
||||
map.put("DesktopIconUI", DESKTOP_ICON);
|
||||
map.put("EditorPaneUI", EDITOR_PANE);
|
||||
map.put("FileChooserUI", FILE_CHOOSER);
|
||||
map.put("FormattedTextFieldUI", FORMATTED_TEXT_FIELD);
|
||||
map.put("InternalFrameUI", INTERNAL_FRAME);
|
||||
map.put("InternalFrameTitlePaneUI", INTERNAL_FRAME_TITLE_PANE);
|
||||
map.put("LabelUI", LABEL);
|
||||
map.put("ListUI", LIST);
|
||||
map.put("MenuUI", MENU);
|
||||
map.put("MenuBarUI", MENU_BAR);
|
||||
map.put("MenuItemUI", MENU_ITEM);
|
||||
map.put("OptionPaneUI", OPTION_PANE);
|
||||
map.put("PanelUI", PANEL);
|
||||
map.put("PasswordFieldUI", PASSWORD_FIELD);
|
||||
map.put("PopupMenuUI", POPUP_MENU);
|
||||
map.put("PopupMenuSeparatorUI", POPUP_MENU_SEPARATOR);
|
||||
map.put("ProgressBarUI", PROGRESS_BAR);
|
||||
map.put("RadioButtonUI", RADIO_BUTTON);
|
||||
map.put("RadioButtonMenuItemUI", RADIO_BUTTON_MENU_ITEM);
|
||||
map.put("RootPaneUI", ROOT_PANE);
|
||||
map.put("ScrollBarUI", SCROLL_BAR);
|
||||
map.put("ScrollPaneUI", SCROLL_PANE);
|
||||
map.put("SeparatorUI", SEPARATOR);
|
||||
map.put("SliderUI", SLIDER);
|
||||
map.put("SpinnerUI", SPINNER);
|
||||
map.put("SplitPaneUI", SPLIT_PANE);
|
||||
map.put("TabbedPaneUI", TABBED_PANE);
|
||||
map.put("TableUI", TABLE);
|
||||
map.put("TableHeaderUI", TABLE_HEADER);
|
||||
map.put("TextAreaUI", TEXT_AREA);
|
||||
map.put("TextFieldUI", TEXT_FIELD);
|
||||
map.put("TextPaneUI", TEXT_PANE);
|
||||
map.put("ToggleButtonUI", TOGGLE_BUTTON);
|
||||
map.put("ToolBarUI", TOOL_BAR);
|
||||
map.put("ToolTipUI", TOOL_TIP);
|
||||
map.put("ToolBarSeparatorUI", TOOL_BAR_SEPARATOR);
|
||||
map.put("TreeUI", TREE);
|
||||
map.put("ViewportUI", VIEWPORT);
|
||||
context.put(UI_TO_REGION_MAP_KEY, map);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static Map<Region, String> getLowerCaseNameMap() {
|
||||
AppContext context = AppContext.getAppContext();
|
||||
Map<Region, String> map = (Map<Region, String>) context.get(LOWER_CASE_NAME_MAP_KEY);
|
||||
if (map == null) {
|
||||
map = new HashMap<Region, String>();
|
||||
context.put(LOWER_CASE_NAME_MAP_KEY, map);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static Region getRegion(JComponent c) {
|
||||
return getUItoRegionMap().get(c.getUIClassID());
|
||||
}
|
||||
|
||||
static void registerUIs(UIDefaults table) {
|
||||
for (Object key : getUItoRegionMap().keySet()) {
|
||||
table.put(key, "javax.swing.plaf.synth.SynthLookAndFeel");
|
||||
}
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final boolean subregion;
|
||||
|
||||
private Region(String name, boolean subregion) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("You must specify a non-null name");
|
||||
}
|
||||
this.name = name;
|
||||
this.subregion = subregion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Region with the specified name. This should only be
|
||||
* used if you are creating your own <code>JComponent</code> subclass
|
||||
* with a custom <code>ComponentUI</code> class.
|
||||
*
|
||||
* @param name Name of the region
|
||||
* @param ui String that will be returned from
|
||||
* <code>component.getUIClassID</code>. This will be null
|
||||
* if this is a subregion.
|
||||
* @param subregion Whether or not this is a subregion.
|
||||
*/
|
||||
protected Region(String name, String ui, boolean subregion) {
|
||||
this(name, subregion);
|
||||
if (ui != null) {
|
||||
getUItoRegionMap().put(ui, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Region is a subregion of a Component, otherwise
|
||||
* false. For example, <code>Region.BUTTON</code> corresponds do a
|
||||
* <code>Component</code> so that <code>Region.BUTTON.isSubregion()</code>
|
||||
* returns false.
|
||||
*
|
||||
* @return true if the Region is a subregion of a Component.
|
||||
*/
|
||||
public boolean isSubregion() {
|
||||
return subregion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the region.
|
||||
*
|
||||
* @return name of the Region.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name, in lowercase.
|
||||
*
|
||||
* @return lower case representation of the name of the Region
|
||||
*/
|
||||
String getLowerCaseName() {
|
||||
Map<Region, String> lowerCaseNameMap = getLowerCaseNameMap();
|
||||
String lowerCaseName = lowerCaseNameMap.get(this);
|
||||
if (lowerCaseName == null) {
|
||||
lowerCaseName = name.toLowerCase(Locale.ENGLISH);
|
||||
lowerCaseNameMap.put(this, lowerCaseName);
|
||||
}
|
||||
return lowerCaseName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the Region.
|
||||
*
|
||||
* @return name of the Region.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
145
jdkSrc/jdk8/javax/swing/plaf/synth/SynthArrowButton.java
Normal file
145
jdkSrc/jdk8/javax/swing/plaf/synth/SynthArrowButton.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.UIResource;
|
||||
|
||||
/**
|
||||
* JButton object that draws a scaled Arrow in one of the cardinal directions.
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class SynthArrowButton extends JButton implements SwingConstants, UIResource {
|
||||
private int direction;
|
||||
|
||||
public SynthArrowButton(int direction) {
|
||||
super();
|
||||
super.setFocusable(false);
|
||||
setDirection(direction);
|
||||
setDefaultCapable(false);
|
||||
}
|
||||
|
||||
public String getUIClassID() {
|
||||
return "ArrowButtonUI";
|
||||
}
|
||||
|
||||
public void updateUI() {
|
||||
setUI(new SynthArrowButtonUI());
|
||||
}
|
||||
|
||||
public void setDirection(int dir) {
|
||||
direction = dir;
|
||||
putClientProperty("__arrow_direction__", Integer.valueOf(dir));
|
||||
repaint();
|
||||
}
|
||||
|
||||
public int getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setFocusable(boolean focusable) {}
|
||||
|
||||
private static class SynthArrowButtonUI extends SynthButtonUI {
|
||||
protected void installDefaults(AbstractButton b) {
|
||||
super.installDefaults(b);
|
||||
updateStyle(b);
|
||||
}
|
||||
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
SynthArrowButton button = (SynthArrowButton)context.
|
||||
getComponent();
|
||||
context.getPainter().paintArrowButtonForeground(
|
||||
context, g, 0, 0, button.getWidth(), button.getHeight(),
|
||||
button.getDirection());
|
||||
}
|
||||
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintArrowButtonBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintArrowButtonBorder(context, g, x, y, w,h);
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
return new Dimension(5, 5);
|
||||
}
|
||||
|
||||
public Dimension getMaximumSize() {
|
||||
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
Dimension dim = null;
|
||||
if (context.getComponent().getName() == "ScrollBar.button") {
|
||||
// ScrollBar arrow buttons can be non-square when
|
||||
// the ScrollBar.squareButtons property is set to FALSE
|
||||
// and the ScrollBar.buttonSize property is non-null
|
||||
dim = (Dimension)
|
||||
context.getStyle().get(context, "ScrollBar.buttonSize");
|
||||
}
|
||||
if (dim == null) {
|
||||
// For all other cases (including Spinner, ComboBox), we will
|
||||
// fall back on the single ArrowButton.size value to create
|
||||
// a square return value
|
||||
int size =
|
||||
context.getStyle().getInt(context, "ArrowButton.size", 16);
|
||||
dim = new Dimension(size, size);
|
||||
}
|
||||
|
||||
// handle scaling for sizeVarients for special case components. The
|
||||
// key "JComponent.sizeVariant" scales for large/small/mini
|
||||
// components are based on Apples LAF
|
||||
Container parent = context.getComponent().getParent();
|
||||
if (parent instanceof JComponent && !(parent instanceof JComboBox)) {
|
||||
Object scaleKey = ((JComponent)parent).
|
||||
getClientProperty("JComponent.sizeVariant");
|
||||
if (scaleKey != null){
|
||||
if ("large".equals(scaleKey)){
|
||||
dim = new Dimension(
|
||||
(int)(dim.width * 1.15),
|
||||
(int)(dim.height * 1.15));
|
||||
} else if ("small".equals(scaleKey)){
|
||||
dim = new Dimension(
|
||||
(int)(dim.width * 0.857),
|
||||
(int)(dim.height * 0.857));
|
||||
} else if ("mini".equals(scaleKey)){
|
||||
dim = new Dimension(
|
||||
(int)(dim.width * 0.714),
|
||||
(int)(dim.height * 0.714));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.dispose();
|
||||
return dim;
|
||||
}
|
||||
}
|
||||
}
|
||||
136
jdkSrc/jdk8/javax/swing/plaf/synth/SynthBorder.java
Normal file
136
jdkSrc/jdk8/javax/swing/plaf/synth/SynthBorder.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2006, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.UIResource;
|
||||
|
||||
/**
|
||||
* SynthBorder is a border that delegates to a Painter. The Insets
|
||||
* are determined at construction time.
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class SynthBorder extends AbstractBorder implements UIResource {
|
||||
private SynthUI ui;
|
||||
private Insets insets;
|
||||
|
||||
SynthBorder(SynthUI ui, Insets insets) {
|
||||
this.ui = ui;
|
||||
this.insets = insets;
|
||||
}
|
||||
|
||||
SynthBorder(SynthUI ui) {
|
||||
this(ui, null);
|
||||
}
|
||||
|
||||
public void paintBorder(Component c, Graphics g, int x, int y,
|
||||
int width, int height) {
|
||||
JComponent jc = (JComponent)c;
|
||||
SynthContext context = ui.getContext(jc);
|
||||
SynthStyle style = context.getStyle();
|
||||
if (style == null) {
|
||||
assert false: "SynthBorder is being used outside after the UI " +
|
||||
"has been uninstalled";
|
||||
return;
|
||||
}
|
||||
ui.paintBorder(context, g, x, y, width, height);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitializes the insets parameter with this Border's current Insets.
|
||||
* @param c the component for which this border insets value applies
|
||||
* @param insets the object to be reinitialized
|
||||
* @return the <code>insets</code> object
|
||||
*/
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
if (this.insets != null) {
|
||||
if (insets == null) {
|
||||
insets = new Insets(this.insets.top, this.insets.left,
|
||||
this.insets.bottom, this.insets.right);
|
||||
}
|
||||
else {
|
||||
insets.top = this.insets.top;
|
||||
insets.bottom = this.insets.bottom;
|
||||
insets.left = this.insets.left;
|
||||
insets.right = this.insets.right;
|
||||
}
|
||||
}
|
||||
else if (insets == null) {
|
||||
insets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
else {
|
||||
insets.top = insets.bottom = insets.left = insets.right = 0;
|
||||
}
|
||||
if (c instanceof JComponent) {
|
||||
Region region = Region.getRegion((JComponent)c);
|
||||
Insets margin = null;
|
||||
if ((region == Region.ARROW_BUTTON || region == Region.BUTTON ||
|
||||
region == Region.CHECK_BOX ||
|
||||
region == Region.CHECK_BOX_MENU_ITEM ||
|
||||
region == Region.MENU || region == Region.MENU_ITEM ||
|
||||
region == Region.RADIO_BUTTON ||
|
||||
region == Region.RADIO_BUTTON_MENU_ITEM ||
|
||||
region == Region.TOGGLE_BUTTON) &&
|
||||
(c instanceof AbstractButton)) {
|
||||
margin = ((AbstractButton)c).getMargin();
|
||||
}
|
||||
else if ((region == Region.EDITOR_PANE ||
|
||||
region == Region.FORMATTED_TEXT_FIELD ||
|
||||
region == Region.PASSWORD_FIELD ||
|
||||
region == Region.TEXT_AREA ||
|
||||
region == Region.TEXT_FIELD ||
|
||||
region == Region.TEXT_PANE) &&
|
||||
(c instanceof JTextComponent)) {
|
||||
margin = ((JTextComponent)c).getMargin();
|
||||
}
|
||||
else if (region == Region.TOOL_BAR && (c instanceof JToolBar)) {
|
||||
margin = ((JToolBar)c).getMargin();
|
||||
}
|
||||
else if (region == Region.MENU_BAR && (c instanceof JMenuBar)) {
|
||||
margin = ((JMenuBar)c).getMargin();
|
||||
}
|
||||
if (margin != null) {
|
||||
insets.top += margin.top;
|
||||
insets.bottom += margin.bottom;
|
||||
insets.left += margin.left;
|
||||
insets.right += margin.right;
|
||||
}
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
|
||||
/**
|
||||
* This default implementation returns false.
|
||||
* @return false
|
||||
*/
|
||||
public boolean isBorderOpaque() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
534
jdkSrc/jdk8/javax/swing/plaf/synth/SynthButtonUI.java
Normal file
534
jdkSrc/jdk8/javax/swing/plaf/synth/SynthButtonUI.java
Normal file
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.text.View;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JButton}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthButtonUI extends BasicButtonUI implements
|
||||
PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthButtonUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults(AbstractButton b) {
|
||||
updateStyle(b);
|
||||
|
||||
LookAndFeel.installProperty(b, "rolloverEnabled", Boolean.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners(AbstractButton b) {
|
||||
super.installListeners(b);
|
||||
b.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
void updateStyle(AbstractButton b) {
|
||||
SynthContext context = getContext(b, SynthConstants.ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
if (b.getMargin() == null ||
|
||||
(b.getMargin() instanceof UIResource)) {
|
||||
Insets margin = (Insets)style.get(context,getPropertyPrefix() +
|
||||
"margin");
|
||||
|
||||
if (margin == null) {
|
||||
// Some places assume margins are non-null.
|
||||
margin = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
|
||||
}
|
||||
b.setMargin(margin);
|
||||
}
|
||||
|
||||
Object value = style.get(context, getPropertyPrefix() + "iconTextGap");
|
||||
if (value != null) {
|
||||
LookAndFeel.installProperty(b, "iconTextGap", value);
|
||||
}
|
||||
|
||||
value = style.get(context, getPropertyPrefix() + "contentAreaFilled");
|
||||
LookAndFeel.installProperty(b, "contentAreaFilled",
|
||||
value != null? value : Boolean.TRUE);
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions(b);
|
||||
installKeyboardActions(b);
|
||||
}
|
||||
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners(AbstractButton b) {
|
||||
super.uninstallListeners(b);
|
||||
b.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults(AbstractButton b) {
|
||||
SynthContext context = getContext(b, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current state of the passed in <code>AbstractButton</code>.
|
||||
*/
|
||||
private int getComponentState(JComponent c) {
|
||||
int state = ENABLED;
|
||||
|
||||
if (!c.isEnabled()) {
|
||||
state = DISABLED;
|
||||
}
|
||||
if (SynthLookAndFeel.getSelectedUI() == this) {
|
||||
return SynthLookAndFeel.getSelectedUIState() | SynthConstants.ENABLED;
|
||||
}
|
||||
AbstractButton button = (AbstractButton) c;
|
||||
ButtonModel model = button.getModel();
|
||||
|
||||
if (model.isPressed()) {
|
||||
if (model.isArmed()) {
|
||||
state = PRESSED;
|
||||
}
|
||||
else {
|
||||
state = MOUSE_OVER;
|
||||
}
|
||||
}
|
||||
if (model.isRollover()) {
|
||||
state |= MOUSE_OVER;
|
||||
}
|
||||
if (model.isSelected()) {
|
||||
state |= SELECTED;
|
||||
}
|
||||
if (c.isFocusOwner() && button.isFocusPainted()) {
|
||||
state |= FOCUSED;
|
||||
}
|
||||
if ((c instanceof JButton) && ((JButton)c).isDefaultButton()) {
|
||||
state |= DEFAULT;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getBaseline(JComponent c, int width, int height) {
|
||||
if (c == null) {
|
||||
throw new NullPointerException("Component must be non-null");
|
||||
}
|
||||
if (width < 0 || height < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Width and height must be >= 0");
|
||||
}
|
||||
AbstractButton b = (AbstractButton)c;
|
||||
String text = b.getText();
|
||||
if (text == null || "".equals(text)) {
|
||||
return -1;
|
||||
}
|
||||
Insets i = b.getInsets();
|
||||
Rectangle viewRect = new Rectangle();
|
||||
Rectangle textRect = new Rectangle();
|
||||
Rectangle iconRect = new Rectangle();
|
||||
viewRect.x = i.left;
|
||||
viewRect.y = i.top;
|
||||
viewRect.width = width - (i.right + viewRect.x);
|
||||
viewRect.height = height - (i.bottom + viewRect.y);
|
||||
|
||||
// layout the text and icon
|
||||
SynthContext context = getContext(b);
|
||||
FontMetrics fm = context.getComponent().getFontMetrics(
|
||||
context.getStyle().getFont(context));
|
||||
context.getStyle().getGraphicsUtils(context).layoutText(
|
||||
context, fm, b.getText(), b.getIcon(),
|
||||
b.getHorizontalAlignment(), b.getVerticalAlignment(),
|
||||
b.getHorizontalTextPosition(), b.getVerticalTextPosition(),
|
||||
viewRect, iconRect, textRect, b.getIconTextGap());
|
||||
View view = (View)b.getClientProperty(BasicHTML.propertyKey);
|
||||
int baseline;
|
||||
if (view != null) {
|
||||
baseline = BasicHTML.getHTMLBaseline(view, textRect.width,
|
||||
textRect.height);
|
||||
if (baseline >= 0) {
|
||||
baseline += textRect.y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
baseline = textRect.y + fm.getAscent();
|
||||
}
|
||||
context.dispose();
|
||||
return baseline;
|
||||
}
|
||||
|
||||
// ********************************
|
||||
// Paint Methods
|
||||
// ********************************
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
paintBackground(context, g, c);
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
AbstractButton b = (AbstractButton)context.getComponent();
|
||||
|
||||
g.setColor(context.getStyle().getColor(context,
|
||||
ColorType.TEXT_FOREGROUND));
|
||||
g.setFont(style.getFont(context));
|
||||
context.getStyle().getGraphicsUtils(context).paintText(
|
||||
context, g, b.getText(), getIcon(b),
|
||||
b.getHorizontalAlignment(), b.getVerticalAlignment(),
|
||||
b.getHorizontalTextPosition(), b.getVerticalTextPosition(),
|
||||
b.getIconTextGap(), b.getDisplayedMnemonicIndex(),
|
||||
getTextShiftOffset(context));
|
||||
}
|
||||
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
if (((AbstractButton) c).isContentAreaFilled()) {
|
||||
context.getPainter().paintButtonBackground(context, g, 0, 0,
|
||||
c.getWidth(),
|
||||
c.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintButtonBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default icon. This should not callback
|
||||
* to the JComponent.
|
||||
*
|
||||
* @param b button the icon is associated with
|
||||
* @return default icon
|
||||
*/
|
||||
protected Icon getDefaultIcon(AbstractButton b) {
|
||||
SynthContext context = getContext(b);
|
||||
Icon icon = context.getStyle().getIcon(context, getPropertyPrefix() + "icon");
|
||||
context.dispose();
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Icon to use for painting the button. The icon is chosen with
|
||||
* respect to the current state of the button.
|
||||
*
|
||||
* @param b button the icon is associated with
|
||||
* @return an icon
|
||||
*/
|
||||
protected Icon getIcon(AbstractButton b) {
|
||||
Icon icon = b.getIcon();
|
||||
ButtonModel model = b.getModel();
|
||||
|
||||
if (!model.isEnabled()) {
|
||||
icon = getSynthDisabledIcon(b, icon);
|
||||
} else if (model.isPressed() && model.isArmed()) {
|
||||
icon = getPressedIcon(b, getSelectedIcon(b, icon));
|
||||
} else if (b.isRolloverEnabled() && model.isRollover()) {
|
||||
icon = getRolloverIcon(b, getSelectedIcon(b, icon));
|
||||
} else if (model.isSelected()) {
|
||||
icon = getSelectedIcon(b, icon);
|
||||
} else {
|
||||
icon = getEnabledIcon(b, icon);
|
||||
}
|
||||
if(icon == null) {
|
||||
return getDefaultIcon(b);
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the icon that should be used for a button. We
|
||||
* only want to use the synth icon defined by the style if the specific
|
||||
* icon has not been defined for the button state and the backup icon is a
|
||||
* UIResource (we set it, not the developer).
|
||||
*
|
||||
* @param b button
|
||||
* @param specificIcon icon returned from the button for the specific state
|
||||
* @param defaultIcon fallback icon
|
||||
* @param state the synth state of the button
|
||||
*/
|
||||
private Icon getIcon(AbstractButton b, Icon specificIcon, Icon defaultIcon,
|
||||
int state) {
|
||||
Icon icon = specificIcon;
|
||||
if (icon == null) {
|
||||
if (defaultIcon instanceof UIResource) {
|
||||
icon = getSynthIcon(b, state);
|
||||
if (icon == null) {
|
||||
icon = defaultIcon;
|
||||
}
|
||||
} else {
|
||||
icon = defaultIcon;
|
||||
}
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
private Icon getSynthIcon(AbstractButton b, int synthConstant) {
|
||||
return style.getIcon(getContext(b, synthConstant), getPropertyPrefix() + "icon");
|
||||
}
|
||||
|
||||
private Icon getEnabledIcon(AbstractButton b, Icon defaultIcon) {
|
||||
if (defaultIcon == null) {
|
||||
defaultIcon = getSynthIcon(b, SynthConstants.ENABLED);
|
||||
}
|
||||
return defaultIcon;
|
||||
}
|
||||
|
||||
private Icon getSelectedIcon(AbstractButton b, Icon defaultIcon) {
|
||||
return getIcon(b, b.getSelectedIcon(), defaultIcon,
|
||||
SynthConstants.SELECTED);
|
||||
}
|
||||
|
||||
private Icon getRolloverIcon(AbstractButton b, Icon defaultIcon) {
|
||||
ButtonModel model = b.getModel();
|
||||
Icon icon;
|
||||
if (model.isSelected()) {
|
||||
icon = getIcon(b, b.getRolloverSelectedIcon(), defaultIcon,
|
||||
SynthConstants.MOUSE_OVER | SynthConstants.SELECTED);
|
||||
} else {
|
||||
icon = getIcon(b, b.getRolloverIcon(), defaultIcon,
|
||||
SynthConstants.MOUSE_OVER);
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
private Icon getPressedIcon(AbstractButton b, Icon defaultIcon) {
|
||||
return getIcon(b, b.getPressedIcon(), defaultIcon,
|
||||
SynthConstants.PRESSED);
|
||||
}
|
||||
|
||||
private Icon getSynthDisabledIcon(AbstractButton b, Icon defaultIcon) {
|
||||
ButtonModel model = b.getModel();
|
||||
Icon icon;
|
||||
if (model.isSelected()) {
|
||||
icon = getIcon(b, b.getDisabledSelectedIcon(), defaultIcon,
|
||||
SynthConstants.DISABLED | SynthConstants.SELECTED);
|
||||
} else {
|
||||
icon = getIcon(b, b.getDisabledIcon(), defaultIcon,
|
||||
SynthConstants.DISABLED);
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount to shift the text/icon when painting.
|
||||
*/
|
||||
private int getTextShiftOffset(SynthContext state) {
|
||||
AbstractButton button = (AbstractButton)state.getComponent();
|
||||
ButtonModel model = button.getModel();
|
||||
|
||||
if (model.isArmed() && model.isPressed() &&
|
||||
button.getPressedIcon() == null) {
|
||||
return state.getStyle().getInt(state, getPropertyPrefix() +
|
||||
"textShiftOffset", 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ********************************
|
||||
// Layout Methods
|
||||
// ********************************
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMinimumSize(JComponent c) {
|
||||
if (c.getComponentCount() > 0 && c.getLayout() != null) {
|
||||
return null;
|
||||
}
|
||||
AbstractButton b = (AbstractButton)c;
|
||||
SynthContext ss = getContext(c);
|
||||
Dimension size = ss.getStyle().getGraphicsUtils(ss).getMinimumSize(
|
||||
ss, ss.getStyle().getFont(ss), b.getText(), getSizingIcon(b),
|
||||
b.getHorizontalAlignment(), b.getVerticalAlignment(),
|
||||
b.getHorizontalTextPosition(),
|
||||
b.getVerticalTextPosition(), b.getIconTextGap(),
|
||||
b.getDisplayedMnemonicIndex());
|
||||
|
||||
ss.dispose();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
if (c.getComponentCount() > 0 && c.getLayout() != null) {
|
||||
return null;
|
||||
}
|
||||
AbstractButton b = (AbstractButton)c;
|
||||
SynthContext ss = getContext(c);
|
||||
Dimension size = ss.getStyle().getGraphicsUtils(ss).getPreferredSize(
|
||||
ss, ss.getStyle().getFont(ss), b.getText(), getSizingIcon(b),
|
||||
b.getHorizontalAlignment(), b.getVerticalAlignment(),
|
||||
b.getHorizontalTextPosition(),
|
||||
b.getVerticalTextPosition(), b.getIconTextGap(),
|
||||
b.getDisplayedMnemonicIndex());
|
||||
|
||||
ss.dispose();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMaximumSize(JComponent c) {
|
||||
if (c.getComponentCount() > 0 && c.getLayout() != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AbstractButton b = (AbstractButton)c;
|
||||
SynthContext ss = getContext(c);
|
||||
Dimension size = ss.getStyle().getGraphicsUtils(ss).getMaximumSize(
|
||||
ss, ss.getStyle().getFont(ss), b.getText(), getSizingIcon(b),
|
||||
b.getHorizontalAlignment(), b.getVerticalAlignment(),
|
||||
b.getHorizontalTextPosition(),
|
||||
b.getVerticalTextPosition(), b.getIconTextGap(),
|
||||
b.getDisplayedMnemonicIndex());
|
||||
|
||||
ss.dispose();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Icon used in calculating the
|
||||
* preferred/minimum/maximum size.
|
||||
*/
|
||||
protected Icon getSizingIcon(AbstractButton b) {
|
||||
Icon icon = getEnabledIcon(b, b.getIcon());
|
||||
if (icon == null) {
|
||||
icon = getDefaultIcon(b);
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((AbstractButton)e.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JCheckBoxMenuItem}.
|
||||
*
|
||||
* @author Leif Samuelsson
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @author Arnaud Weber
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthCheckBoxMenuItemUI extends SynthMenuItemUI {
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthCheckBoxMenuItemUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "CheckBoxMenuItem";
|
||||
}
|
||||
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintCheckBoxMenuItemBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintCheckBoxMenuItemBorder(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
77
jdkSrc/jdk8/javax/swing/plaf/synth/SynthCheckBoxUI.java
Normal file
77
jdkSrc/jdk8/javax/swing/plaf/synth/SynthCheckBoxUI.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JCheckBox}.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthCheckBoxUI extends SynthRadioButtonUI {
|
||||
|
||||
// ********************************
|
||||
// Create PLAF
|
||||
// ********************************
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param b component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new SynthCheckBoxUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "CheckBox.";
|
||||
}
|
||||
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintCheckBoxBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintCheckBoxBorder(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
207
jdkSrc/jdk8/javax/swing/plaf/synth/SynthColorChooserUI.java
Normal file
207
jdkSrc/jdk8/javax/swing/plaf/synth/SynthColorChooserUI.java
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.colorchooser.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicColorChooserUI;
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JColorChooser}.
|
||||
*
|
||||
* @author Tom Santos
|
||||
* @author Steve Wilson
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthColorChooserUI extends BasicColorChooserUI implements
|
||||
PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthColorChooserUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected AbstractColorChooserPanel[] createDefaultChoosers() {
|
||||
SynthContext context = getContext(chooser, ENABLED);
|
||||
AbstractColorChooserPanel[] panels = (AbstractColorChooserPanel[])
|
||||
context.getStyle().get(context, "ColorChooser.panels");
|
||||
context.dispose();
|
||||
|
||||
if (panels == null) {
|
||||
panels = ColorChooserComponentFactory.getDefaultChooserPanels();
|
||||
}
|
||||
return panels;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
updateStyle(chooser);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(chooser, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
chooser.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
chooser.removePropertyChangeListener(this);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintColorChooserBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
* This implementation does not perform any actions.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintColorChooserBorder(context, g, x, y,w,h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JColorChooser)e.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
768
jdkSrc/jdk8/javax/swing/plaf/synth/SynthComboBoxUI.java
Normal file
768
jdkSrc/jdk8/javax/swing/plaf/synth/SynthComboBoxUI.java
Normal file
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JComboBox}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthComboBoxUI extends BasicComboBoxUI implements
|
||||
PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
private boolean useListColors;
|
||||
|
||||
/**
|
||||
* Used to adjust the location and size of the popup. Very useful for
|
||||
* situations such as we find in Nimbus where part of the border is used
|
||||
* to paint the focus. In such cases, the border is empty space, and not
|
||||
* part of the "visual" border, and in these cases, you'd like the popup
|
||||
* to be adjusted such that it looks as if it were next to the visual border.
|
||||
* You may want to use negative insets to get the right look.
|
||||
*/
|
||||
Insets popupInsets;
|
||||
|
||||
/**
|
||||
* This flag may be set via UIDefaults. By default, it is false, to
|
||||
* preserve backwards compatibility. If true, then the combo will
|
||||
* "act as a button" when it is not editable.
|
||||
*/
|
||||
private boolean buttonWhenNotEditable;
|
||||
|
||||
/**
|
||||
* A flag to indicate that the combo box and combo box button should
|
||||
* remain in the PRESSED state while the combo popup is visible.
|
||||
*/
|
||||
private boolean pressedWhenPopupVisible;
|
||||
|
||||
/**
|
||||
* When buttonWhenNotEditable is true, this field is used to help make
|
||||
* the combo box appear and function as a button when the combo box is
|
||||
* not editable. In such a state, you can click anywhere on the button
|
||||
* to get it to open the popup. Also, anywhere you hover over the combo
|
||||
* will cause the entire combo to go into "rollover" state, and anywhere
|
||||
* you press will go into "pressed" state. This also keeps in sync the
|
||||
* state of the combo and the arrowButton.
|
||||
*/
|
||||
private ButtonHandler buttonHandler;
|
||||
|
||||
/**
|
||||
* Handler for repainting combo when editor component gains/looses focus
|
||||
*/
|
||||
private EditorFocusHandler editorFocusHandler;
|
||||
|
||||
/**
|
||||
* If true, then the cell renderer will be forced to be non-opaque when
|
||||
* used for rendering the selected item in the combo box (not in the list),
|
||||
* and forced to opaque after rendering the selected value.
|
||||
*/
|
||||
private boolean forceOpaque = false;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthComboBoxUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Overridden to ensure that ButtonHandler is created prior to any of
|
||||
* the other installXXX methods, since several of them reference
|
||||
* buttonHandler.
|
||||
*/
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
buttonHandler = new ButtonHandler();
|
||||
super.installUI(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {
|
||||
padding = (Insets) style.get(context, "ComboBox.padding");
|
||||
popupInsets = (Insets)style.get(context, "ComboBox.popupInsets");
|
||||
useListColors = style.getBoolean(context,
|
||||
"ComboBox.rendererUseListColors", true);
|
||||
buttonWhenNotEditable = style.getBoolean(context,
|
||||
"ComboBox.buttonWhenNotEditable", false);
|
||||
pressedWhenPopupVisible = style.getBoolean(context,
|
||||
"ComboBox.pressedWhenPopupVisible", false);
|
||||
squareButton = style.getBoolean(context,
|
||||
"ComboBox.squareButton", true);
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
forceOpaque = style.getBoolean(context,
|
||||
"ComboBox.forceOpaque", false);
|
||||
}
|
||||
context.dispose();
|
||||
|
||||
if(listBox != null) {
|
||||
SynthLookAndFeel.updateStyles(listBox);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
comboBox.addPropertyChangeListener(this);
|
||||
comboBox.addMouseListener(buttonHandler);
|
||||
editorFocusHandler = new EditorFocusHandler(comboBox);
|
||||
super.installListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
if (popup instanceof SynthComboPopup) {
|
||||
((SynthComboPopup)popup).removePopupMenuListener(buttonHandler);
|
||||
}
|
||||
super.uninstallUI(c);
|
||||
buttonHandler = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(comboBox, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
editorFocusHandler.unregister();
|
||||
comboBox.removePropertyChangeListener(this);
|
||||
comboBox.removeMouseListener(buttonHandler);
|
||||
buttonHandler.pressed = false;
|
||||
buttonHandler.over = false;
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
// currently we have a broken situation where if a developer
|
||||
// takes the border from a JComboBox and sets it on a JTextField
|
||||
// then the codepath will eventually lead back to this method
|
||||
// but pass in a JTextField instead of JComboBox! In case this
|
||||
// happens, we just return the normal synth state for the component
|
||||
// instead of doing anything special
|
||||
if (!(c instanceof JComboBox)) return SynthLookAndFeel.getComponentState(c);
|
||||
|
||||
JComboBox box = (JComboBox)c;
|
||||
if (shouldActLikeButton()) {
|
||||
int state = ENABLED;
|
||||
if ((!c.isEnabled())) {
|
||||
state = DISABLED;
|
||||
}
|
||||
if (buttonHandler.isPressed()) {
|
||||
state |= PRESSED;
|
||||
}
|
||||
if (buttonHandler.isRollover()) {
|
||||
state |= MOUSE_OVER;
|
||||
}
|
||||
if (box.isFocusOwner()) {
|
||||
state |= FOCUSED;
|
||||
}
|
||||
return state;
|
||||
} else {
|
||||
// for editable combos the editor component has the focus not the
|
||||
// combo box its self, so we should make the combo paint focused
|
||||
// when its editor has focus
|
||||
int basicState = SynthLookAndFeel.getComponentState(c);
|
||||
if (box.isEditable() &&
|
||||
box.getEditor().getEditorComponent().isFocusOwner()) {
|
||||
basicState |= FOCUSED;
|
||||
}
|
||||
return basicState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected ComboPopup createPopup() {
|
||||
SynthComboPopup p = new SynthComboPopup(comboBox);
|
||||
p.addPopupMenuListener(buttonHandler);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected ListCellRenderer createRenderer() {
|
||||
return new SynthComboBoxRenderer();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected ComboBoxEditor createEditor() {
|
||||
return new SynthComboBoxEditor();
|
||||
}
|
||||
|
||||
//
|
||||
// end UI Initialization
|
||||
//======================
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle(comboBox);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected JButton createArrowButton() {
|
||||
SynthArrowButton button = new SynthArrowButton(SwingConstants.SOUTH);
|
||||
button.setName("ComboBox.arrowButton");
|
||||
button.setModel(buttonHandler);
|
||||
return button;
|
||||
}
|
||||
|
||||
//=================================
|
||||
// begin ComponentUI Implementation
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
hasFocus = comboBox.hasFocus();
|
||||
if ( !comboBox.isEditable() ) {
|
||||
Rectangle r = rectangleForCurrentValue();
|
||||
paintCurrentValue(g,r,hasFocus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public void paintCurrentValue(Graphics g,Rectangle bounds,boolean hasFocus) {
|
||||
ListCellRenderer renderer = comboBox.getRenderer();
|
||||
Component c;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
boolean force = forceOpaque && c instanceof JComponent;
|
||||
if (force) {
|
||||
((JComponent)c).setOpaque(false);
|
||||
}
|
||||
|
||||
int x = bounds.x, y = bounds.y, w = bounds.width, h = bounds.height;
|
||||
if (padding != null) {
|
||||
x = bounds.x + padding.left;
|
||||
y = bounds.y + padding.top;
|
||||
w = bounds.width - (padding.left + padding.right);
|
||||
h = bounds.height - (padding.top + padding.bottom);
|
||||
}
|
||||
|
||||
currentValuePane.paintComponent(g, c, comboBox, x, y, w, h, shouldValidate);
|
||||
|
||||
if (force) {
|
||||
((JComponent)c).setOpaque(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this combo box should act as one big button. Typically
|
||||
* only happens when buttonWhenNotEditable is true, and comboBox.isEditable
|
||||
* is false.
|
||||
*/
|
||||
private boolean shouldActLikeButton() {
|
||||
return buttonWhenNotEditable && !comboBox.isEditable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default size of an empty display area of the combo box using
|
||||
* the current renderer and font.
|
||||
*
|
||||
* This method was overridden to use SynthComboBoxRenderer instead of
|
||||
* DefaultListCellRenderer as the default renderer when calculating the
|
||||
* size of the combo box. This is used in the case of the combo not having
|
||||
* any data.
|
||||
*
|
||||
* @return the size of an empty display area
|
||||
* @see #getDisplaySize
|
||||
*/
|
||||
@Override
|
||||
protected Dimension getDefaultSize() {
|
||||
SynthComboBoxRenderer r = new SynthComboBoxRenderer();
|
||||
Dimension d = getSizeForComponent(r.getListCellRendererComponent(listBox, " ", -1, false, false));
|
||||
return new Dimension(d.width, d.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* From BasicComboBoxRenderer v 1.18.
|
||||
*
|
||||
* Be aware that SynthFileChooserUIImpl relies on the fact that the default
|
||||
* renderer installed on a Synth combo box is a JLabel. If this is changed,
|
||||
* then an assert will fail in SynthFileChooserUIImpl
|
||||
*/
|
||||
private class SynthComboBoxRenderer extends JLabel implements ListCellRenderer<Object>, UIResource {
|
||||
public SynthComboBoxRenderer() {
|
||||
super();
|
||||
setText(" ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
// SynthComboBoxRenderer should have installed Name while constructor is working.
|
||||
// The setName invocation in the SynthComboBoxRenderer() constructor doesn't work
|
||||
// because of the opaque property is installed in the constructor based on the
|
||||
// component name (see GTKStyle.isOpaque())
|
||||
String name = super.getName();
|
||||
|
||||
return name == null ? "ComboBox.renderer" : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
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.
|
||||
if (comboBox != null){
|
||||
setEnabled(comboBox.isEnabled());
|
||||
setComponentOrientation(comboBox.getComponentOrientation());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SynthComboBoxEditor
|
||||
extends BasicComboBoxEditor.UIResource {
|
||||
|
||||
@Override public JTextField createEditorComponent() {
|
||||
JTextField f = new JTextField("", 9);
|
||||
f.setName("ComboBox.textField");
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles all the logic for treating the combo as a button when it is
|
||||
* not editable, and when shouldActLikeButton() is true. This class is a
|
||||
* special ButtonModel, and installed on the arrowButton when appropriate.
|
||||
* It also is installed as a mouse listener and mouse motion listener on
|
||||
* the combo box. In this way, the state between the button and combo
|
||||
* are in sync. Whenever one is "over" both are. Whenever one is pressed,
|
||||
* both are.
|
||||
*/
|
||||
private final class ButtonHandler extends DefaultButtonModel
|
||||
implements MouseListener, PopupMenuListener {
|
||||
/**
|
||||
* Indicates that the mouse is over the combo or the arrow button.
|
||||
* This field only has meaning if buttonWhenNotEnabled is true.
|
||||
*/
|
||||
private boolean over;
|
||||
/**
|
||||
* Indicates that the combo or arrow button has been pressed. This
|
||||
* field only has meaning if buttonWhenNotEnabled is true.
|
||||
*/
|
||||
private boolean pressed;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// State Methods
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Updates the internal "pressed" state. If shouldActLikeButton()
|
||||
* is true, and if this method call will change the internal state,
|
||||
* then the combo and button will be repainted.</p>
|
||||
*
|
||||
* <p>Note that this method is called either when a press event
|
||||
* occurs on the combo box, or on the arrow button.</p>
|
||||
*/
|
||||
private void updatePressed(boolean p) {
|
||||
this.pressed = p && isEnabled();
|
||||
if (shouldActLikeButton()) {
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Updates the internal "over" state. If shouldActLikeButton()
|
||||
* is true, and if this method call will change the internal state,
|
||||
* then the combo and button will be repainted.</p>
|
||||
*
|
||||
* <p>Note that this method is called either when a mouseover/mouseoff event
|
||||
* occurs on the combo box, or on the arrow button.</p>
|
||||
*/
|
||||
private void updateOver(boolean o) {
|
||||
boolean old = isRollover();
|
||||
this.over = o && isEnabled();
|
||||
boolean newo = isRollover();
|
||||
if (shouldActLikeButton() && old != newo) {
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// DefaultButtonModel Methods
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* Ensures that isPressed() will return true if the combo is pressed,
|
||||
* or the arrowButton is pressed, <em>or</em> if the combo popup is
|
||||
* visible. This is the case because a combo box looks pressed when
|
||||
* the popup is visible, and so should the arrow button.
|
||||
*/
|
||||
@Override
|
||||
public boolean isPressed() {
|
||||
boolean b = shouldActLikeButton() ? pressed : super.isPressed();
|
||||
return b || (pressedWhenPopupVisible && comboBox.isPopupVisible());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* Ensures that the armed state is in sync with the pressed state
|
||||
* if shouldActLikeButton is true. Without this method, the arrow
|
||||
* button will not look pressed when the popup is open, regardless
|
||||
* of the result of isPressed() alone.
|
||||
*/
|
||||
@Override
|
||||
public boolean isArmed() {
|
||||
boolean b = shouldActLikeButton() ||
|
||||
(pressedWhenPopupVisible && comboBox.isPopupVisible());
|
||||
return b ? isPressed() : super.isArmed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* Ensures that isRollover() will return true if the combo is
|
||||
* rolled over, or the arrowButton is rolled over.
|
||||
*/
|
||||
@Override
|
||||
public boolean isRollover() {
|
||||
return shouldActLikeButton() ? over : super.isRollover();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* Forwards pressed states to the internal "pressed" field
|
||||
*/
|
||||
@Override
|
||||
public void setPressed(boolean b) {
|
||||
super.setPressed(b);
|
||||
updatePressed(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* Forwards rollover states to the internal "over" field
|
||||
*/
|
||||
@Override
|
||||
public void setRollover(boolean b) {
|
||||
super.setRollover(b);
|
||||
updateOver(b);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// MouseListener/MouseMotionListener Methods
|
||||
//------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent mouseEvent) {
|
||||
updateOver(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent mouseEvent) {
|
||||
updateOver(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent) {
|
||||
updatePressed(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent mouseEvent) {
|
||||
updatePressed(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PopupMenuListener Methods
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* Ensures that the combo box is repainted when the popup is closed.
|
||||
* This avoids a bug where clicking off the combo wasn't causing a repaint,
|
||||
* and thus the combo box still looked pressed even when it was not.
|
||||
*
|
||||
* This bug was only noticed when acting as a button, but may be generally
|
||||
* present. If so, remove the if() block
|
||||
*/
|
||||
@Override
|
||||
public void popupMenuCanceled(PopupMenuEvent e) {
|
||||
if (shouldActLikeButton() || pressedWhenPopupVisible) {
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for repainting combo when editor component gains/looses focus
|
||||
*/
|
||||
private static class EditorFocusHandler implements FocusListener,
|
||||
PropertyChangeListener {
|
||||
private JComboBox comboBox;
|
||||
private ComboBoxEditor editor = null;
|
||||
private Component editorComponent = null;
|
||||
|
||||
private EditorFocusHandler(JComboBox comboBox) {
|
||||
this.comboBox = comboBox;
|
||||
editor = comboBox.getEditor();
|
||||
if (editor != null){
|
||||
editorComponent = editor.getEditorComponent();
|
||||
if (editorComponent != null){
|
||||
editorComponent.addFocusListener(this);
|
||||
}
|
||||
}
|
||||
comboBox.addPropertyChangeListener("editor",this);
|
||||
}
|
||||
|
||||
public void unregister(){
|
||||
comboBox.removePropertyChangeListener(this);
|
||||
if (editorComponent!=null){
|
||||
editorComponent.removeFocusListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Invoked when a component gains the keyboard focus. */
|
||||
public void focusGained(FocusEvent e) {
|
||||
// repaint whole combo on focus gain
|
||||
comboBox.repaint();
|
||||
}
|
||||
|
||||
/** Invoked when a component loses the keyboard focus. */
|
||||
public void focusLost(FocusEvent e) {
|
||||
// repaint whole combo on focus loss
|
||||
comboBox.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the combos editor changes
|
||||
*
|
||||
* @param evt A PropertyChangeEvent object describing the event source and
|
||||
* the property that has changed.
|
||||
*/
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
ComboBoxEditor newEditor = comboBox.getEditor();
|
||||
if (editor != newEditor){
|
||||
if (editorComponent!=null){
|
||||
editorComponent.removeFocusListener(this);
|
||||
}
|
||||
editor = newEditor;
|
||||
if (editor != null){
|
||||
editorComponent = editor.getEditorComponent();
|
||||
if (editorComponent != null){
|
||||
editorComponent.addFocusListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
90
jdkSrc/jdk8/javax/swing/plaf/synth/SynthComboPopup.java
Normal file
90
jdkSrc/jdk8/javax/swing/plaf/synth/SynthComboPopup.java
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ComboBoxUI;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import java.awt.*;
|
||||
|
||||
|
||||
/**
|
||||
* Synth's ComboPopup.
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class SynthComboPopup extends BasicComboPopup {
|
||||
public SynthComboPopup( JComboBox combo ) {
|
||||
super(combo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the list which is used to hold the combo box items in the
|
||||
* popup. This method is called when the UI class
|
||||
* is created.
|
||||
*
|
||||
* @see #createList
|
||||
*/
|
||||
@Override
|
||||
protected void configureList() {
|
||||
list.setFont( comboBox.getFont() );
|
||||
list.setCellRenderer( comboBox.getRenderer() );
|
||||
list.setFocusable( false );
|
||||
list.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
|
||||
int selectedIndex = comboBox.getSelectedIndex();
|
||||
if ( selectedIndex == -1 ) {
|
||||
list.clearSelection();
|
||||
}
|
||||
else {
|
||||
list.setSelectedIndex( selectedIndex );
|
||||
list.ensureIndexIsVisible( selectedIndex );
|
||||
}
|
||||
installListListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* Overridden to take into account any popup insets specified in
|
||||
* SynthComboBoxUI
|
||||
*/
|
||||
@Override
|
||||
protected Rectangle computePopupBounds(int px, int py, int pw, int ph) {
|
||||
ComboBoxUI ui = comboBox.getUI();
|
||||
if (ui instanceof SynthComboBoxUI) {
|
||||
SynthComboBoxUI sui = (SynthComboBoxUI) ui;
|
||||
if (sui.popupInsets != null) {
|
||||
Insets i = sui.popupInsets;
|
||||
return super.computePopupBounds(
|
||||
px + i.left,
|
||||
py + i.top,
|
||||
pw - i.left - i.right,
|
||||
ph - i.top - i.bottom);
|
||||
}
|
||||
}
|
||||
return super.computePopupBounds(px, py, pw, ph);
|
||||
}
|
||||
}
|
||||
71
jdkSrc/jdk8/javax/swing/plaf/synth/SynthConstants.java
Normal file
71
jdkSrc/jdk8/javax/swing/plaf/synth/SynthConstants.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Constants used by Synth. Not all Components support all states. A
|
||||
* Component will at least be in one of the primary states. That is, the
|
||||
* return value from <code>SynthContext.getComponentState()</code> will at
|
||||
* least be one of <code>ENABLED</code>, <code>MOUSE_OVER</code>,
|
||||
* <code>PRESSED</code> or <code>DISABLED</code>, and may also contain
|
||||
* <code>FOCUSED</code>, <code>SELECTED</code> or <code>DEFAULT</code>.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface SynthConstants {
|
||||
/**
|
||||
* Primary state indicating the component is enabled.
|
||||
*/
|
||||
public static final int ENABLED = 1 << 0;
|
||||
/**
|
||||
* Primary state indicating the mouse is over the region.
|
||||
*/
|
||||
public static final int MOUSE_OVER = 1 << 1;
|
||||
/**
|
||||
* Primary state indicating the region is in a pressed state. Pressed
|
||||
* does not necessarily mean the user has pressed the mouse button.
|
||||
*/
|
||||
public static final int PRESSED = 1 << 2;
|
||||
/**
|
||||
* Primary state indicating the region is not enabled.
|
||||
*/
|
||||
public static final int DISABLED = 1 << 3;
|
||||
|
||||
/**
|
||||
* Indicates the region has focus.
|
||||
*/
|
||||
public static final int FOCUSED = 1 << 8;
|
||||
/**
|
||||
* Indicates the region is selected.
|
||||
*/
|
||||
public static final int SELECTED = 1 << 9;
|
||||
/**
|
||||
* Indicates the region is the default. This is typically used for buttons
|
||||
* to indicate this button is somehow special.
|
||||
*/
|
||||
public static final int DEFAULT = 1 << 10;
|
||||
}
|
||||
178
jdkSrc/jdk8/javax/swing/plaf/synth/SynthContext.java
Normal file
178
jdkSrc/jdk8/javax/swing/plaf/synth/SynthContext.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
* An immutable transient object containing contextual information about
|
||||
* a <code>Region</code>. A <code>SynthContext</code> should only be
|
||||
* considered valid for the duration
|
||||
* of the method it is passed to. In other words you should not cache
|
||||
* a <code>SynthContext</code> that is passed to you and expect it to
|
||||
* remain valid.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Scott Violet
|
||||
*/
|
||||
public class SynthContext {
|
||||
private static final Queue<SynthContext> queue = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private JComponent component;
|
||||
private Region region;
|
||||
private SynthStyle style;
|
||||
private int state;
|
||||
|
||||
static SynthContext getContext(JComponent c, SynthStyle style, int state) {
|
||||
return getContext(c, SynthLookAndFeel.getRegion(c), style, state);
|
||||
}
|
||||
|
||||
static SynthContext getContext(JComponent component,
|
||||
Region region, SynthStyle style,
|
||||
int state) {
|
||||
SynthContext context = queue.poll();
|
||||
if (context == null) {
|
||||
context = new SynthContext();
|
||||
}
|
||||
context.reset(component, region, style, state);
|
||||
return context;
|
||||
}
|
||||
|
||||
static void releaseContext(SynthContext context) {
|
||||
queue.offer(context);
|
||||
}
|
||||
|
||||
SynthContext() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SynthContext with the specified values. This is meant
|
||||
* for subclasses and custom UI implementors. You very rarely need to
|
||||
* construct a SynthContext, though some methods will take one.
|
||||
*
|
||||
* @param component JComponent
|
||||
* @param region Identifies the portion of the JComponent
|
||||
* @param style Style associated with the component
|
||||
* @param state State of the component as defined in SynthConstants.
|
||||
* @throws NullPointerException if component, region of style is null.
|
||||
*/
|
||||
public SynthContext(JComponent component, Region region, SynthStyle style,
|
||||
int state) {
|
||||
if (component == null || region == null || style == null) {
|
||||
throw new NullPointerException(
|
||||
"You must supply a non-null component, region and style");
|
||||
}
|
||||
reset(component, region, style, state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hosting component containing the region.
|
||||
*
|
||||
* @return Hosting Component
|
||||
*/
|
||||
public JComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Region identifying this state.
|
||||
*
|
||||
* @return Region of the hosting component
|
||||
*/
|
||||
public Region getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for <code>getRegion().isSubregion()</code>.
|
||||
*/
|
||||
boolean isSubregion() {
|
||||
return getRegion().isSubregion();
|
||||
}
|
||||
|
||||
void setStyle(SynthStyle style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the style associated with this Region.
|
||||
*
|
||||
* @return SynthStyle associated with the region.
|
||||
*/
|
||||
public SynthStyle getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
void setComponentState(int state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of the widget, which is a bitmask of the
|
||||
* values defined in <code>SynthConstants</code>. A region will at least
|
||||
* be in one of
|
||||
* <code>ENABLED</code>, <code>MOUSE_OVER</code>, <code>PRESSED</code>
|
||||
* or <code>DISABLED</code>.
|
||||
*
|
||||
* @see SynthConstants
|
||||
* @return State of Component
|
||||
*/
|
||||
public int getComponentState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of the Context.
|
||||
*/
|
||||
void reset(JComponent component, Region region, SynthStyle style,
|
||||
int state) {
|
||||
this.component = component;
|
||||
this.region = region;
|
||||
this.style = style;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
this.component = null;
|
||||
this.style = null;
|
||||
releaseContext(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the Painter from the current SynthStyle.
|
||||
* This will NEVER return null.
|
||||
*/
|
||||
SynthPainter getPainter() {
|
||||
SynthPainter painter = getStyle().getPainter(this);
|
||||
|
||||
if (painter != null) {
|
||||
return painter;
|
||||
}
|
||||
return SynthPainter.NULL_PAINTER;
|
||||
}
|
||||
}
|
||||
47
jdkSrc/jdk8/javax/swing/plaf/synth/SynthDefaultLookup.java
Normal file
47
jdkSrc/jdk8/javax/swing/plaf/synth/SynthDefaultLookup.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import sun.swing.DefaultLookup;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
|
||||
/**
|
||||
* SynthDefaultLookup redirects all lookup calls to the SynthContext.
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class SynthDefaultLookup extends DefaultLookup {
|
||||
public Object getDefault(JComponent c, ComponentUI ui, String key) {
|
||||
if (!(ui instanceof SynthUI)) {
|
||||
Object value = super.getDefault(c, ui, key);
|
||||
return value;
|
||||
}
|
||||
SynthContext context = ((SynthUI)ui).getContext(c);
|
||||
Object value = context.getStyle().get(context, key);
|
||||
context.dispose();
|
||||
return value;
|
||||
}
|
||||
}
|
||||
253
jdkSrc/jdk8/javax/swing/plaf/synth/SynthDesktopIconUI.java
Normal file
253
jdkSrc/jdk8/javax/swing/plaf/synth/SynthDesktopIconUI.java
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicDesktopIconUI;
|
||||
import java.beans.*;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for a minimized internal frame on a desktop.
|
||||
*
|
||||
* @author Joshua Outwater
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthDesktopIconUI extends BasicDesktopIconUI
|
||||
implements SynthUI, PropertyChangeListener {
|
||||
private SynthStyle style;
|
||||
private Handler handler = new Handler();
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthDesktopIconUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
|
||||
iconPane = new JToggleButton(frame.getTitle(), frame.getFrameIcon()) {
|
||||
@Override public String getToolTipText() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Override public JPopupMenu getComponentPopupMenu() {
|
||||
return frame.getComponentPopupMenu();
|
||||
}
|
||||
};
|
||||
ToolTipManager.sharedInstance().registerComponent(iconPane);
|
||||
iconPane.setFont(desktopIcon.getFont());
|
||||
iconPane.setBackground(desktopIcon.getBackground());
|
||||
iconPane.setForeground(desktopIcon.getForeground());
|
||||
} else {
|
||||
iconPane = new SynthInternalFrameTitlePane(frame);
|
||||
iconPane.setName("InternalFrame.northPane");
|
||||
}
|
||||
desktopIcon.setLayout(new BorderLayout());
|
||||
desktopIcon.add(iconPane, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
desktopIcon.addPropertyChangeListener(this);
|
||||
|
||||
if (iconPane instanceof JToggleButton) {
|
||||
frame.addPropertyChangeListener(this);
|
||||
((JToggleButton)iconPane).addActionListener(handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
if (iconPane instanceof JToggleButton) {
|
||||
((JToggleButton)iconPane).removeActionListener(handler);
|
||||
frame.removePropertyChangeListener(this);
|
||||
}
|
||||
desktopIcon.removePropertyChangeListener(this);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(desktopIcon);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(desktopIcon, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintDesktopIconBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintDesktopIconBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getSource() instanceof JInternalFrame.JDesktopIcon) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle((JInternalFrame.JDesktopIcon)evt.getSource());
|
||||
}
|
||||
} else if (evt.getSource() instanceof JInternalFrame) {
|
||||
JInternalFrame frame = (JInternalFrame)evt.getSource();
|
||||
if (iconPane instanceof JToggleButton) {
|
||||
JToggleButton button = (JToggleButton)iconPane;
|
||||
String prop = evt.getPropertyName();
|
||||
if (prop == "title") {
|
||||
button.setText((String)evt.getNewValue());
|
||||
} else if (prop == "frameIcon") {
|
||||
button.setIcon((Icon)evt.getNewValue());
|
||||
} else if (prop == JInternalFrame.IS_ICON_PROPERTY ||
|
||||
prop == JInternalFrame.IS_SELECTED_PROPERTY) {
|
||||
button.setSelected(!frame.isIcon() && frame.isSelected());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class Handler implements ActionListener {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
if (evt.getSource() instanceof JToggleButton) {
|
||||
// Either iconify the frame or deiconify and activate it.
|
||||
JToggleButton button = (JToggleButton)evt.getSource();
|
||||
try {
|
||||
boolean selected = button.isSelected();
|
||||
if (!selected && !frame.isIconifiable()) {
|
||||
button.setSelected(true);
|
||||
} else {
|
||||
frame.setIcon(!selected);
|
||||
if (selected) {
|
||||
frame.setSelected(true);
|
||||
}
|
||||
}
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
511
jdkSrc/jdk8/javax/swing/plaf/synth/SynthDesktopPaneUI.java
Normal file
511
jdkSrc/jdk8/javax/swing/plaf/synth/SynthDesktopPaneUI.java
Normal file
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicDesktopPaneUI;
|
||||
import java.beans.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JDesktopPane}.
|
||||
*
|
||||
* @author Joshua Outwater
|
||||
* @author Steve Wilson
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements
|
||||
PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
private TaskBar taskBar;
|
||||
private DesktopManager oldDesktopManager;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthDesktopPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
desktop.addPropertyChangeListener(this);
|
||||
if (taskBar != null) {
|
||||
// Listen for desktop being resized
|
||||
desktop.addComponentListener(taskBar);
|
||||
// Listen for frames being added to desktop
|
||||
desktop.addContainerListener(taskBar);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(desktop);
|
||||
|
||||
if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
|
||||
taskBar = new TaskBar();
|
||||
|
||||
for (Component comp : desktop.getComponents()) {
|
||||
JInternalFrame.JDesktopIcon desktopIcon;
|
||||
|
||||
if (comp instanceof JInternalFrame.JDesktopIcon) {
|
||||
desktopIcon = (JInternalFrame.JDesktopIcon)comp;
|
||||
} else if (comp instanceof JInternalFrame) {
|
||||
desktopIcon = ((JInternalFrame)comp).getDesktopIcon();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
// Move desktopIcon from desktop to taskBar
|
||||
if (desktopIcon.getParent() == desktop) {
|
||||
desktop.remove(desktopIcon);
|
||||
}
|
||||
if (desktopIcon.getParent() != taskBar) {
|
||||
taskBar.add(desktopIcon);
|
||||
desktopIcon.getInternalFrame().addComponentListener(
|
||||
taskBar);
|
||||
}
|
||||
}
|
||||
taskBar.setBackground(desktop.getBackground());
|
||||
desktop.add(taskBar,
|
||||
Integer.valueOf(JLayeredPane.PALETTE_LAYER.intValue() + 1));
|
||||
if (desktop.isShowing()) {
|
||||
taskBar.adjustSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStyle(JDesktopPane c) {
|
||||
SynthStyle oldStyle = style;
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
if (taskBar != null) {
|
||||
desktop.removeComponentListener(taskBar);
|
||||
desktop.removeContainerListener(taskBar);
|
||||
}
|
||||
desktop.removePropertyChangeListener(this);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(desktop, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
if (taskBar != null) {
|
||||
for (Component comp : taskBar.getComponents()) {
|
||||
JInternalFrame.JDesktopIcon desktopIcon =
|
||||
(JInternalFrame.JDesktopIcon)comp;
|
||||
taskBar.remove(desktopIcon);
|
||||
desktopIcon.setPreferredSize(null);
|
||||
JInternalFrame f = desktopIcon.getInternalFrame();
|
||||
if (f.isIcon()) {
|
||||
desktop.add(desktopIcon);
|
||||
}
|
||||
f.removeComponentListener(taskBar);
|
||||
}
|
||||
desktop.remove(taskBar);
|
||||
taskBar = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDesktopManager() {
|
||||
if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
|
||||
desktopManager = oldDesktopManager = desktop.getDesktopManager();
|
||||
if (!(desktopManager instanceof SynthDesktopManager)) {
|
||||
desktopManager = new SynthDesktopManager();
|
||||
desktop.setDesktopManager(desktopManager);
|
||||
}
|
||||
} else {
|
||||
super.installDesktopManager();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDesktopManager() {
|
||||
if (oldDesktopManager != null && !(oldDesktopManager instanceof UIResource)) {
|
||||
desktopManager = desktop.getDesktopManager();
|
||||
if (desktopManager == null || desktopManager instanceof UIResource) {
|
||||
desktop.setDesktopManager(oldDesktopManager);
|
||||
}
|
||||
}
|
||||
oldDesktopManager = null;
|
||||
super.uninstallDesktopManager();
|
||||
}
|
||||
|
||||
static class TaskBar extends JPanel implements ComponentListener, ContainerListener {
|
||||
TaskBar() {
|
||||
setOpaque(true);
|
||||
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0) {
|
||||
public void layoutContainer(Container target) {
|
||||
// First shrink buttons to fit
|
||||
Component[] comps = target.getComponents();
|
||||
int n = comps.length;
|
||||
if (n > 0) {
|
||||
// Start with the largest preferred width
|
||||
int prefWidth = 0;
|
||||
for (Component c : comps) {
|
||||
c.setPreferredSize(null);
|
||||
Dimension prefSize = c.getPreferredSize();
|
||||
if (prefSize.width > prefWidth) {
|
||||
prefWidth = prefSize.width;
|
||||
}
|
||||
}
|
||||
// Shrink equally to fit if needed
|
||||
Insets insets = target.getInsets();
|
||||
int tw = target.getWidth() - insets.left - insets.right;
|
||||
int w = Math.min(prefWidth, Math.max(10, tw/n));
|
||||
for (Component c : comps) {
|
||||
Dimension prefSize = c.getPreferredSize();
|
||||
c.setPreferredSize(new Dimension(w, prefSize.height));
|
||||
}
|
||||
}
|
||||
super.layoutContainer(target);
|
||||
}
|
||||
});
|
||||
|
||||
// PENDING: This should be handled by the painter
|
||||
setBorder(new BevelBorder(BevelBorder.RAISED) {
|
||||
protected void paintRaisedBevel(Component c, Graphics g,
|
||||
int x, int y, int w, int h) {
|
||||
Color oldColor = g.getColor();
|
||||
g.translate(x, y);
|
||||
g.setColor(getHighlightOuterColor(c));
|
||||
g.drawLine(0, 0, 0, h-2);
|
||||
g.drawLine(1, 0, w-2, 0);
|
||||
g.setColor(getShadowOuterColor(c));
|
||||
g.drawLine(0, h-1, w-1, h-1);
|
||||
g.drawLine(w-1, 0, w-1, h-2);
|
||||
g.translate(-x, -y);
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void adjustSize() {
|
||||
JDesktopPane desktop = (JDesktopPane)getParent();
|
||||
if (desktop != null) {
|
||||
int height = getPreferredSize().height;
|
||||
Insets insets = getInsets();
|
||||
if (height == insets.top + insets.bottom) {
|
||||
if (getHeight() <= height) {
|
||||
// Initial size, because we have no buttons yet
|
||||
height += 21;
|
||||
} else {
|
||||
// We already have a good height
|
||||
height = getHeight();
|
||||
}
|
||||
}
|
||||
setBounds(0, desktop.getHeight() - height, desktop.getWidth(), height);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ComponentListener interface
|
||||
|
||||
public void componentResized(ComponentEvent e) {
|
||||
if (e.getSource() instanceof JDesktopPane) {
|
||||
adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
public void componentMoved(ComponentEvent e){}
|
||||
|
||||
public void componentShown(ComponentEvent e) {
|
||||
if (e.getSource() instanceof JInternalFrame) {
|
||||
adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
if (e.getSource() instanceof JInternalFrame) {
|
||||
((JInternalFrame)e.getSource()).getDesktopIcon().setVisible(false);
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerListener interface
|
||||
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
if (e.getChild() instanceof JInternalFrame) {
|
||||
JDesktopPane desktop = (JDesktopPane)e.getSource();
|
||||
JInternalFrame f = (JInternalFrame)e.getChild();
|
||||
JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();
|
||||
for (Component comp : getComponents()) {
|
||||
if (comp == desktopIcon) {
|
||||
// We have it already
|
||||
return;
|
||||
}
|
||||
}
|
||||
add(desktopIcon);
|
||||
f.addComponentListener(this);
|
||||
if (getComponentCount() == 1) {
|
||||
adjustSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void componentRemoved(ContainerEvent e) {
|
||||
if (e.getChild() instanceof JInternalFrame) {
|
||||
JInternalFrame f = (JInternalFrame)e.getChild();
|
||||
if (!f.isIcon()) {
|
||||
// Frame was removed without using setClosed(true)
|
||||
remove(f.getDesktopIcon());
|
||||
f.removeComponentListener(this);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SynthDesktopManager extends DefaultDesktopManager implements UIResource {
|
||||
|
||||
public void maximizeFrame(JInternalFrame f) {
|
||||
if (f.isIcon()) {
|
||||
try {
|
||||
f.setIcon(false);
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
} else {
|
||||
f.setNormalBounds(f.getBounds());
|
||||
Component desktop = f.getParent();
|
||||
setBoundsForFrame(f, 0, 0,
|
||||
desktop.getWidth(),
|
||||
desktop.getHeight() - taskBar.getHeight());
|
||||
}
|
||||
|
||||
try {
|
||||
f.setSelected(true);
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
}
|
||||
|
||||
public void iconifyFrame(JInternalFrame f) {
|
||||
JInternalFrame.JDesktopIcon desktopIcon;
|
||||
Container c = f.getParent();
|
||||
JDesktopPane d = f.getDesktopPane();
|
||||
boolean findNext = f.isSelected();
|
||||
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
desktopIcon = f.getDesktopIcon();
|
||||
|
||||
if (!f.isMaximum()) {
|
||||
f.setNormalBounds(f.getBounds());
|
||||
}
|
||||
c.remove(f);
|
||||
c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
|
||||
try {
|
||||
f.setSelected(false);
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
|
||||
// Get topmost of the remaining frames
|
||||
if (findNext) {
|
||||
for (Component comp : c.getComponents()) {
|
||||
if (comp instanceof JInternalFrame) {
|
||||
try {
|
||||
((JInternalFrame)comp).setSelected(true);
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
((JInternalFrame)comp).moveToFront();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void deiconifyFrame(JInternalFrame f) {
|
||||
JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();
|
||||
Container c = desktopIcon.getParent();
|
||||
if (c != null) {
|
||||
c = c.getParent();
|
||||
if (c != null) {
|
||||
c.add(f);
|
||||
if (f.isMaximum()) {
|
||||
int w = c.getWidth();
|
||||
int h = c.getHeight() - taskBar.getHeight();
|
||||
if (f.getWidth() != w || f.getHeight() != h) {
|
||||
setBoundsForFrame(f, 0, 0, w, h);
|
||||
}
|
||||
}
|
||||
if (f.isSelected()) {
|
||||
f.moveToFront();
|
||||
} else {
|
||||
try {
|
||||
f.setSelected(true);
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeIconFor(JInternalFrame f) {
|
||||
super.removeIconFor(f);
|
||||
taskBar.validate();
|
||||
}
|
||||
|
||||
public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
|
||||
super.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
|
||||
if (taskBar != null && newY >= taskBar.getY()) {
|
||||
f.setLocation(f.getX(), taskBar.getY()-f.getInsets().top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintDesktopPaneBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintDesktopPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle((JDesktopPane)evt.getSource());
|
||||
}
|
||||
if (evt.getPropertyName() == "ancestor" && taskBar != null) {
|
||||
taskBar.adjustSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
203
jdkSrc/jdk8/javax/swing/plaf/synth/SynthEditorPaneUI.java
Normal file
203
jdkSrc/jdk8/javax/swing/plaf/synth/SynthEditorPaneUI.java
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicEditorPaneUI;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JEditorPane}.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI {
|
||||
private SynthStyle style;
|
||||
/*
|
||||
* I would prefer to use UIResource instad of this.
|
||||
* Unfortunately Boolean is a final class
|
||||
*/
|
||||
private Boolean localTrue = Boolean.TRUE;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthEditorPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
// Installs the text cursor on the component
|
||||
super.installDefaults();
|
||||
JComponent c = getComponent();
|
||||
Object clientProperty =
|
||||
c.getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
|
||||
if (clientProperty == null) {
|
||||
c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, localTrue);
|
||||
}
|
||||
updateStyle(getComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(getComponent(), ENABLED);
|
||||
JComponent c = getComponent();
|
||||
c.putClientProperty("caretAspectRatio", null);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
Object clientProperty =
|
||||
c.getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
|
||||
if (clientProperty == localTrue) {
|
||||
c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES,
|
||||
Boolean.FALSE);
|
||||
}
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a bound property is changed
|
||||
* on the associated JTextComponent. This is a hook
|
||||
* which UI implementations may change to reflect how the
|
||||
* UI displays bound properties of JTextComponent subclasses.
|
||||
* This is implemented to rebuild the ActionMap based upon an
|
||||
* EditorKit change.
|
||||
*
|
||||
* @param evt the property change event
|
||||
*/
|
||||
@Override
|
||||
protected void propertyChange(PropertyChangeEvent evt) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle((JTextComponent)evt.getSource());
|
||||
}
|
||||
super.propertyChange(evt);
|
||||
}
|
||||
|
||||
private void updateStyle(JTextComponent comp) {
|
||||
SynthContext context = getContext(comp, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
|
||||
if (style != oldStyle) {
|
||||
SynthTextFieldUI.updateStyle(comp, context, getPropertyPrefix());
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
paintBackground(context, g, c);
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
super.paint(g, getComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
// Overriden to do nothing, all our painting is done from update/paint.
|
||||
}
|
||||
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintEditorPaneBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintEditorPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JFormattedTextField}.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthFormattedTextFieldUI extends SynthTextFieldUI {
|
||||
/**
|
||||
* Creates a UI for a JFormattedTextField.
|
||||
*
|
||||
* @param c the formatted text field
|
||||
* @return the UI
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthFormattedTextFieldUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the name used as a key to lookup properties through the
|
||||
* UIManager. This is used as a prefix to all the standard
|
||||
* text properties.
|
||||
*
|
||||
* @return the name "FormattedTextField"
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "FormattedTextField";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintFormattedTextFieldBackground(context, g, 0,
|
||||
0, c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintFormattedTextFieldBorder(context, g, x, y,
|
||||
w, h);
|
||||
}
|
||||
}
|
||||
657
jdkSrc/jdk8/javax/swing/plaf/synth/SynthGraphicsUtils.java
Normal file
657
jdkSrc/jdk8/javax/swing/plaf/synth/SynthGraphicsUtils.java
Normal file
@@ -0,0 +1,657 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import sun.swing.SwingUtilities2;
|
||||
import sun.swing.MenuItemLayoutHelper;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.text.*;
|
||||
import sun.swing.plaf.synth.*;
|
||||
|
||||
/**
|
||||
* Wrapper for primitive graphics calls.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Scott Violet
|
||||
*/
|
||||
public class SynthGraphicsUtils {
|
||||
// These are used in the text painting code to avoid allocating a bunch of
|
||||
// garbage.
|
||||
private Rectangle paintIconR = new Rectangle();
|
||||
private Rectangle paintTextR = new Rectangle();
|
||||
private Rectangle paintViewR = new Rectangle();
|
||||
private Insets paintInsets = new Insets(0, 0, 0, 0);
|
||||
|
||||
// These Rectangles/Insets are used in the text size calculation to avoid a
|
||||
// a bunch of garbage.
|
||||
private Rectangle iconR = new Rectangle();
|
||||
private Rectangle textR = new Rectangle();
|
||||
private Rectangle viewR = new Rectangle();
|
||||
private Insets viewSizingInsets = new Insets(0, 0, 0, 0);
|
||||
|
||||
/**
|
||||
* Creates a <code>SynthGraphicsUtils</code>.
|
||||
*/
|
||||
public SynthGraphicsUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a line between the two end points.
|
||||
*
|
||||
* @param context Identifies hosting region.
|
||||
* @param paintKey Identifies the portion of the component being asked
|
||||
* to paint, may be null.
|
||||
* @param g Graphics object to paint to
|
||||
* @param x1 x origin
|
||||
* @param y1 y origin
|
||||
* @param x2 x destination
|
||||
* @param y2 y destination
|
||||
*/
|
||||
public void drawLine(SynthContext context, Object paintKey,
|
||||
Graphics g, int x1, int y1, int x2, int y2) {
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a line between the two end points.
|
||||
* <p>This implementation supports only one line style key,
|
||||
* <code>"dashed"</code>. The <code>"dashed"</code> line style is applied
|
||||
* only to vertical and horizontal lines.
|
||||
* <p>Specifying <code>null</code> or any key different from
|
||||
* <code>"dashed"</code> will draw solid lines.
|
||||
*
|
||||
* @param context identifies hosting region
|
||||
* @param paintKey identifies the portion of the component being asked
|
||||
* to paint, may be null
|
||||
* @param g Graphics object to paint to
|
||||
* @param x1 x origin
|
||||
* @param y1 y origin
|
||||
* @param x2 x destination
|
||||
* @param y2 y destination
|
||||
* @param styleKey identifies the requested style of the line (e.g. "dashed")
|
||||
* @since 1.6
|
||||
*/
|
||||
public void drawLine(SynthContext context, Object paintKey,
|
||||
Graphics g, int x1, int y1, int x2, int y2,
|
||||
Object styleKey) {
|
||||
if ("dashed".equals(styleKey)) {
|
||||
// draw vertical line
|
||||
if (x1 == x2) {
|
||||
y1 += (y1 % 2);
|
||||
|
||||
for (int y = y1; y <= y2; y+=2) {
|
||||
g.drawLine(x1, y, x2, y);
|
||||
}
|
||||
// draw horizontal line
|
||||
} else if (y1 == y2) {
|
||||
x1 += (x1 % 2);
|
||||
|
||||
for (int x = x1; x <= x2; x+=2) {
|
||||
g.drawLine(x, y1, x, y2);
|
||||
}
|
||||
// oblique lines are not supported
|
||||
}
|
||||
} else {
|
||||
drawLine(context, paintKey, g, x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lays out text and an icon returning, by reference, the location to
|
||||
* place the icon and text.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param fm FontMetrics for the Font to use, this may be ignored
|
||||
* @param text Text to layout
|
||||
* @param icon Icon to layout
|
||||
* @param hAlign horizontal alignment
|
||||
* @param vAlign vertical alignment
|
||||
* @param hTextPosition horizontal text position
|
||||
* @param vTextPosition vertical text position
|
||||
* @param viewR Rectangle to layout text and icon in.
|
||||
* @param iconR Rectangle to place icon bounds in
|
||||
* @param textR Rectangle to place text in
|
||||
* @param iconTextGap gap between icon and text
|
||||
*/
|
||||
public String layoutText(SynthContext ss, FontMetrics fm,
|
||||
String text, Icon icon, int hAlign,
|
||||
int vAlign, int hTextPosition,
|
||||
int vTextPosition, Rectangle viewR,
|
||||
Rectangle iconR, Rectangle textR, int iconTextGap) {
|
||||
if (icon instanceof SynthIcon) {
|
||||
SynthIconWrapper wrapper = SynthIconWrapper.get((SynthIcon)icon,
|
||||
ss);
|
||||
String formattedText = SwingUtilities.layoutCompoundLabel(
|
||||
ss.getComponent(), fm, text, wrapper, vAlign, hAlign,
|
||||
vTextPosition, hTextPosition, viewR, iconR, textR,
|
||||
iconTextGap);
|
||||
SynthIconWrapper.release(wrapper);
|
||||
return formattedText;
|
||||
}
|
||||
return SwingUtilities.layoutCompoundLabel(
|
||||
ss.getComponent(), fm, text, icon, vAlign, hAlign,
|
||||
vTextPosition, hTextPosition, viewR, iconR, textR,
|
||||
iconTextGap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the passed in string.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param font Font to use
|
||||
* @param metrics FontMetrics, may be ignored
|
||||
* @param text Text to get size of.
|
||||
*/
|
||||
public int computeStringWidth(SynthContext ss, Font font,
|
||||
FontMetrics metrics, String text) {
|
||||
return SwingUtilities2.stringWidth(ss.getComponent(), metrics,
|
||||
text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum size needed to properly render an icon and text.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param font Font to use
|
||||
* @param text Text to layout
|
||||
* @param icon Icon to layout
|
||||
* @param hAlign horizontal alignment
|
||||
* @param vAlign vertical alignment
|
||||
* @param hTextPosition horizontal text position
|
||||
* @param vTextPosition vertical text position
|
||||
* @param iconTextGap gap between icon and text
|
||||
* @param mnemonicIndex Index into text to render the mnemonic at, -1
|
||||
* indicates no mnemonic.
|
||||
*/
|
||||
public Dimension getMinimumSize(SynthContext ss, Font font, String text,
|
||||
Icon icon, int hAlign, int vAlign, int hTextPosition,
|
||||
int vTextPosition, int iconTextGap, int mnemonicIndex) {
|
||||
JComponent c = ss.getComponent();
|
||||
Dimension size = getPreferredSize(ss, font, text, icon, hAlign,
|
||||
vAlign, hTextPosition, vTextPosition,
|
||||
iconTextGap, mnemonicIndex);
|
||||
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
|
||||
|
||||
if (v != null) {
|
||||
size.width -= v.getPreferredSpan(View.X_AXIS) -
|
||||
v.getMinimumSpan(View.X_AXIS);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum size needed to properly render an icon and text.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param font Font to use
|
||||
* @param text Text to layout
|
||||
* @param icon Icon to layout
|
||||
* @param hAlign horizontal alignment
|
||||
* @param vAlign vertical alignment
|
||||
* @param hTextPosition horizontal text position
|
||||
* @param vTextPosition vertical text position
|
||||
* @param iconTextGap gap between icon and text
|
||||
* @param mnemonicIndex Index into text to render the mnemonic at, -1
|
||||
* indicates no mnemonic.
|
||||
*/
|
||||
public Dimension getMaximumSize(SynthContext ss, Font font, String text,
|
||||
Icon icon, int hAlign, int vAlign, int hTextPosition,
|
||||
int vTextPosition, int iconTextGap, int mnemonicIndex) {
|
||||
JComponent c = ss.getComponent();
|
||||
Dimension size = getPreferredSize(ss, font, text, icon, hAlign,
|
||||
vAlign, hTextPosition, vTextPosition,
|
||||
iconTextGap, mnemonicIndex);
|
||||
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
|
||||
|
||||
if (v != null) {
|
||||
size.width += v.getMaximumSpan(View.X_AXIS) -
|
||||
v.getPreferredSpan(View.X_AXIS);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum height of the the Font from the passed in
|
||||
* SynthContext.
|
||||
*
|
||||
* @param context SynthContext used to determine font.
|
||||
* @return maximum height of the characters for the font from the passed
|
||||
* in context.
|
||||
*/
|
||||
public int getMaximumCharHeight(SynthContext context) {
|
||||
FontMetrics fm = context.getComponent().getFontMetrics(
|
||||
context.getStyle().getFont(context));
|
||||
return (fm.getAscent() + fm.getDescent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred size needed to properly render an icon and text.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param font Font to use
|
||||
* @param text Text to layout
|
||||
* @param icon Icon to layout
|
||||
* @param hAlign horizontal alignment
|
||||
* @param vAlign vertical alignment
|
||||
* @param hTextPosition horizontal text position
|
||||
* @param vTextPosition vertical text position
|
||||
* @param iconTextGap gap between icon and text
|
||||
* @param mnemonicIndex Index into text to render the mnemonic at, -1
|
||||
* indicates no mnemonic.
|
||||
*/
|
||||
public Dimension getPreferredSize(SynthContext ss, Font font, String text,
|
||||
Icon icon, int hAlign, int vAlign, int hTextPosition,
|
||||
int vTextPosition, int iconTextGap, int mnemonicIndex) {
|
||||
JComponent c = ss.getComponent();
|
||||
Insets insets = c.getInsets(viewSizingInsets);
|
||||
int dx = insets.left + insets.right;
|
||||
int dy = insets.top + insets.bottom;
|
||||
|
||||
if (icon == null && (text == null || font == null)) {
|
||||
return new Dimension(dx, dy);
|
||||
}
|
||||
else if ((text == null) || ((icon != null) && (font == null))) {
|
||||
return new Dimension(SynthIcon.getIconWidth(icon, ss) + dx,
|
||||
SynthIcon.getIconHeight(icon, ss) + dy);
|
||||
}
|
||||
else {
|
||||
FontMetrics fm = c.getFontMetrics(font);
|
||||
|
||||
iconR.x = iconR.y = iconR.width = iconR.height = 0;
|
||||
textR.x = textR.y = textR.width = textR.height = 0;
|
||||
viewR.x = dx;
|
||||
viewR.y = dy;
|
||||
viewR.width = viewR.height = Short.MAX_VALUE;
|
||||
|
||||
layoutText(ss, fm, text, icon, hAlign, vAlign,
|
||||
hTextPosition, vTextPosition, viewR, iconR, textR,
|
||||
iconTextGap);
|
||||
int x1 = Math.min(iconR.x, textR.x);
|
||||
int x2 = Math.max(iconR.x + iconR.width, textR.x + textR.width);
|
||||
int y1 = Math.min(iconR.y, textR.y);
|
||||
int y2 = Math.max(iconR.y + iconR.height, textR.y + textR.height);
|
||||
Dimension rv = new Dimension(x2 - x1, y2 - y1);
|
||||
|
||||
rv.width += dx;
|
||||
rv.height += dy;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints text at the specified location. This will not attempt to
|
||||
* render the text as html nor will it offset by the insets of the
|
||||
* component.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param g Graphics used to render string in.
|
||||
* @param text Text to render
|
||||
* @param bounds Bounds of the text to be drawn.
|
||||
* @param mnemonicIndex Index to draw string at.
|
||||
*/
|
||||
public void paintText(SynthContext ss, Graphics g, String text,
|
||||
Rectangle bounds, int mnemonicIndex) {
|
||||
paintText(ss, g, text, bounds.x, bounds.y, mnemonicIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints text at the specified location. This will not attempt to
|
||||
* render the text as html nor will it offset by the insets of the
|
||||
* component.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param g Graphics used to render string in.
|
||||
* @param text Text to render
|
||||
* @param x X location to draw text at.
|
||||
* @param y Upper left corner to draw text at.
|
||||
* @param mnemonicIndex Index to draw string at.
|
||||
*/
|
||||
public void paintText(SynthContext ss, Graphics g, String text,
|
||||
int x, int y, int mnemonicIndex) {
|
||||
if (text != null) {
|
||||
JComponent c = ss.getComponent();
|
||||
FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
|
||||
y += fm.getAscent();
|
||||
SwingUtilities2.drawStringUnderlineCharAt(c, g, text,
|
||||
mnemonicIndex, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints an icon and text. This will render the text as html, if
|
||||
* necessary, and offset the location by the insets of the component.
|
||||
*
|
||||
* @param ss SynthContext
|
||||
* @param g Graphics to render string and icon into
|
||||
* @param text Text to layout
|
||||
* @param icon Icon to layout
|
||||
* @param hAlign horizontal alignment
|
||||
* @param vAlign vertical alignment
|
||||
* @param hTextPosition horizontal text position
|
||||
* @param vTextPosition vertical text position
|
||||
* @param iconTextGap gap between icon and text
|
||||
* @param mnemonicIndex Index into text to render the mnemonic at, -1
|
||||
* indicates no mnemonic.
|
||||
* @param textOffset Amount to offset the text when painting
|
||||
*/
|
||||
public void paintText(SynthContext ss, Graphics g, String text,
|
||||
Icon icon, int hAlign, int vAlign, int hTextPosition,
|
||||
int vTextPosition, int iconTextGap, int mnemonicIndex,
|
||||
int textOffset) {
|
||||
if ((icon == null) && (text == null)) {
|
||||
return;
|
||||
}
|
||||
JComponent c = ss.getComponent();
|
||||
FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
|
||||
Insets insets = SynthLookAndFeel.getPaintingInsets(ss, paintInsets);
|
||||
|
||||
paintViewR.x = insets.left;
|
||||
paintViewR.y = insets.top;
|
||||
paintViewR.width = c.getWidth() - (insets.left + insets.right);
|
||||
paintViewR.height = c.getHeight() - (insets.top + insets.bottom);
|
||||
|
||||
paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
|
||||
paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
|
||||
|
||||
String clippedText =
|
||||
layoutText(ss, fm, text, icon, hAlign, vAlign,
|
||||
hTextPosition, vTextPosition, paintViewR, paintIconR,
|
||||
paintTextR, iconTextGap);
|
||||
|
||||
if (icon != null) {
|
||||
Color color = g.getColor();
|
||||
|
||||
if (ss.getStyle().getBoolean(ss, "TableHeader.alignSorterArrow", false) &&
|
||||
"TableHeader.renderer".equals(c.getName())) {
|
||||
paintIconR.x = paintViewR.width - paintIconR.width;
|
||||
} else {
|
||||
paintIconR.x += textOffset;
|
||||
}
|
||||
paintIconR.y += textOffset;
|
||||
SynthIcon.paintIcon(icon, ss, g, paintIconR.x, paintIconR.y,
|
||||
paintIconR.width, paintIconR.height);
|
||||
g.setColor(color);
|
||||
}
|
||||
|
||||
if (text != null) {
|
||||
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
|
||||
|
||||
if (v != null) {
|
||||
v.paint(g, paintTextR);
|
||||
} else {
|
||||
paintTextR.x += textOffset;
|
||||
paintTextR.y += textOffset;
|
||||
|
||||
paintText(ss, g, clippedText, paintTextR, mnemonicIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A quick note about how preferred sizes are calculated... Generally
|
||||
* speaking, SynthPopupMenuUI will run through the list of its children
|
||||
* (from top to bottom) and ask each for its preferred size. Each menu
|
||||
* item will add up the max width of each element (icons, text,
|
||||
* accelerator spacing, accelerator text or arrow icon) encountered thus
|
||||
* far, so by the time all menu items have been calculated, we will
|
||||
* know the maximum (preferred) menu item size for that popup menu.
|
||||
* Later when it comes time to paint each menu item, we can use those
|
||||
* same accumulated max element sizes in order to layout the item.
|
||||
*/
|
||||
static Dimension getPreferredMenuItemSize(SynthContext context,
|
||||
SynthContext accContext, JComponent c,
|
||||
Icon checkIcon, Icon arrowIcon, int defaultTextIconGap,
|
||||
String acceleratorDelimiter, boolean useCheckAndArrow,
|
||||
String propertyPrefix) {
|
||||
|
||||
JMenuItem mi = (JMenuItem) c;
|
||||
SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper(
|
||||
context, accContext, mi, checkIcon, arrowIcon,
|
||||
MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap,
|
||||
acceleratorDelimiter, SynthLookAndFeel.isLeftToRight(mi),
|
||||
useCheckAndArrow, propertyPrefix);
|
||||
|
||||
Dimension result = new Dimension();
|
||||
|
||||
// Calculate the result width
|
||||
int gap = lh.getGap();
|
||||
result.width = 0;
|
||||
MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), gap, result);
|
||||
MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), gap, result);
|
||||
MenuItemLayoutHelper.addWidth(lh.getMaxAccOrArrowWidth(), 5 * gap, result);
|
||||
// The last gap is unnecessary
|
||||
result.width -= gap;
|
||||
|
||||
// Calculate the result height
|
||||
result.height = MenuItemLayoutHelper.max(lh.getCheckSize().getHeight(),
|
||||
lh.getLabelSize().getHeight(), lh.getAccSize().getHeight(),
|
||||
lh.getArrowSize().getHeight());
|
||||
|
||||
// Take into account menu item insets
|
||||
Insets insets = lh.getMenuItem().getInsets();
|
||||
if (insets != null) {
|
||||
result.width += insets.left + insets.right;
|
||||
result.height += insets.top + insets.bottom;
|
||||
}
|
||||
|
||||
// if the width is even, bump it up one. This is critical
|
||||
// for the focus dash lhne to draw properly
|
||||
if (result.width % 2 == 0) {
|
||||
result.width++;
|
||||
}
|
||||
|
||||
// if the height is even, bump it up one. This is critical
|
||||
// for the text to center properly
|
||||
if (result.height % 2 == 0) {
|
||||
result.height++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void applyInsets(Rectangle rect, Insets insets, boolean leftToRight) {
|
||||
if (insets != null) {
|
||||
rect.x += (leftToRight ? insets.left : insets.right);
|
||||
rect.y += insets.top;
|
||||
rect.width -= (leftToRight ? insets.right : insets.left) + rect.x;
|
||||
rect.height -= (insets.bottom + rect.y);
|
||||
}
|
||||
}
|
||||
|
||||
static void paint(SynthContext context, SynthContext accContext, Graphics g,
|
||||
Icon checkIcon, Icon arrowIcon, String acceleratorDelimiter,
|
||||
int defaultTextIconGap, String propertyPrefix) {
|
||||
JMenuItem mi = (JMenuItem) context.getComponent();
|
||||
SynthStyle style = context.getStyle();
|
||||
g.setFont(style.getFont(context));
|
||||
|
||||
Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight());
|
||||
boolean leftToRight = SynthLookAndFeel.isLeftToRight(mi);
|
||||
applyInsets(viewRect, mi.getInsets(), leftToRight);
|
||||
|
||||
SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper(
|
||||
context, accContext, mi, checkIcon, arrowIcon, viewRect,
|
||||
defaultTextIconGap, acceleratorDelimiter, leftToRight,
|
||||
MenuItemLayoutHelper.useCheckAndArrow(mi), propertyPrefix);
|
||||
MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem();
|
||||
|
||||
paintMenuItem(g, lh, lr);
|
||||
}
|
||||
|
||||
static void paintMenuItem(Graphics g, SynthMenuItemLayoutHelper lh,
|
||||
MenuItemLayoutHelper.LayoutResult lr) {
|
||||
// Save original graphics font and color
|
||||
Font holdf = g.getFont();
|
||||
Color holdc = g.getColor();
|
||||
|
||||
paintCheckIcon(g, lh, lr);
|
||||
paintIcon(g, lh, lr);
|
||||
paintText(g, lh, lr);
|
||||
paintAccText(g, lh, lr);
|
||||
paintArrowIcon(g, lh, lr);
|
||||
|
||||
// Restore original graphics font and color
|
||||
g.setColor(holdc);
|
||||
g.setFont(holdf);
|
||||
}
|
||||
|
||||
static void paintBackground(Graphics g, SynthMenuItemLayoutHelper lh) {
|
||||
paintBackground(lh.getContext(), g, lh.getMenuItem());
|
||||
}
|
||||
|
||||
static void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintMenuItemBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
static void paintIcon(Graphics g, SynthMenuItemLayoutHelper lh,
|
||||
MenuItemLayoutHelper.LayoutResult lr) {
|
||||
if (lh.getIcon() != null) {
|
||||
Icon icon;
|
||||
JMenuItem mi = lh.getMenuItem();
|
||||
ButtonModel model = mi.getModel();
|
||||
if (!model.isEnabled()) {
|
||||
icon = mi.getDisabledIcon();
|
||||
} else if (model.isPressed() && model.isArmed()) {
|
||||
icon = mi.getPressedIcon();
|
||||
if (icon == null) {
|
||||
// Use default icon
|
||||
icon = mi.getIcon();
|
||||
}
|
||||
} else {
|
||||
icon = mi.getIcon();
|
||||
}
|
||||
|
||||
if (icon != null) {
|
||||
Rectangle iconRect = lr.getIconRect();
|
||||
SynthIcon.paintIcon(icon, lh.getContext(), g, iconRect.x,
|
||||
iconRect.y, iconRect.width, iconRect.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void paintCheckIcon(Graphics g, SynthMenuItemLayoutHelper lh,
|
||||
MenuItemLayoutHelper.LayoutResult lr) {
|
||||
if (lh.getCheckIcon() != null) {
|
||||
Rectangle checkRect = lr.getCheckRect();
|
||||
SynthIcon.paintIcon(lh.getCheckIcon(), lh.getContext(), g,
|
||||
checkRect.x, checkRect.y, checkRect.width, checkRect.height);
|
||||
}
|
||||
}
|
||||
|
||||
static void paintAccText(Graphics g, SynthMenuItemLayoutHelper lh,
|
||||
MenuItemLayoutHelper.LayoutResult lr) {
|
||||
String accText = lh.getAccText();
|
||||
if (accText != null && !accText.equals("")) {
|
||||
g.setColor(lh.getAccStyle().getColor(lh.getAccContext(),
|
||||
ColorType.TEXT_FOREGROUND));
|
||||
g.setFont(lh.getAccStyle().getFont(lh.getAccContext()));
|
||||
lh.getAccGraphicsUtils().paintText(lh.getAccContext(), g, accText,
|
||||
lr.getAccRect().x, lr.getAccRect().y, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void paintText(Graphics g, SynthMenuItemLayoutHelper lh,
|
||||
MenuItemLayoutHelper.LayoutResult lr) {
|
||||
if (!lh.getText().equals("")) {
|
||||
if (lh.getHtmlView() != null) {
|
||||
// Text is HTML
|
||||
lh.getHtmlView().paint(g, lr.getTextRect());
|
||||
} else {
|
||||
// Text isn't HTML
|
||||
g.setColor(lh.getStyle().getColor(
|
||||
lh.getContext(), ColorType.TEXT_FOREGROUND));
|
||||
g.setFont(lh.getStyle().getFont(lh.getContext()));
|
||||
lh.getGraphicsUtils().paintText(lh.getContext(), g, lh.getText(),
|
||||
lr.getTextRect().x, lr.getTextRect().y,
|
||||
lh.getMenuItem().getDisplayedMnemonicIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void paintArrowIcon(Graphics g, SynthMenuItemLayoutHelper lh,
|
||||
MenuItemLayoutHelper.LayoutResult lr) {
|
||||
if (lh.getArrowIcon() != null) {
|
||||
Rectangle arrowRect = lr.getArrowRect();
|
||||
SynthIcon.paintIcon(lh.getArrowIcon(), lh.getContext(), g,
|
||||
arrowRect.x, arrowRect.y, arrowRect.width, arrowRect.height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a SynthIcon around the Icon interface, forwarding calls to
|
||||
* the SynthIcon with a given SynthContext.
|
||||
*/
|
||||
private static class SynthIconWrapper implements Icon {
|
||||
private static final java.util.List<SynthIconWrapper> CACHE = new java.util.ArrayList<SynthIconWrapper>(1);
|
||||
|
||||
private SynthIcon synthIcon;
|
||||
private SynthContext context;
|
||||
|
||||
static SynthIconWrapper get(SynthIcon icon, SynthContext context) {
|
||||
synchronized(CACHE) {
|
||||
int size = CACHE.size();
|
||||
if (size > 0) {
|
||||
SynthIconWrapper wrapper = CACHE.remove(size - 1);
|
||||
wrapper.reset(icon, context);
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
return new SynthIconWrapper(icon, context);
|
||||
}
|
||||
|
||||
static void release(SynthIconWrapper wrapper) {
|
||||
wrapper.reset(null, null);
|
||||
synchronized(CACHE) {
|
||||
CACHE.add(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
SynthIconWrapper(SynthIcon icon, SynthContext context) {
|
||||
reset(icon, context);
|
||||
}
|
||||
|
||||
void reset(SynthIcon icon, SynthContext context) {
|
||||
synthIcon = icon;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
// This is a noop as this should only be for sizing calls.
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
return synthIcon.getIconWidth(context);
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
return synthIcon.getIconHeight(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import sun.swing.SwingUtilities2;
|
||||
|
||||
/**
|
||||
* The class that manages a synth title bar
|
||||
*
|
||||
* @author David Kloba
|
||||
* @author Joshua Outwater
|
||||
* @author Steve Wilson
|
||||
*/
|
||||
class SynthInternalFrameTitlePane extends BasicInternalFrameTitlePane
|
||||
implements SynthUI, PropertyChangeListener {
|
||||
|
||||
protected JPopupMenu systemPopupMenu;
|
||||
protected JButton menuButton;
|
||||
|
||||
private SynthStyle style;
|
||||
private int titleSpacing;
|
||||
private int buttonSpacing;
|
||||
// Alignment for the title, one of SwingConstants.(LEADING|TRAILING|CENTER)
|
||||
private int titleAlignment;
|
||||
|
||||
public SynthInternalFrameTitlePane(JInternalFrame f) {
|
||||
super(f);
|
||||
}
|
||||
|
||||
public String getUIClassID() {
|
||||
return "InternalFrameTitlePaneUI";
|
||||
}
|
||||
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
public SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private Region getRegion(JComponent c) {
|
||||
return SynthLookAndFeel.getRegion(c);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
if (frame != null) {
|
||||
if (frame.isSelected()) {
|
||||
return SELECTED;
|
||||
}
|
||||
}
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
protected void addSubComponents() {
|
||||
menuButton.setName("InternalFrameTitlePane.menuButton");
|
||||
iconButton.setName("InternalFrameTitlePane.iconifyButton");
|
||||
maxButton.setName("InternalFrameTitlePane.maximizeButton");
|
||||
closeButton.setName("InternalFrameTitlePane.closeButton");
|
||||
|
||||
add(menuButton);
|
||||
add(iconButton);
|
||||
add(maxButton);
|
||||
add(closeButton);
|
||||
}
|
||||
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
frame.addPropertyChangeListener(this);
|
||||
addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
protected void uninstallListeners() {
|
||||
frame.removePropertyChangeListener(this);
|
||||
removePropertyChangeListener(this);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(this, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
maxIcon =
|
||||
style.getIcon(context,"InternalFrameTitlePane.maximizeIcon");
|
||||
minIcon =
|
||||
style.getIcon(context,"InternalFrameTitlePane.minimizeIcon");
|
||||
iconIcon =
|
||||
style.getIcon(context,"InternalFrameTitlePane.iconifyIcon");
|
||||
closeIcon =
|
||||
style.getIcon(context,"InternalFrameTitlePane.closeIcon");
|
||||
titleSpacing = style.getInt(context,
|
||||
"InternalFrameTitlePane.titleSpacing", 2);
|
||||
buttonSpacing = style.getInt(context,
|
||||
"InternalFrameTitlePane.buttonSpacing", 2);
|
||||
String alignString = (String)style.get(context,
|
||||
"InternalFrameTitlePane.titleAlignment");
|
||||
titleAlignment = SwingConstants.LEADING;
|
||||
if (alignString != null) {
|
||||
alignString = alignString.toUpperCase();
|
||||
if (alignString.equals("TRAILING")) {
|
||||
titleAlignment = SwingConstants.TRAILING;
|
||||
}
|
||||
else if (alignString.equals("CENTER")) {
|
||||
titleAlignment = SwingConstants.CENTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
updateStyle(this);
|
||||
}
|
||||
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(this, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
JInternalFrame.JDesktopIcon di = frame.getDesktopIcon();
|
||||
if(di != null && di.getComponentPopupMenu() == systemPopupMenu) {
|
||||
// Release link to systemMenu from the JInternalFrame
|
||||
di.setComponentPopupMenu(null);
|
||||
}
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
private static class JPopupMenuUIResource extends JPopupMenu implements
|
||||
UIResource { }
|
||||
|
||||
protected void assembleSystemMenu() {
|
||||
systemPopupMenu = new JPopupMenuUIResource();
|
||||
addSystemMenuItems(systemPopupMenu);
|
||||
enableActions();
|
||||
menuButton = createNoFocusButton();
|
||||
updateMenuIcon();
|
||||
menuButton.addMouseListener(new MouseAdapter() {
|
||||
public void mousePressed(MouseEvent e) {
|
||||
try {
|
||||
frame.setSelected(true);
|
||||
} catch(PropertyVetoException pve) {
|
||||
}
|
||||
showSystemMenu();
|
||||
}
|
||||
});
|
||||
JPopupMenu p = frame.getComponentPopupMenu();
|
||||
if (p == null || p instanceof UIResource) {
|
||||
frame.setComponentPopupMenu(systemPopupMenu);
|
||||
}
|
||||
if (frame.getDesktopIcon() != null) {
|
||||
p = frame.getDesktopIcon().getComponentPopupMenu();
|
||||
if (p == null || p instanceof UIResource) {
|
||||
frame.getDesktopIcon().setComponentPopupMenu(systemPopupMenu);
|
||||
}
|
||||
}
|
||||
setInheritsPopupMenu(true);
|
||||
}
|
||||
|
||||
protected void addSystemMenuItems(JPopupMenu menu) {
|
||||
JMenuItem mi = menu.add(restoreAction);
|
||||
mi.setMnemonic(getButtonMnemonic("restore"));
|
||||
mi = menu.add(moveAction);
|
||||
mi.setMnemonic(getButtonMnemonic("move"));
|
||||
mi = menu.add(sizeAction);
|
||||
mi.setMnemonic(getButtonMnemonic("size"));
|
||||
mi = menu.add(iconifyAction);
|
||||
mi.setMnemonic(getButtonMnemonic("minimize"));
|
||||
mi = menu.add(maximizeAction);
|
||||
mi.setMnemonic(getButtonMnemonic("maximize"));
|
||||
menu.add(new JSeparator());
|
||||
mi = menu.add(closeAction);
|
||||
mi.setMnemonic(getButtonMnemonic("close"));
|
||||
}
|
||||
|
||||
private static int getButtonMnemonic(String button) {
|
||||
try {
|
||||
return Integer.parseInt(UIManager.getString(
|
||||
"InternalFrameTitlePane." + button + "Button.mnemonic"));
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected void showSystemMenu() {
|
||||
Insets insets = frame.getInsets();
|
||||
if (!frame.isIcon()) {
|
||||
systemPopupMenu.show(frame, menuButton.getX(), getY() + getHeight());
|
||||
} else {
|
||||
systemPopupMenu.show(menuButton,
|
||||
getX() - insets.left - insets.right,
|
||||
getY() - systemPopupMenu.getPreferredSize().height -
|
||||
insets.bottom - insets.top);
|
||||
}
|
||||
}
|
||||
|
||||
// SynthInternalFrameTitlePane has no UI, we'll invoke paint on it.
|
||||
public void paintComponent(Graphics g) {
|
||||
SynthContext context = getContext(this);
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintInternalFrameTitlePaneBackground(context,
|
||||
g, 0, 0, getWidth(), getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
String title = frame.getTitle();
|
||||
|
||||
if (title != null) {
|
||||
SynthStyle style = context.getStyle();
|
||||
|
||||
g.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND));
|
||||
g.setFont(style.getFont(context));
|
||||
|
||||
// Center text vertically.
|
||||
FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g);
|
||||
int baseline = (getHeight() + fm.getAscent() - fm.getLeading() -
|
||||
fm.getDescent()) / 2;
|
||||
JButton lastButton = null;
|
||||
if (frame.isIconifiable()) {
|
||||
lastButton = iconButton;
|
||||
}
|
||||
else if (frame.isMaximizable()) {
|
||||
lastButton = maxButton;
|
||||
}
|
||||
else if (frame.isClosable()) {
|
||||
lastButton = closeButton;
|
||||
}
|
||||
int maxX;
|
||||
int minX;
|
||||
boolean ltr = SynthLookAndFeel.isLeftToRight(frame);
|
||||
int titleAlignment = this.titleAlignment;
|
||||
if (ltr) {
|
||||
if (lastButton != null) {
|
||||
maxX = lastButton.getX() - titleSpacing;
|
||||
}
|
||||
else {
|
||||
maxX = frame.getWidth() - frame.getInsets().right -
|
||||
titleSpacing;
|
||||
}
|
||||
minX = menuButton.getX() + menuButton.getWidth() +
|
||||
titleSpacing;
|
||||
}
|
||||
else {
|
||||
if (lastButton != null) {
|
||||
minX = lastButton.getX() + lastButton.getWidth() +
|
||||
titleSpacing;
|
||||
}
|
||||
else {
|
||||
minX = frame.getInsets().left + titleSpacing;
|
||||
}
|
||||
maxX = menuButton.getX() - titleSpacing;
|
||||
if (titleAlignment == SwingConstants.LEADING) {
|
||||
titleAlignment = SwingConstants.TRAILING;
|
||||
}
|
||||
else if (titleAlignment == SwingConstants.TRAILING) {
|
||||
titleAlignment = SwingConstants.LEADING;
|
||||
}
|
||||
}
|
||||
String clippedTitle = getTitle(title, fm, maxX - minX);
|
||||
if (clippedTitle == title) {
|
||||
// String fit, align as necessary.
|
||||
if (titleAlignment == SwingConstants.TRAILING) {
|
||||
minX = maxX - style.getGraphicsUtils(context).
|
||||
computeStringWidth(context, g.getFont(), fm, title);
|
||||
}
|
||||
else if (titleAlignment == SwingConstants.CENTER) {
|
||||
int width = style.getGraphicsUtils(context).
|
||||
computeStringWidth(context, g.getFont(), fm, title);
|
||||
minX = Math.max(minX, (getWidth() - width) / 2);
|
||||
minX = Math.min(maxX - width, minX);
|
||||
}
|
||||
}
|
||||
style.getGraphicsUtils(context).paintText(
|
||||
context, g, clippedTitle, minX, baseline - fm.getAscent(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintInternalFrameTitlePaneBorder(context,
|
||||
g, x, y, w, h);
|
||||
}
|
||||
|
||||
protected LayoutManager createLayout() {
|
||||
SynthContext context = getContext(this);
|
||||
LayoutManager lm =
|
||||
(LayoutManager)style.get(context, "InternalFrameTitlePane.titlePaneLayout");
|
||||
context.dispose();
|
||||
return (lm != null) ? lm : new SynthTitlePaneLayout();
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getSource() == this) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle(this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Changes for the internal frame
|
||||
if (evt.getPropertyName() == JInternalFrame.FRAME_ICON_PROPERTY) {
|
||||
updateMenuIcon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the menuButton icon to match that of the frame.
|
||||
*/
|
||||
private void updateMenuIcon() {
|
||||
Icon frameIcon = frame.getFrameIcon();
|
||||
SynthContext context = getContext(this);
|
||||
if (frameIcon != null) {
|
||||
Dimension maxSize = (Dimension)context.getStyle().get(context,
|
||||
"InternalFrameTitlePane.maxFrameIconSize");
|
||||
int maxWidth = 16;
|
||||
int maxHeight = 16;
|
||||
if (maxSize != null) {
|
||||
maxWidth = maxSize.width;
|
||||
maxHeight = maxSize.height;
|
||||
}
|
||||
if ((frameIcon.getIconWidth() > maxWidth ||
|
||||
frameIcon.getIconHeight() > maxHeight) &&
|
||||
(frameIcon instanceof ImageIcon)) {
|
||||
frameIcon = new ImageIcon(((ImageIcon)frameIcon).
|
||||
getImage().getScaledInstance(maxWidth, maxHeight,
|
||||
Image.SCALE_SMOOTH));
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
menuButton.setIcon(frameIcon);
|
||||
}
|
||||
|
||||
|
||||
class SynthTitlePaneLayout implements LayoutManager {
|
||||
public void addLayoutComponent(String name, Component c) {}
|
||||
public void removeLayoutComponent(Component c) {}
|
||||
public Dimension preferredLayoutSize(Container c) {
|
||||
return minimumLayoutSize(c);
|
||||
}
|
||||
|
||||
public Dimension minimumLayoutSize(Container c) {
|
||||
SynthContext context = getContext(
|
||||
SynthInternalFrameTitlePane.this);
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
int buttonCount = 0;
|
||||
Dimension pref;
|
||||
|
||||
if (frame.isClosable()) {
|
||||
pref = closeButton.getPreferredSize();
|
||||
width += pref.width;
|
||||
height = Math.max(pref.height, height);
|
||||
buttonCount++;
|
||||
}
|
||||
if (frame.isMaximizable()) {
|
||||
pref = maxButton.getPreferredSize();
|
||||
width += pref.width;
|
||||
height = Math.max(pref.height, height);
|
||||
buttonCount++;
|
||||
}
|
||||
if (frame.isIconifiable()) {
|
||||
pref = iconButton.getPreferredSize();
|
||||
width += pref.width;
|
||||
height = Math.max(pref.height, height);
|
||||
buttonCount++;
|
||||
}
|
||||
pref = menuButton.getPreferredSize();
|
||||
width += pref.width;
|
||||
height = Math.max(pref.height, height);
|
||||
|
||||
width += Math.max(0, (buttonCount - 1) * buttonSpacing);
|
||||
|
||||
FontMetrics fm = SynthInternalFrameTitlePane.this.getFontMetrics(
|
||||
getFont());
|
||||
SynthGraphicsUtils graphicsUtils = context.getStyle().
|
||||
getGraphicsUtils(context);
|
||||
String frameTitle = frame.getTitle();
|
||||
int title_w = frameTitle != null ? graphicsUtils.
|
||||
computeStringWidth(context, fm.getFont(),
|
||||
fm, frameTitle) : 0;
|
||||
int title_length = frameTitle != null ? frameTitle.length() : 0;
|
||||
|
||||
// Leave room for three characters in the title.
|
||||
if (title_length > 3) {
|
||||
int subtitle_w = graphicsUtils.computeStringWidth(context,
|
||||
fm.getFont(), fm, frameTitle.substring(0, 3) + "...");
|
||||
width += (title_w < subtitle_w) ? title_w : subtitle_w;
|
||||
} else {
|
||||
width += title_w;
|
||||
}
|
||||
|
||||
height = Math.max(fm.getHeight() + 2, height);
|
||||
|
||||
width += titleSpacing + titleSpacing;
|
||||
|
||||
Insets insets = getInsets();
|
||||
height += insets.top + insets.bottom;
|
||||
width += insets.left + insets.right;
|
||||
context.dispose();
|
||||
return new Dimension(width, height);
|
||||
}
|
||||
|
||||
private int center(Component c, Insets insets, int x,
|
||||
boolean trailing) {
|
||||
Dimension pref = c.getPreferredSize();
|
||||
if (trailing) {
|
||||
x -= pref.width;
|
||||
}
|
||||
c.setBounds(x, insets.top +
|
||||
(getHeight() - insets.top - insets.bottom -
|
||||
pref.height) / 2, pref.width, pref.height);
|
||||
if (pref.width > 0) {
|
||||
if (trailing) {
|
||||
return x - buttonSpacing;
|
||||
}
|
||||
return x + pref.width + buttonSpacing;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public void layoutContainer(Container c) {
|
||||
Insets insets = c.getInsets();
|
||||
Dimension pref;
|
||||
|
||||
if (SynthLookAndFeel.isLeftToRight(frame)) {
|
||||
center(menuButton, insets, insets.left, false);
|
||||
int x = getWidth() - insets.right;
|
||||
if (frame.isClosable()) {
|
||||
x = center(closeButton, insets, x, true);
|
||||
}
|
||||
if (frame.isMaximizable()) {
|
||||
x = center(maxButton, insets, x, true);
|
||||
}
|
||||
if (frame.isIconifiable()) {
|
||||
x = center(iconButton, insets, x, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
center(menuButton, insets, getWidth() - insets.right,
|
||||
true);
|
||||
int x = insets.left;
|
||||
if (frame.isClosable()) {
|
||||
x = center(closeButton, insets, x, false);
|
||||
}
|
||||
if (frame.isMaximizable()) {
|
||||
x = center(maxButton, insets, x, false);
|
||||
}
|
||||
if (frame.isIconifiable()) {
|
||||
x = center(iconButton, insets, x, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JButton createNoFocusButton() {
|
||||
JButton button = new JButton();
|
||||
button.setFocusable(false);
|
||||
button.setMargin(new Insets(0,0,0,0));
|
||||
return button;
|
||||
}
|
||||
}
|
||||
277
jdkSrc/jdk8/javax/swing/plaf/synth/SynthInternalFrameUI.java
Normal file
277
jdkSrc/jdk8/javax/swing/plaf/synth/SynthInternalFrameUI.java
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||
import java.beans.*;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @author David Kloba
|
||||
* @author Joshua Outwater
|
||||
* @author Rich Schiavi
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthInternalFrameUI extends BasicInternalFrameUI
|
||||
implements SynthUI, PropertyChangeListener {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param b component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new SynthInternalFrameUI((JInternalFrame)b);
|
||||
}
|
||||
|
||||
protected SynthInternalFrameUI(JInternalFrame b) {
|
||||
super(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void installDefaults() {
|
||||
frame.setLayout(internalFrameLayout = createLayoutManager());
|
||||
updateStyle(frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
frame.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallComponents() {
|
||||
if (frame.getComponentPopupMenu() instanceof UIResource) {
|
||||
frame.setComponentPopupMenu(null);
|
||||
}
|
||||
super.uninstallComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
frame.removePropertyChangeListener(this);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
Icon frameIcon = frame.getFrameIcon();
|
||||
if (frameIcon == null || frameIcon instanceof UIResource) {
|
||||
frame.setFrameIcon(context.getStyle().getIcon(
|
||||
context, "InternalFrame.icon"));
|
||||
}
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(frame, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
if(frame.getLayout() == internalFrameLayout) {
|
||||
frame.setLayout(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected JComponent createNorthPane(JInternalFrame w) {
|
||||
titlePane = new SynthInternalFrameTitlePane(w);
|
||||
titlePane.setName("InternalFrame.northPane");
|
||||
return titlePane;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected ComponentListener createComponentListener() {
|
||||
if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
|
||||
return new ComponentHandler() {
|
||||
@Override public void componentResized(ComponentEvent e) {
|
||||
if (frame != null && frame.isMaximum()) {
|
||||
JDesktopPane desktop = (JDesktopPane)e.getSource();
|
||||
for (Component comp : desktop.getComponents()) {
|
||||
if (comp instanceof SynthDesktopPaneUI.TaskBar) {
|
||||
frame.setBounds(0, 0,
|
||||
desktop.getWidth(),
|
||||
desktop.getHeight() - comp.getHeight());
|
||||
frame.revalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the new parent bounds for next resize, but don't
|
||||
// let the super method touch this frame
|
||||
JInternalFrame f = frame;
|
||||
frame = null;
|
||||
super.componentResized(e);
|
||||
frame = f;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return super.createComponentListener();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintInternalFrameBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintInternalFrameBorder(context,
|
||||
g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
SynthStyle oldStyle = style;
|
||||
JInternalFrame f = (JInternalFrame)evt.getSource();
|
||||
String prop = evt.getPropertyName();
|
||||
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle(f);
|
||||
}
|
||||
|
||||
if (style == oldStyle &&
|
||||
(prop == JInternalFrame.IS_MAXIMUM_PROPERTY ||
|
||||
prop == JInternalFrame.IS_SELECTED_PROPERTY)) {
|
||||
// Border (and other defaults) may need to change
|
||||
SynthContext context = getContext(f, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
style.installDefaults(context, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
301
jdkSrc/jdk8/javax/swing/plaf/synth/SynthLabelUI.java
Normal file
301
jdkSrc/jdk8/javax/swing/plaf/synth/SynthLabelUI.java
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import javax.swing.text.View;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.FontMetrics;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JLabel}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthLabelUI extends BasicLabelUI implements SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Returns the LabelUI implementation used for the skins look and feel.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c){
|
||||
return new SynthLabelUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults(JLabel c) {
|
||||
updateStyle(c);
|
||||
}
|
||||
|
||||
void updateStyle(JLabel c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults(JLabel c){
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
int state = SynthLookAndFeel.getComponentState(c);
|
||||
if (SynthLookAndFeel.getSelectedUI() == this &&
|
||||
state == SynthConstants.ENABLED) {
|
||||
state = SynthLookAndFeel.getSelectedUIState() | SynthConstants.ENABLED;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getBaseline(JComponent c, int width, int height) {
|
||||
if (c == null) {
|
||||
throw new NullPointerException("Component must be non-null");
|
||||
}
|
||||
if (width < 0 || height < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Width and height must be >= 0");
|
||||
}
|
||||
JLabel label = (JLabel)c;
|
||||
String text = label.getText();
|
||||
if (text == null || "".equals(text)) {
|
||||
return -1;
|
||||
}
|
||||
Insets i = label.getInsets();
|
||||
Rectangle viewRect = new Rectangle();
|
||||
Rectangle textRect = new Rectangle();
|
||||
Rectangle iconRect = new Rectangle();
|
||||
viewRect.x = i.left;
|
||||
viewRect.y = i.top;
|
||||
viewRect.width = width - (i.right + viewRect.x);
|
||||
viewRect.height = height - (i.bottom + viewRect.y);
|
||||
|
||||
// layout the text and icon
|
||||
SynthContext context = getContext(label);
|
||||
FontMetrics fm = context.getComponent().getFontMetrics(
|
||||
context.getStyle().getFont(context));
|
||||
context.getStyle().getGraphicsUtils(context).layoutText(
|
||||
context, fm, label.getText(), label.getIcon(),
|
||||
label.getHorizontalAlignment(), label.getVerticalAlignment(),
|
||||
label.getHorizontalTextPosition(), label.getVerticalTextPosition(),
|
||||
viewRect, iconRect, textRect, label.getIconTextGap());
|
||||
View view = (View)label.getClientProperty(BasicHTML.propertyKey);
|
||||
int baseline;
|
||||
if (view != null) {
|
||||
baseline = BasicHTML.getHTMLBaseline(view, textRect.width,
|
||||
textRect.height);
|
||||
if (baseline >= 0) {
|
||||
baseline += textRect.y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
baseline = textRect.y + fm.getAscent();
|
||||
}
|
||||
context.dispose();
|
||||
return baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintLabelBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
JLabel label = (JLabel)context.getComponent();
|
||||
Icon icon = (label.isEnabled()) ? label.getIcon() :
|
||||
label.getDisabledIcon();
|
||||
|
||||
g.setColor(context.getStyle().getColor(context,
|
||||
ColorType.TEXT_FOREGROUND));
|
||||
g.setFont(style.getFont(context));
|
||||
context.getStyle().getGraphicsUtils(context).paintText(
|
||||
context, g, label.getText(), icon,
|
||||
label.getHorizontalAlignment(), label.getVerticalAlignment(),
|
||||
label.getHorizontalTextPosition(), label.getVerticalTextPosition(),
|
||||
label.getIconTextGap(), label.getDisplayedMnemonicIndex(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintLabelBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
JLabel label = (JLabel)c;
|
||||
Icon icon = (label.isEnabled()) ? label.getIcon() :
|
||||
label.getDisabledIcon();
|
||||
SynthContext context = getContext(c);
|
||||
Dimension size = context.getStyle().getGraphicsUtils(context).
|
||||
getPreferredSize(
|
||||
context, context.getStyle().getFont(context), label.getText(),
|
||||
icon, label.getHorizontalAlignment(),
|
||||
label.getVerticalAlignment(), label.getHorizontalTextPosition(),
|
||||
label.getVerticalTextPosition(), label.getIconTextGap(),
|
||||
label.getDisplayedMnemonicIndex());
|
||||
|
||||
context.dispose();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMinimumSize(JComponent c) {
|
||||
JLabel label = (JLabel)c;
|
||||
Icon icon = (label.isEnabled()) ? label.getIcon() :
|
||||
label.getDisabledIcon();
|
||||
SynthContext context = getContext(c);
|
||||
Dimension size = context.getStyle().getGraphicsUtils(context).
|
||||
getMinimumSize(
|
||||
context, context.getStyle().getFont(context), label.getText(),
|
||||
icon, label.getHorizontalAlignment(),
|
||||
label.getVerticalAlignment(), label.getHorizontalTextPosition(),
|
||||
label.getVerticalTextPosition(), label.getIconTextGap(),
|
||||
label.getDisplayedMnemonicIndex());
|
||||
|
||||
context.dispose();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMaximumSize(JComponent c) {
|
||||
JLabel label = (JLabel)c;
|
||||
Icon icon = (label.isEnabled()) ? label.getIcon() :
|
||||
label.getDisabledIcon();
|
||||
SynthContext context = getContext(c);
|
||||
Dimension size = context.getStyle().getGraphicsUtils(context).
|
||||
getMaximumSize(
|
||||
context, context.getStyle().getFont(context), label.getText(),
|
||||
icon, label.getHorizontalAlignment(),
|
||||
label.getVerticalAlignment(), label.getHorizontalTextPosition(),
|
||||
label.getVerticalTextPosition(), label.getIconTextGap(),
|
||||
label.getDisplayedMnemonicIndex());
|
||||
|
||||
context.dispose();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
super.propertyChange(e);
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JLabel)e.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
231
jdkSrc/jdk8/javax/swing/plaf/synth/SynthListUI.java
Normal file
231
jdkSrc/jdk8/javax/swing/plaf/synth/SynthListUI.java
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JList}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthListUI extends BasicListUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
private boolean useListColors;
|
||||
private boolean useUIBorder;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param list component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent list) {
|
||||
return new SynthListUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintListBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
context.dispose();
|
||||
paint(g, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintListBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
list.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JList)e.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
list.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
if (list.getCellRenderer() == null ||
|
||||
(list.getCellRenderer() instanceof UIResource)) {
|
||||
list.setCellRenderer(new SynthListCellRenderer());
|
||||
}
|
||||
updateStyle(list);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(list, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
|
||||
if (style != oldStyle) {
|
||||
context.setComponentState(SELECTED);
|
||||
Color sbg = list.getSelectionBackground();
|
||||
if (sbg == null || sbg instanceof UIResource) {
|
||||
list.setSelectionBackground(style.getColor(
|
||||
context, ColorType.TEXT_BACKGROUND));
|
||||
}
|
||||
|
||||
Color sfg = list.getSelectionForeground();
|
||||
if (sfg == null || sfg instanceof UIResource) {
|
||||
list.setSelectionForeground(style.getColor(
|
||||
context, ColorType.TEXT_FOREGROUND));
|
||||
}
|
||||
|
||||
useListColors = style.getBoolean(context,
|
||||
"List.rendererUseListColors", true);
|
||||
useUIBorder = style.getBoolean(context,
|
||||
"List.rendererUseUIBorder", true);
|
||||
|
||||
int height = style.getInt(context, "List.cellHeight", -1);
|
||||
if (height != -1) {
|
||||
list.setFixedCellHeight(height);
|
||||
}
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
SynthContext context = getContext(list, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
|
||||
private class SynthListCellRenderer extends DefaultListCellRenderer.UIResource {
|
||||
@Override public String getName() {
|
||||
return "List.cellRenderer";
|
||||
}
|
||||
|
||||
@Override public void setBorder(Border b) {
|
||||
if (useUIBorder || b instanceof SynthBorder) {
|
||||
super.setBorder(b);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public Component getListCellRendererComponent(JList list, Object value,
|
||||
int index, boolean isSelected, boolean cellHasFocus) {
|
||||
if (!useListColors && (isSelected || cellHasFocus)) {
|
||||
SynthLookAndFeel.setSelectedUI((SynthLabelUI)SynthLookAndFeel.
|
||||
getUIOfType(getUI(), SynthLabelUI.class),
|
||||
isSelected, cellHasFocus, list.isEnabled(), false);
|
||||
}
|
||||
else {
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
|
||||
super.getListCellRendererComponent(list, value, index,
|
||||
isSelected, cellHasFocus);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
996
jdkSrc/jdk8/javax/swing/plaf/synth/SynthLookAndFeel.java
Normal file
996
jdkSrc/jdk8/javax/swing/plaf/synth/SynthLookAndFeel.java
Normal file
@@ -0,0 +1,996 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import java.io.*;
|
||||
import java.lang.ref.*;
|
||||
import java.net.*;
|
||||
import java.security.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
|
||||
import sun.awt.*;
|
||||
import sun.security.action.*;
|
||||
import sun.swing.*;
|
||||
import sun.swing.plaf.synth.*;
|
||||
|
||||
/**
|
||||
* SynthLookAndFeel provides the basis for creating a customized look and
|
||||
* feel. SynthLookAndFeel does not directly provide a look, all painting is
|
||||
* delegated.
|
||||
* You need to either provide a configuration file, by way of the
|
||||
* {@link #load} method, or provide your own {@link SynthStyleFactory}
|
||||
* to {@link #setStyleFactory}. Refer to the
|
||||
* <a href="package-summary.html">package summary</a> for an example of
|
||||
* loading a file, and {@link javax.swing.plaf.synth.SynthStyleFactory} for
|
||||
* an example of providing your own <code>SynthStyleFactory</code> to
|
||||
* <code>setStyleFactory</code>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* This class implements {@link Serializable} as a side effect of it
|
||||
* extending {@link BasicLookAndFeel}. It is not intended to be serialized.
|
||||
* An attempt to serialize it will
|
||||
* result in {@link NotSerializableException}.
|
||||
*
|
||||
* @serial exclude
|
||||
* @since 1.5
|
||||
* @author Scott Violet
|
||||
*/
|
||||
public class SynthLookAndFeel extends BasicLookAndFeel {
|
||||
/**
|
||||
* Used in a handful of places where we need an empty Insets.
|
||||
*/
|
||||
static final Insets EMPTY_UIRESOURCE_INSETS = new InsetsUIResource(
|
||||
0, 0, 0, 0);
|
||||
|
||||
/**
|
||||
* AppContext key to get the current SynthStyleFactory.
|
||||
*/
|
||||
private static final Object STYLE_FACTORY_KEY =
|
||||
new StringBuffer("com.sun.java.swing.plaf.gtk.StyleCache");
|
||||
|
||||
/**
|
||||
* AppContext key to get selectedUI.
|
||||
*/
|
||||
private static final Object SELECTED_UI_KEY = new StringBuilder("selectedUI");
|
||||
|
||||
/**
|
||||
* AppContext key to get selectedUIState.
|
||||
*/
|
||||
private static final Object SELECTED_UI_STATE_KEY = new StringBuilder("selectedUIState");
|
||||
|
||||
/**
|
||||
* The last SynthStyleFactory that was asked for from AppContext
|
||||
* <code>lastContext</code>.
|
||||
*/
|
||||
private static SynthStyleFactory lastFactory;
|
||||
/**
|
||||
* AppContext lastLAF came from.
|
||||
*/
|
||||
private static AppContext lastContext;
|
||||
|
||||
/**
|
||||
* SynthStyleFactory for the this SynthLookAndFeel.
|
||||
*/
|
||||
private SynthStyleFactory factory;
|
||||
|
||||
/**
|
||||
* Map of defaults table entries. This is populated via the load
|
||||
* method.
|
||||
*/
|
||||
private Map<String, Object> defaultsMap;
|
||||
|
||||
private Handler _handler;
|
||||
|
||||
static ComponentUI getSelectedUI() {
|
||||
return (ComponentUI) AppContext.getAppContext().get(SELECTED_UI_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the renderers. For the most part the renderers are implemented
|
||||
* as Labels, which is problematic in so far as they are never selected.
|
||||
* To accommodate this SynthLabelUI checks if the current
|
||||
* UI matches that of <code>selectedUI</code> (which this methods sets), if
|
||||
* it does, then a state as set by this method is returned. This provides
|
||||
* a way for labels to have a state other than selected.
|
||||
*/
|
||||
static void setSelectedUI(ComponentUI uix, boolean selected,
|
||||
boolean focused, boolean enabled,
|
||||
boolean rollover) {
|
||||
int selectedUIState = 0;
|
||||
|
||||
if (selected) {
|
||||
selectedUIState = SynthConstants.SELECTED;
|
||||
if (focused) {
|
||||
selectedUIState |= SynthConstants.FOCUSED;
|
||||
}
|
||||
}
|
||||
else if (rollover && enabled) {
|
||||
selectedUIState |=
|
||||
SynthConstants.MOUSE_OVER | SynthConstants.ENABLED;
|
||||
if (focused) {
|
||||
selectedUIState |= SynthConstants.FOCUSED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (enabled) {
|
||||
selectedUIState |= SynthConstants.ENABLED;
|
||||
if (focused) {
|
||||
selectedUIState |= SynthConstants.FOCUSED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
selectedUIState |= SynthConstants.DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
AppContext context = AppContext.getAppContext();
|
||||
|
||||
context.put(SELECTED_UI_KEY, uix);
|
||||
context.put(SELECTED_UI_STATE_KEY, Integer.valueOf(selectedUIState));
|
||||
}
|
||||
|
||||
static int getSelectedUIState() {
|
||||
Integer result = (Integer) AppContext.getAppContext().get(SELECTED_UI_STATE_KEY);
|
||||
|
||||
return result == null ? 0 : result.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out the selected UI that was last set in setSelectedUI.
|
||||
*/
|
||||
static void resetSelectedUI() {
|
||||
AppContext.getAppContext().remove(SELECTED_UI_KEY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the SynthStyleFactory that the UI classes provided by
|
||||
* synth will use to obtain a SynthStyle.
|
||||
*
|
||||
* @param cache SynthStyleFactory the UIs should use.
|
||||
*/
|
||||
public static void setStyleFactory(SynthStyleFactory cache) {
|
||||
// We assume the setter is called BEFORE the getter has been invoked
|
||||
// for a particular AppContext.
|
||||
synchronized(SynthLookAndFeel.class) {
|
||||
AppContext context = AppContext.getAppContext();
|
||||
lastFactory = cache;
|
||||
lastContext = context;
|
||||
context.put(STYLE_FACTORY_KEY, cache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current SynthStyleFactory.
|
||||
*
|
||||
* @return SynthStyleFactory
|
||||
*/
|
||||
public static SynthStyleFactory getStyleFactory() {
|
||||
synchronized(SynthLookAndFeel.class) {
|
||||
AppContext context = AppContext.getAppContext();
|
||||
|
||||
if (lastContext == context) {
|
||||
return lastFactory;
|
||||
}
|
||||
lastContext = context;
|
||||
lastFactory = (SynthStyleFactory) context.get(STYLE_FACTORY_KEY);
|
||||
return lastFactory;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component state for the specified component. This should
|
||||
* only be used for Components that don't have any special state beyond
|
||||
* that of ENABLED, DISABLED or FOCUSED. For example, buttons shouldn't
|
||||
* call into this method.
|
||||
*/
|
||||
static int getComponentState(Component c) {
|
||||
if (c.isEnabled()) {
|
||||
if (c.isFocusOwner()) {
|
||||
return SynthUI.ENABLED | SynthUI.FOCUSED;
|
||||
}
|
||||
return SynthUI.ENABLED;
|
||||
}
|
||||
return SynthUI.DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a SynthStyle for the specified region of the specified component.
|
||||
* This is not for general consumption, only custom UIs should call this
|
||||
* method.
|
||||
*
|
||||
* @param c JComponent to get the SynthStyle for
|
||||
* @param region Identifies the region of the specified component
|
||||
* @return SynthStyle to use.
|
||||
*/
|
||||
public static SynthStyle getStyle(JComponent c, Region region) {
|
||||
return getStyleFactory().getStyle(c, region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Style should be updated in response to the
|
||||
* specified PropertyChangeEvent. This forwards to
|
||||
* <code>shouldUpdateStyleOnAncestorChanged</code> as necessary.
|
||||
*/
|
||||
static boolean shouldUpdateStyle(PropertyChangeEvent event) {
|
||||
LookAndFeel laf = UIManager.getLookAndFeel();
|
||||
return (laf instanceof SynthLookAndFeel &&
|
||||
((SynthLookAndFeel) laf).shouldUpdateStyleOnEvent(event));
|
||||
}
|
||||
|
||||
/**
|
||||
* A convience method that will reset the Style of StyleContext if
|
||||
* necessary.
|
||||
*
|
||||
* @return newStyle
|
||||
*/
|
||||
static SynthStyle updateStyle(SynthContext context, SynthUI ui) {
|
||||
SynthStyle newStyle = getStyle(context.getComponent(),
|
||||
context.getRegion());
|
||||
SynthStyle oldStyle = context.getStyle();
|
||||
|
||||
if (newStyle != oldStyle) {
|
||||
if (oldStyle != null) {
|
||||
oldStyle.uninstallDefaults(context);
|
||||
}
|
||||
context.setStyle(newStyle);
|
||||
newStyle.installDefaults(context, ui);
|
||||
}
|
||||
return newStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the style associated with <code>c</code>, and all its children.
|
||||
* This is a lighter version of
|
||||
* <code>SwingUtilities.updateComponentTreeUI</code>.
|
||||
*
|
||||
* @param c Component to update style for.
|
||||
*/
|
||||
public static void updateStyles(Component c) {
|
||||
if (c instanceof JComponent) {
|
||||
// Yes, this is hacky. A better solution is to get the UI
|
||||
// and cast, but JComponent doesn't expose a getter for the UI
|
||||
// (each of the UIs do), making that approach impractical.
|
||||
String name = c.getName();
|
||||
c.setName(null);
|
||||
if (name != null) {
|
||||
c.setName(name);
|
||||
}
|
||||
((JComponent)c).revalidate();
|
||||
}
|
||||
Component[] children = null;
|
||||
if (c instanceof JMenu) {
|
||||
children = ((JMenu)c).getMenuComponents();
|
||||
}
|
||||
else if (c instanceof Container) {
|
||||
children = ((Container)c).getComponents();
|
||||
}
|
||||
if (children != null) {
|
||||
for (Component child : children) {
|
||||
updateStyles(child);
|
||||
}
|
||||
}
|
||||
c.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Region for the JComponent <code>c</code>.
|
||||
*
|
||||
* @param c JComponent to fetch the Region for
|
||||
* @return Region corresponding to <code>c</code>
|
||||
*/
|
||||
public static Region getRegion(JComponent c) {
|
||||
return Region.getRegion(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return where the foreground should be
|
||||
* painted for the Component identified by the passed in
|
||||
* AbstractSynthContext.
|
||||
*/
|
||||
static Insets getPaintingInsets(SynthContext state, Insets insets) {
|
||||
if (state.isSubregion()) {
|
||||
insets = state.getStyle().getInsets(state, insets);
|
||||
}
|
||||
else {
|
||||
insets = state.getComponent().getInsets(insets);
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method that handles painting of the background.
|
||||
* All SynthUI implementations should override update and invoke
|
||||
* this method.
|
||||
*/
|
||||
static void update(SynthContext state, Graphics g) {
|
||||
paintRegion(state, g, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method that handles painting of the background for
|
||||
* subregions. All SynthUI's that have subregions should invoke
|
||||
* this method, than paint the foreground.
|
||||
*/
|
||||
static void updateSubregion(SynthContext state, Graphics g,
|
||||
Rectangle bounds) {
|
||||
paintRegion(state, g, bounds);
|
||||
}
|
||||
|
||||
private static void paintRegion(SynthContext state, Graphics g,
|
||||
Rectangle bounds) {
|
||||
JComponent c = state.getComponent();
|
||||
SynthStyle style = state.getStyle();
|
||||
int x, y, width, height;
|
||||
|
||||
if (bounds == null) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
width = c.getWidth();
|
||||
height = c.getHeight();
|
||||
}
|
||||
else {
|
||||
x = bounds.x;
|
||||
y = bounds.y;
|
||||
width = bounds.width;
|
||||
height = bounds.height;
|
||||
}
|
||||
|
||||
// Fill in the background, if necessary.
|
||||
boolean subregion = state.isSubregion();
|
||||
if ((subregion && style.isOpaque(state)) ||
|
||||
(!subregion && c.isOpaque())) {
|
||||
g.setColor(style.getColor(state, ColorType.BACKGROUND));
|
||||
g.fillRect(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isLeftToRight(Component c) {
|
||||
return c.getComponentOrientation().isLeftToRight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ui that is of type <code>klass</code>, or null if
|
||||
* one can not be found.
|
||||
*/
|
||||
static Object getUIOfType(ComponentUI ui, Class klass) {
|
||||
if (klass.isInstance(ui)) {
|
||||
return ui;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Synth look and feel <code>ComponentUI</code> for
|
||||
* the passed in <code>JComponent</code>.
|
||||
*
|
||||
* @param c JComponent to create the <code>ComponentUI</code> for
|
||||
* @return ComponentUI to use for <code>c</code>
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
String key = c.getUIClassID().intern();
|
||||
|
||||
if (key == "ButtonUI") {
|
||||
return SynthButtonUI.createUI(c);
|
||||
}
|
||||
else if (key == "CheckBoxUI") {
|
||||
return SynthCheckBoxUI.createUI(c);
|
||||
}
|
||||
else if (key == "CheckBoxMenuItemUI") {
|
||||
return SynthCheckBoxMenuItemUI.createUI(c);
|
||||
}
|
||||
else if (key == "ColorChooserUI") {
|
||||
return SynthColorChooserUI.createUI(c);
|
||||
}
|
||||
else if (key == "ComboBoxUI") {
|
||||
return SynthComboBoxUI.createUI(c);
|
||||
}
|
||||
else if (key == "DesktopPaneUI") {
|
||||
return SynthDesktopPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "DesktopIconUI") {
|
||||
return SynthDesktopIconUI.createUI(c);
|
||||
}
|
||||
else if (key == "EditorPaneUI") {
|
||||
return SynthEditorPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "FileChooserUI") {
|
||||
return SynthFileChooserUI.createUI(c);
|
||||
}
|
||||
else if (key == "FormattedTextFieldUI") {
|
||||
return SynthFormattedTextFieldUI.createUI(c);
|
||||
}
|
||||
else if (key == "InternalFrameUI") {
|
||||
return SynthInternalFrameUI.createUI(c);
|
||||
}
|
||||
else if (key == "LabelUI") {
|
||||
return SynthLabelUI.createUI(c);
|
||||
}
|
||||
else if (key == "ListUI") {
|
||||
return SynthListUI.createUI(c);
|
||||
}
|
||||
else if (key == "MenuBarUI") {
|
||||
return SynthMenuBarUI.createUI(c);
|
||||
}
|
||||
else if (key == "MenuUI") {
|
||||
return SynthMenuUI.createUI(c);
|
||||
}
|
||||
else if (key == "MenuItemUI") {
|
||||
return SynthMenuItemUI.createUI(c);
|
||||
}
|
||||
else if (key == "OptionPaneUI") {
|
||||
return SynthOptionPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "PanelUI") {
|
||||
return SynthPanelUI.createUI(c);
|
||||
}
|
||||
else if (key == "PasswordFieldUI") {
|
||||
return SynthPasswordFieldUI.createUI(c);
|
||||
}
|
||||
else if (key == "PopupMenuSeparatorUI") {
|
||||
return SynthSeparatorUI.createUI(c);
|
||||
}
|
||||
else if (key == "PopupMenuUI") {
|
||||
return SynthPopupMenuUI.createUI(c);
|
||||
}
|
||||
else if (key == "ProgressBarUI") {
|
||||
return SynthProgressBarUI.createUI(c);
|
||||
}
|
||||
else if (key == "RadioButtonUI") {
|
||||
return SynthRadioButtonUI.createUI(c);
|
||||
}
|
||||
else if (key == "RadioButtonMenuItemUI") {
|
||||
return SynthRadioButtonMenuItemUI.createUI(c);
|
||||
}
|
||||
else if (key == "RootPaneUI") {
|
||||
return SynthRootPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "ScrollBarUI") {
|
||||
return SynthScrollBarUI.createUI(c);
|
||||
}
|
||||
else if (key == "ScrollPaneUI") {
|
||||
return SynthScrollPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "SeparatorUI") {
|
||||
return SynthSeparatorUI.createUI(c);
|
||||
}
|
||||
else if (key == "SliderUI") {
|
||||
return SynthSliderUI.createUI(c);
|
||||
}
|
||||
else if (key == "SpinnerUI") {
|
||||
return SynthSpinnerUI.createUI(c);
|
||||
}
|
||||
else if (key == "SplitPaneUI") {
|
||||
return SynthSplitPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "TabbedPaneUI") {
|
||||
return SynthTabbedPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "TableUI") {
|
||||
return SynthTableUI.createUI(c);
|
||||
}
|
||||
else if (key == "TableHeaderUI") {
|
||||
return SynthTableHeaderUI.createUI(c);
|
||||
}
|
||||
else if (key == "TextAreaUI") {
|
||||
return SynthTextAreaUI.createUI(c);
|
||||
}
|
||||
else if (key == "TextFieldUI") {
|
||||
return SynthTextFieldUI.createUI(c);
|
||||
}
|
||||
else if (key == "TextPaneUI") {
|
||||
return SynthTextPaneUI.createUI(c);
|
||||
}
|
||||
else if (key == "ToggleButtonUI") {
|
||||
return SynthToggleButtonUI.createUI(c);
|
||||
}
|
||||
else if (key == "ToolBarSeparatorUI") {
|
||||
return SynthSeparatorUI.createUI(c);
|
||||
}
|
||||
else if (key == "ToolBarUI") {
|
||||
return SynthToolBarUI.createUI(c);
|
||||
}
|
||||
else if (key == "ToolTipUI") {
|
||||
return SynthToolTipUI.createUI(c);
|
||||
}
|
||||
else if (key == "TreeUI") {
|
||||
return SynthTreeUI.createUI(c);
|
||||
}
|
||||
else if (key == "ViewportUI") {
|
||||
return SynthViewportUI.createUI(c);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SynthLookAndFeel.
|
||||
* <p>
|
||||
* For the returned <code>SynthLookAndFeel</code> to be useful you need to
|
||||
* invoke <code>load</code> to specify the set of
|
||||
* <code>SynthStyle</code>s, or invoke <code>setStyleFactory</code>.
|
||||
*
|
||||
* @see #load
|
||||
* @see #setStyleFactory
|
||||
*/
|
||||
public SynthLookAndFeel() {
|
||||
factory = new DefaultSynthStyleFactory();
|
||||
_handler = new Handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the set of <code>SynthStyle</code>s that will be used by
|
||||
* this <code>SynthLookAndFeel</code>. <code>resourceBase</code> is
|
||||
* used to resolve any path based resources, for example an
|
||||
* <code>Image</code> would be resolved by
|
||||
* <code>resourceBase.getResource(path)</code>. Refer to
|
||||
* <a href="doc-files/synthFileFormat.html">Synth File Format</a>
|
||||
* for more information.
|
||||
*
|
||||
* @param input InputStream to load from
|
||||
* @param resourceBase used to resolve any images or other resources
|
||||
* @throws ParseException if there is an error in parsing
|
||||
* @throws IllegalArgumentException if input or resourceBase is <code>null</code>
|
||||
*/
|
||||
public void load(InputStream input, Class<?> resourceBase) throws
|
||||
ParseException {
|
||||
if (resourceBase == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"You must supply a valid resource base Class");
|
||||
}
|
||||
|
||||
if (defaultsMap == null) {
|
||||
defaultsMap = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
|
||||
null, resourceBase, defaultsMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the set of <code>SynthStyle</code>s that will be used by
|
||||
* this <code>SynthLookAndFeel</code>. Path based resources are resolved
|
||||
* relatively to the specified <code>URL</code> of the style. For example
|
||||
* an <code>Image</code> would be resolved by
|
||||
* <code>new URL(synthFile, path)</code>. Refer to
|
||||
* <a href="doc-files/synthFileFormat.html">Synth File Format</a> for more
|
||||
* information.
|
||||
* <p>
|
||||
* Whilst this API may be safe for loading local resources that are
|
||||
* delivered with a {@code LookAndFeel} or application, and so have an
|
||||
* equal level of trust with application code, using it to load from
|
||||
* remote resources, particularly any which may have a lower level of
|
||||
* trust, is strongly discouraged.
|
||||
* The alternative mechanisms to load styles from an {@code InputStream}
|
||||
* {@linkplain #load(InputStream, Class)}
|
||||
* using resources co-located with the application or by providing a
|
||||
* {@code SynthStyleFactory} to
|
||||
* {@linkplain #setStyleFactory setStyleFactory(SynthStyleFactory)}
|
||||
* are preferred.
|
||||
*
|
||||
* @param url the <code>URL</code> to load the set of
|
||||
* <code>SynthStyle</code> from
|
||||
* @throws ParseException if there is an error in parsing
|
||||
* @throws IllegalArgumentException if synthSet is <code>null</code>
|
||||
* @throws IOException if synthSet cannot be opened as an <code>InputStream</code>
|
||||
* @since 1.6
|
||||
*/
|
||||
public void load(URL url) throws ParseException, IOException {
|
||||
if (url == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"You must supply a valid Synth set URL");
|
||||
}
|
||||
|
||||
if (defaultsMap == null) {
|
||||
defaultsMap = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
InputStream input = url.openStream();
|
||||
new SynthParser().parse(input, (DefaultSynthStyleFactory) factory,
|
||||
url, null, defaultsMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by UIManager when this look and feel is installed.
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
DefaultLookup.setDefaultLookup(new SynthDefaultLookup());
|
||||
setStyleFactory(factory);
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().
|
||||
addPropertyChangeListener(_handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by UIManager when this look and feel is uninstalled.
|
||||
*/
|
||||
@Override
|
||||
public void uninitialize() {
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().
|
||||
removePropertyChangeListener(_handler);
|
||||
// We should uninstall the StyleFactory here, but unfortunately
|
||||
// there are a handful of things that retain references to the
|
||||
// LookAndFeel and expect things to work
|
||||
super.uninitialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the defaults for this SynthLookAndFeel.
|
||||
*
|
||||
* @return Defaults table.
|
||||
*/
|
||||
@Override
|
||||
public UIDefaults getDefaults() {
|
||||
UIDefaults table = new UIDefaults(60, 0.75f);
|
||||
|
||||
Region.registerUIs(table);
|
||||
table.setDefaultLocale(Locale.getDefault());
|
||||
table.addResourceBundle(
|
||||
"com.sun.swing.internal.plaf.basic.resources.basic" );
|
||||
table.addResourceBundle("com.sun.swing.internal.plaf.synth.resources.synth");
|
||||
|
||||
// SynthTabbedPaneUI supports rollover on tabs, GTK does not
|
||||
table.put("TabbedPane.isTabRollover", Boolean.TRUE);
|
||||
|
||||
// These need to be defined for JColorChooser to work.
|
||||
table.put("ColorChooser.swatchesRecentSwatchSize",
|
||||
new Dimension(10, 10));
|
||||
table.put("ColorChooser.swatchesDefaultRecentColor", Color.RED);
|
||||
table.put("ColorChooser.swatchesSwatchSize", new Dimension(10, 10));
|
||||
|
||||
// These need to be defined for ImageView.
|
||||
table.put("html.pendingImage", SwingUtilities2.makeIcon(getClass(),
|
||||
BasicLookAndFeel.class,
|
||||
"icons/image-delayed.png"));
|
||||
table.put("html.missingImage", SwingUtilities2.makeIcon(getClass(),
|
||||
BasicLookAndFeel.class,
|
||||
"icons/image-failed.png"));
|
||||
|
||||
// These are needed for PopupMenu.
|
||||
table.put("PopupMenu.selectedWindowInputMapBindings", new Object[] {
|
||||
"ESCAPE", "cancel",
|
||||
"DOWN", "selectNext",
|
||||
"KP_DOWN", "selectNext",
|
||||
"UP", "selectPrevious",
|
||||
"KP_UP", "selectPrevious",
|
||||
"LEFT", "selectParent",
|
||||
"KP_LEFT", "selectParent",
|
||||
"RIGHT", "selectChild",
|
||||
"KP_RIGHT", "selectChild",
|
||||
"ENTER", "return",
|
||||
"SPACE", "return"
|
||||
});
|
||||
table.put("PopupMenu.selectedWindowInputMapBindings.RightToLeft",
|
||||
new Object[] {
|
||||
"LEFT", "selectChild",
|
||||
"KP_LEFT", "selectChild",
|
||||
"RIGHT", "selectParent",
|
||||
"KP_RIGHT", "selectParent",
|
||||
});
|
||||
|
||||
// enabled antialiasing depending on desktop settings
|
||||
flushUnreferenced();
|
||||
Object aaTextInfo = getAATextInfo();
|
||||
table.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
new AATextListener(this);
|
||||
|
||||
if (defaultsMap != null) {
|
||||
table.putAll(defaultsMap);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, SynthLookAndFeel is always supported.
|
||||
*
|
||||
* @return true.
|
||||
*/
|
||||
@Override
|
||||
public boolean isSupportedLookAndFeel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false, SynthLookAndFeel is not a native look and feel.
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
@Override
|
||||
public boolean isNativeLookAndFeel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a textual description of SynthLookAndFeel.
|
||||
*
|
||||
* @return textual description of synth.
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Synth look and feel";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a short string that identifies this look and feel.
|
||||
*
|
||||
* @return a short string identifying this look and feel.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Synth look and feel";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string that identifies this look and feel.
|
||||
*
|
||||
* @return a short string identifying this look and feel.
|
||||
*/
|
||||
@Override
|
||||
public String getID() {
|
||||
return "Synth";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the UIs should update their
|
||||
* <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
|
||||
* when the ancestor of the <code>JComponent</code> changes. A subclass
|
||||
* that provided a <code>SynthStyleFactory</code> that based the
|
||||
* return value from <code>getStyle</code> off the containment hierarchy
|
||||
* would override this method to return true.
|
||||
*
|
||||
* @return whether or not the UIs should update their
|
||||
* <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
|
||||
* when the ancestor changed.
|
||||
*/
|
||||
public boolean shouldUpdateStyleOnAncestorChanged() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the UIs should update their styles when a
|
||||
* particular event occurs.
|
||||
*
|
||||
* @param ev a {@code PropertyChangeEvent}
|
||||
* @return whether or not the UIs should update their styles
|
||||
* @since 1.7
|
||||
*/
|
||||
protected boolean shouldUpdateStyleOnEvent(PropertyChangeEvent ev) {
|
||||
String eName = ev.getPropertyName();
|
||||
if ("name" == eName || "componentOrientation" == eName) {
|
||||
return true;
|
||||
}
|
||||
if ("ancestor" == eName && ev.getNewValue() != null) {
|
||||
// Only update on an ancestor change when getting a valid
|
||||
// parent and the LookAndFeel wants this.
|
||||
return shouldUpdateStyleOnAncestorChanged();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the antialiasing information as specified by the host desktop.
|
||||
* Antialiasing might be forced off if the desktop is GNOME and the user
|
||||
* has set his locale to Chinese, Japanese or Korean. This is consistent
|
||||
* with what GTK does. See com.sun.java.swing.plaf.gtk.GtkLookAndFeel
|
||||
* for more information about CJK and antialiased fonts.
|
||||
*
|
||||
* @return the text antialiasing information associated to the desktop
|
||||
*/
|
||||
private static Object getAATextInfo() {
|
||||
String language = Locale.getDefault().getLanguage();
|
||||
String desktop =
|
||||
AccessController.doPrivileged(new GetPropertyAction("sun.desktop"));
|
||||
|
||||
boolean isCjkLocale = (Locale.CHINESE.getLanguage().equals(language) ||
|
||||
Locale.JAPANESE.getLanguage().equals(language) ||
|
||||
Locale.KOREAN.getLanguage().equals(language));
|
||||
boolean isGnome = "gnome".equals(desktop);
|
||||
boolean isLocal = SwingUtilities2.isLocalDisplay();
|
||||
|
||||
boolean setAA = isLocal && (!isGnome || !isCjkLocale);
|
||||
|
||||
Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(setAA);
|
||||
return aaTextInfo;
|
||||
}
|
||||
|
||||
private static ReferenceQueue<LookAndFeel> queue = new ReferenceQueue<LookAndFeel>();
|
||||
|
||||
private static void flushUnreferenced() {
|
||||
AATextListener aatl;
|
||||
while ((aatl = (AATextListener) queue.poll()) != null) {
|
||||
aatl.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static class AATextListener
|
||||
extends WeakReference<LookAndFeel> implements PropertyChangeListener {
|
||||
private String key = SunToolkit.DESKTOPFONTHINTS;
|
||||
|
||||
AATextListener(LookAndFeel laf) {
|
||||
super(laf, queue);
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
tk.addPropertyChangeListener(key, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent pce) {
|
||||
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
|
||||
if (defaults.getBoolean("Synth.doNotSetTextAA")) {
|
||||
dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
LookAndFeel laf = get();
|
||||
if (laf == null || laf != UIManager.getLookAndFeel()) {
|
||||
dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Object aaTextInfo = getAATextInfo();
|
||||
defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
tk.removePropertyChangeListener(key, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the UI of the passed in window and all its children.
|
||||
*/
|
||||
private static void updateWindowUI(Window window) {
|
||||
updateStyles(window);
|
||||
Window ownedWins[] = window.getOwnedWindows();
|
||||
for (Window w : ownedWins) {
|
||||
updateWindowUI(w);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the UIs of all the known Frames.
|
||||
*/
|
||||
private static void updateAllUIs() {
|
||||
Frame appFrames[] = Frame.getFrames();
|
||||
for (Frame frame : appFrames) {
|
||||
updateWindowUI(frame);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if an updateUI call is pending.
|
||||
*/
|
||||
private static boolean updatePending;
|
||||
|
||||
/**
|
||||
* Sets whether or not an updateUI call is pending.
|
||||
*/
|
||||
private static synchronized void setUpdatePending(boolean update) {
|
||||
updatePending = update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a UI update is pending.
|
||||
*/
|
||||
private static synchronized boolean isUpdatePending() {
|
||||
return updatePending;
|
||||
}
|
||||
|
||||
protected void updateUI() {
|
||||
if (!isUpdatePending()) {
|
||||
setUpdatePending(true);
|
||||
Runnable uiUpdater = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateAllUIs();
|
||||
setUpdatePending(false);
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(uiUpdater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(java.io.ObjectOutputStream out)
|
||||
throws IOException {
|
||||
throw new NotSerializableException(this.getClass().getName());
|
||||
}
|
||||
|
||||
private class Handler implements PropertyChangeListener {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String propertyName = evt.getPropertyName();
|
||||
Object newValue = evt.getNewValue();
|
||||
Object oldValue = evt.getOldValue();
|
||||
|
||||
if ("focusOwner" == propertyName) {
|
||||
if (oldValue instanceof JComponent) {
|
||||
repaintIfBackgroundsDiffer((JComponent)oldValue);
|
||||
|
||||
}
|
||||
|
||||
if (newValue instanceof JComponent) {
|
||||
repaintIfBackgroundsDiffer((JComponent)newValue);
|
||||
}
|
||||
}
|
||||
else if ("managingFocus" == propertyName) {
|
||||
// De-register listener on old keyboard focus manager and
|
||||
// register it on the new one.
|
||||
KeyboardFocusManager manager =
|
||||
(KeyboardFocusManager)evt.getSource();
|
||||
if (newValue.equals(Boolean.FALSE)) {
|
||||
manager.removePropertyChangeListener(_handler);
|
||||
}
|
||||
else {
|
||||
manager.addPropertyChangeListener(_handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a support method that will check if the background colors of
|
||||
* the specified component differ between focused and unfocused states.
|
||||
* If the color differ the component will then repaint itself.
|
||||
*
|
||||
* @comp the component to check
|
||||
*/
|
||||
private void repaintIfBackgroundsDiffer(JComponent comp) {
|
||||
ComponentUI ui = (ComponentUI)comp.getClientProperty(
|
||||
SwingUtilities2.COMPONENT_UI_PROPERTY_KEY);
|
||||
if (ui instanceof SynthUI) {
|
||||
SynthUI synthUI = (SynthUI)ui;
|
||||
SynthContext context = synthUI.getContext(comp);
|
||||
SynthStyle style = context.getStyle();
|
||||
int state = context.getComponentState();
|
||||
|
||||
// Get the current background color.
|
||||
Color currBG = style.getColor(context, ColorType.BACKGROUND);
|
||||
|
||||
// Get the last background color.
|
||||
state ^= SynthConstants.FOCUSED;
|
||||
context.setComponentState(state);
|
||||
Color lastBG = style.getColor(context, ColorType.BACKGROUND);
|
||||
|
||||
// Reset the component state back to original.
|
||||
state ^= SynthConstants.FOCUSED;
|
||||
context.setComponentState(state);
|
||||
|
||||
// Repaint the component if the backgrounds differed.
|
||||
if (currBG != null && !currBG.equals(lastBG)) {
|
||||
comp.repaint();
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
194
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuBarUI.java
Normal file
194
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuBarUI.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JMenuBar}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthMenuBarUI extends BasicMenuBarUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthMenuBarUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
if (menuBar.getLayout() == null ||
|
||||
menuBar.getLayout() instanceof UIResource) {
|
||||
menuBar.setLayout(new SynthMenuLayout(menuBar,BoxLayout.LINE_AXIS));
|
||||
}
|
||||
updateStyle(menuBar);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
menuBar.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
private void updateStyle(JMenuBar c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(menuBar, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
menuBar.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintMenuBarBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintMenuBarBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JMenuBar)e.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import sun.swing.StringUIClientPropertyKey;
|
||||
import sun.swing.MenuItemLayoutHelper;
|
||||
import sun.swing.plaf.synth.SynthIcon;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.View;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Calculates preferred size and layouts synth menu items.
|
||||
*
|
||||
* All JMenuItems (and JMenus) include enough space for the insets
|
||||
* plus one or more elements. When we say "label" below, we mean
|
||||
* "icon and/or text."
|
||||
*
|
||||
* Cases to consider for SynthMenuItemUI (visualized here in a
|
||||
* LTR orientation; the RTL case would be reversed):
|
||||
* label
|
||||
* check icon + label
|
||||
* check icon + label + accelerator
|
||||
* label + accelerator
|
||||
*
|
||||
* Cases to consider for SynthMenuUI (again visualized here in a
|
||||
* LTR orientation):
|
||||
* label + arrow
|
||||
*
|
||||
* Note that in the above scenarios, accelerator and arrow icon are
|
||||
* mutually exclusive. This means that if a popup menu contains a mix
|
||||
* of JMenus and JMenuItems, we only need to allow enough space for
|
||||
* max(maxAccelerator, maxArrow), and both accelerators and arrow icons
|
||||
* can occupy the same "column" of space in the menu.
|
||||
*/
|
||||
class SynthMenuItemLayoutHelper extends MenuItemLayoutHelper {
|
||||
|
||||
public static final StringUIClientPropertyKey MAX_ACC_OR_ARROW_WIDTH =
|
||||
new StringUIClientPropertyKey("maxAccOrArrowWidth");
|
||||
|
||||
public static final ColumnAlignment LTR_ALIGNMENT_1 =
|
||||
new ColumnAlignment(
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.RIGHT
|
||||
);
|
||||
public static final ColumnAlignment LTR_ALIGNMENT_2 =
|
||||
new ColumnAlignment(
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.RIGHT
|
||||
);
|
||||
public static final ColumnAlignment RTL_ALIGNMENT_1 =
|
||||
new ColumnAlignment(
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.LEFT,
|
||||
SwingConstants.LEFT
|
||||
);
|
||||
public static final ColumnAlignment RTL_ALIGNMENT_2 =
|
||||
new ColumnAlignment(
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.RIGHT,
|
||||
SwingConstants.LEFT
|
||||
);
|
||||
|
||||
private SynthContext context;
|
||||
private SynthContext accContext;
|
||||
private SynthStyle style;
|
||||
private SynthStyle accStyle;
|
||||
private SynthGraphicsUtils gu;
|
||||
private SynthGraphicsUtils accGu;
|
||||
private boolean alignAcceleratorText;
|
||||
private int maxAccOrArrowWidth;
|
||||
|
||||
public SynthMenuItemLayoutHelper(SynthContext context, SynthContext accContext,
|
||||
JMenuItem mi, Icon checkIcon, Icon arrowIcon,
|
||||
Rectangle viewRect, int gap, String accDelimiter,
|
||||
boolean isLeftToRight, boolean useCheckAndArrow,
|
||||
String propertyPrefix) {
|
||||
this.context = context;
|
||||
this.accContext = accContext;
|
||||
this.style = context.getStyle();
|
||||
this.accStyle = accContext.getStyle();
|
||||
this.gu = style.getGraphicsUtils(context);
|
||||
this.accGu = accStyle.getGraphicsUtils(accContext);
|
||||
this.alignAcceleratorText = getAlignAcceleratorText(propertyPrefix);
|
||||
reset(mi, checkIcon, arrowIcon, viewRect, gap, accDelimiter,
|
||||
isLeftToRight, style.getFont(context), accStyle.getFont(accContext),
|
||||
useCheckAndArrow, propertyPrefix);
|
||||
setLeadingGap(0);
|
||||
}
|
||||
|
||||
private boolean getAlignAcceleratorText(String propertyPrefix) {
|
||||
return style.getBoolean(context,
|
||||
propertyPrefix + ".alignAcceleratorText", true);
|
||||
}
|
||||
|
||||
protected void calcWidthsAndHeights() {
|
||||
// iconRect
|
||||
if (getIcon() != null) {
|
||||
getIconSize().setWidth(SynthIcon.getIconWidth(getIcon(), context));
|
||||
getIconSize().setHeight(SynthIcon.getIconHeight(getIcon(), context));
|
||||
}
|
||||
|
||||
// accRect
|
||||
if (!getAccText().equals("")) {
|
||||
getAccSize().setWidth(accGu.computeStringWidth(getAccContext(),
|
||||
getAccFontMetrics().getFont(), getAccFontMetrics(),
|
||||
getAccText()));
|
||||
getAccSize().setHeight(getAccFontMetrics().getHeight());
|
||||
}
|
||||
|
||||
// textRect
|
||||
if (getText() == null) {
|
||||
setText("");
|
||||
} else if (!getText().equals("")) {
|
||||
if (getHtmlView() != null) {
|
||||
// Text is HTML
|
||||
getTextSize().setWidth(
|
||||
(int) getHtmlView().getPreferredSpan(View.X_AXIS));
|
||||
getTextSize().setHeight(
|
||||
(int) getHtmlView().getPreferredSpan(View.Y_AXIS));
|
||||
} else {
|
||||
// Text isn't HTML
|
||||
getTextSize().setWidth(gu.computeStringWidth(context,
|
||||
getFontMetrics().getFont(), getFontMetrics(),
|
||||
getText()));
|
||||
getTextSize().setHeight(getFontMetrics().getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
if (useCheckAndArrow()) {
|
||||
// checkIcon
|
||||
if (getCheckIcon() != null) {
|
||||
getCheckSize().setWidth(
|
||||
SynthIcon.getIconWidth(getCheckIcon(), context));
|
||||
getCheckSize().setHeight(
|
||||
SynthIcon.getIconHeight(getCheckIcon(), context));
|
||||
}
|
||||
// arrowRect
|
||||
if (getArrowIcon() != null) {
|
||||
getArrowSize().setWidth(
|
||||
SynthIcon.getIconWidth(getArrowIcon(), context));
|
||||
getArrowSize().setHeight(
|
||||
SynthIcon.getIconHeight(getArrowIcon(), context));
|
||||
}
|
||||
}
|
||||
|
||||
// labelRect
|
||||
if (isColumnLayout()) {
|
||||
getLabelSize().setWidth(getIconSize().getWidth()
|
||||
+ getTextSize().getWidth() + getGap());
|
||||
getLabelSize().setHeight(MenuItemLayoutHelper.max(
|
||||
getCheckSize().getHeight(),
|
||||
getIconSize().getHeight(),
|
||||
getTextSize().getHeight(),
|
||||
getAccSize().getHeight(),
|
||||
getArrowSize().getHeight()));
|
||||
} else {
|
||||
Rectangle textRect = new Rectangle();
|
||||
Rectangle iconRect = new Rectangle();
|
||||
gu.layoutText(context, getFontMetrics(), getText(), getIcon(),
|
||||
getHorizontalAlignment(), getVerticalAlignment(),
|
||||
getHorizontalTextPosition(), getVerticalTextPosition(),
|
||||
getViewRect(), iconRect, textRect, getGap());
|
||||
textRect.width += getLeftTextExtraWidth();
|
||||
Rectangle labelRect = iconRect.union(textRect);
|
||||
getLabelSize().setHeight(labelRect.height);
|
||||
getLabelSize().setWidth(labelRect.width);
|
||||
}
|
||||
}
|
||||
|
||||
protected void calcMaxWidths() {
|
||||
calcMaxWidth(getCheckSize(), MAX_CHECK_WIDTH);
|
||||
maxAccOrArrowWidth =
|
||||
calcMaxValue(MAX_ACC_OR_ARROW_WIDTH, getArrowSize().getWidth());
|
||||
maxAccOrArrowWidth =
|
||||
calcMaxValue(MAX_ACC_OR_ARROW_WIDTH, getAccSize().getWidth());
|
||||
|
||||
if (isColumnLayout()) {
|
||||
calcMaxWidth(getIconSize(), MAX_ICON_WIDTH);
|
||||
calcMaxWidth(getTextSize(), MAX_TEXT_WIDTH);
|
||||
int curGap = getGap();
|
||||
if ((getIconSize().getMaxWidth() == 0)
|
||||
|| (getTextSize().getMaxWidth() == 0)) {
|
||||
curGap = 0;
|
||||
}
|
||||
getLabelSize().setMaxWidth(
|
||||
calcMaxValue(MAX_LABEL_WIDTH, getIconSize().getMaxWidth()
|
||||
+ getTextSize().getMaxWidth() + curGap));
|
||||
} else {
|
||||
// We shouldn't use current icon and text widths
|
||||
// in maximal widths calculation for complex layout.
|
||||
getIconSize().setMaxWidth(getParentIntProperty(
|
||||
MAX_ICON_WIDTH));
|
||||
calcMaxWidth(getLabelSize(), MAX_LABEL_WIDTH);
|
||||
// If maxLabelWidth is wider
|
||||
// than the widest icon + the widest text + gap,
|
||||
// we should update the maximal text witdh
|
||||
int candidateTextWidth = getLabelSize().getMaxWidth() -
|
||||
getIconSize().getMaxWidth();
|
||||
if (getIconSize().getMaxWidth() > 0) {
|
||||
candidateTextWidth -= getGap();
|
||||
}
|
||||
getTextSize().setMaxWidth(calcMaxValue(
|
||||
MAX_TEXT_WIDTH, candidateTextWidth));
|
||||
}
|
||||
}
|
||||
|
||||
public SynthContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public SynthContext getAccContext() {
|
||||
return accContext;
|
||||
}
|
||||
|
||||
public SynthStyle getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public SynthStyle getAccStyle() {
|
||||
return accStyle;
|
||||
}
|
||||
|
||||
public SynthGraphicsUtils getGraphicsUtils() {
|
||||
return gu;
|
||||
}
|
||||
|
||||
public SynthGraphicsUtils getAccGraphicsUtils() {
|
||||
return accGu;
|
||||
}
|
||||
|
||||
public boolean alignAcceleratorText() {
|
||||
return alignAcceleratorText;
|
||||
}
|
||||
|
||||
public int getMaxAccOrArrowWidth() {
|
||||
return maxAccOrArrowWidth;
|
||||
}
|
||||
|
||||
protected void prepareForLayout(LayoutResult lr) {
|
||||
lr.getCheckRect().width = getCheckSize().getMaxWidth();
|
||||
// An item can have an arrow or a check icon at once
|
||||
if (useCheckAndArrow() && (!"".equals(getAccText()))) {
|
||||
lr.getAccRect().width = maxAccOrArrowWidth;
|
||||
} else {
|
||||
lr.getArrowRect().width = maxAccOrArrowWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public ColumnAlignment getLTRColumnAlignment() {
|
||||
if (alignAcceleratorText()) {
|
||||
return LTR_ALIGNMENT_2;
|
||||
} else {
|
||||
return LTR_ALIGNMENT_1;
|
||||
}
|
||||
}
|
||||
|
||||
public ColumnAlignment getRTLColumnAlignment() {
|
||||
if (alignAcceleratorText()) {
|
||||
return RTL_ALIGNMENT_2;
|
||||
} else {
|
||||
return RTL_ALIGNMENT_1;
|
||||
}
|
||||
}
|
||||
|
||||
protected void layoutIconAndTextInLabelRect(LayoutResult lr) {
|
||||
lr.setTextRect(new Rectangle());
|
||||
lr.setIconRect(new Rectangle());
|
||||
gu.layoutText(context, getFontMetrics(), getText(), getIcon(),
|
||||
getHorizontalAlignment(), getVerticalAlignment(),
|
||||
getHorizontalTextPosition(), getVerticalTextPosition(),
|
||||
lr.getLabelRect(), lr.getIconRect(), lr.getTextRect(), getGap());
|
||||
}
|
||||
}
|
||||
308
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuItemUI.java
Normal file
308
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuItemUI.java
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import sun.swing.MenuItemLayoutHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JMenuItem}.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @author Arnaud Weber
|
||||
* @author Fredrik Lagerblad
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthMenuItemUI extends BasicMenuItemUI implements
|
||||
PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
private SynthStyle accStyle;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthMenuItemUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
super.uninstallUI(c);
|
||||
// Remove values from the parent's Client Properties.
|
||||
JComponent p = MenuItemLayoutHelper.getMenuItemParent((JMenuItem) c);
|
||||
if (p != null) {
|
||||
p.putClientProperty(
|
||||
SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(menuItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
menuItem.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
private void updateStyle(JMenuItem mi) {
|
||||
SynthContext context = getContext(mi, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (oldStyle != style) {
|
||||
String prefix = getPropertyPrefix();
|
||||
|
||||
Object value = style.get(context, prefix + ".textIconGap");
|
||||
if (value != null) {
|
||||
LookAndFeel.installProperty(mi, "iconTextGap", value);
|
||||
}
|
||||
defaultTextIconGap = mi.getIconTextGap();
|
||||
|
||||
if (menuItem.getMargin() == null ||
|
||||
(menuItem.getMargin() instanceof UIResource)) {
|
||||
Insets insets = (Insets)style.get(context, prefix + ".margin");
|
||||
|
||||
if (insets == null) {
|
||||
// Some places assume margins are non-null.
|
||||
insets = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
|
||||
}
|
||||
menuItem.setMargin(insets);
|
||||
}
|
||||
acceleratorDelimiter = style.getString(context, prefix +
|
||||
".acceleratorDelimiter", "+");
|
||||
|
||||
arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
|
||||
|
||||
checkIcon = style.getIcon(context, prefix + ".checkIcon");
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
|
||||
SynthContext accContext = getContext(mi, Region.MENU_ITEM_ACCELERATOR,
|
||||
ENABLED);
|
||||
|
||||
accStyle = SynthLookAndFeel.updateStyle(accContext, this);
|
||||
accContext.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(menuItem, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
SynthContext accContext = getContext(menuItem,
|
||||
Region.MENU_ITEM_ACCELERATOR, ENABLED);
|
||||
accStyle.uninstallDefaults(accContext);
|
||||
accContext.dispose();
|
||||
accStyle = null;
|
||||
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
menuItem.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
SynthContext getContext(JComponent c, Region region) {
|
||||
return getContext(c, region, getComponentState(c, region));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region, int state) {
|
||||
return SynthContext.getContext(c, region, accStyle, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
int state;
|
||||
|
||||
if (!c.isEnabled()) {
|
||||
state = DISABLED;
|
||||
}
|
||||
else if (menuItem.isArmed()) {
|
||||
state = MOUSE_OVER;
|
||||
}
|
||||
else {
|
||||
state = SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
if (menuItem.isSelected()) {
|
||||
state |= SELECTED;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c, Region region) {
|
||||
return getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize(JComponent c,
|
||||
Icon checkIcon,
|
||||
Icon arrowIcon,
|
||||
int defaultTextIconGap) {
|
||||
SynthContext context = getContext(c);
|
||||
SynthContext accContext = getContext(c, Region.MENU_ITEM_ACCELERATOR);
|
||||
Dimension value = SynthGraphicsUtils.getPreferredMenuItemSize(
|
||||
context, accContext, c, checkIcon, arrowIcon,
|
||||
defaultTextIconGap, acceleratorDelimiter,
|
||||
MenuItemLayoutHelper.useCheckAndArrow(menuItem),
|
||||
getPropertyPrefix());
|
||||
context.dispose();
|
||||
accContext.dispose();
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
paintBackground(context, g, c);
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
SynthContext accContext = getContext(menuItem,
|
||||
Region.MENU_ITEM_ACCELERATOR);
|
||||
|
||||
// Refetch the appropriate check indicator for the current state
|
||||
String prefix = getPropertyPrefix();
|
||||
Icon checkIcon = style.getIcon(context, prefix + ".checkIcon");
|
||||
Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
|
||||
SynthGraphicsUtils.paint(context, accContext, g, checkIcon, arrowIcon,
|
||||
acceleratorDelimiter, defaultTextIconGap, getPropertyPrefix());
|
||||
accContext.dispose();
|
||||
}
|
||||
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
SynthGraphicsUtils.paintBackground(context, g, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintMenuItemBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JMenuItem)e.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
53
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuLayout.java
Normal file
53
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuLayout.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.plaf.basic.DefaultMenuLayout;
|
||||
import javax.swing.JPopupMenu;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @author Georges Saab
|
||||
*/
|
||||
|
||||
class SynthMenuLayout extends DefaultMenuLayout {
|
||||
public SynthMenuLayout(Container target, int axis) {
|
||||
super(target, axis);
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container target) {
|
||||
if (target instanceof JPopupMenu) {
|
||||
JPopupMenu popupMenu = (JPopupMenu) target;
|
||||
popupMenu.putClientProperty(
|
||||
SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null);
|
||||
}
|
||||
|
||||
return super.preferredLayoutSize(target);
|
||||
}
|
||||
}
|
||||
304
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuUI.java
Normal file
304
jdkSrc/jdk8/javax/swing/plaf/synth/SynthMenuUI.java
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import sun.swing.MenuItemLayoutHelper;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JMenu}.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @author Arnaud Weber
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthMenuUI extends BasicMenuUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
private SynthStyle accStyle;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthMenuUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(menuItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
menuItem.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
private void updateStyle(JMenuItem mi) {
|
||||
SynthStyle oldStyle = style;
|
||||
SynthContext context = getContext(mi, ENABLED);
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (oldStyle != style) {
|
||||
String prefix = getPropertyPrefix();
|
||||
defaultTextIconGap = style.getInt(
|
||||
context, prefix + ".textIconGap", 4);
|
||||
if (menuItem.getMargin() == null ||
|
||||
(menuItem.getMargin() instanceof UIResource)) {
|
||||
Insets insets = (Insets)style.get(context, prefix + ".margin");
|
||||
|
||||
if (insets == null) {
|
||||
// Some places assume margins are non-null.
|
||||
insets = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
|
||||
}
|
||||
menuItem.setMargin(insets);
|
||||
}
|
||||
acceleratorDelimiter = style.getString(context, prefix +
|
||||
".acceleratorDelimiter", "+");
|
||||
|
||||
if (MenuItemLayoutHelper.useCheckAndArrow(menuItem)) {
|
||||
checkIcon = style.getIcon(context, prefix + ".checkIcon");
|
||||
arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
|
||||
} else {
|
||||
// Not needed in this case
|
||||
checkIcon = null;
|
||||
arrowIcon = null;
|
||||
}
|
||||
|
||||
((JMenu)menuItem).setDelay(style.getInt(context, prefix +
|
||||
".delay", 200));
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
|
||||
SynthContext accContext = getContext(mi, Region.MENU_ITEM_ACCELERATOR,
|
||||
ENABLED);
|
||||
|
||||
accStyle = SynthLookAndFeel.updateStyle(accContext, this);
|
||||
accContext.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
super.uninstallUI(c);
|
||||
// Remove values from the parent's Client Properties.
|
||||
JComponent p = MenuItemLayoutHelper.getMenuItemParent((JMenuItem) c);
|
||||
if (p != null) {
|
||||
p.putClientProperty(
|
||||
SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(menuItem, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
SynthContext accContext = getContext(menuItem,
|
||||
Region.MENU_ITEM_ACCELERATOR, ENABLED);
|
||||
accStyle.uninstallDefaults(accContext);
|
||||
accContext.dispose();
|
||||
accStyle = null;
|
||||
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
menuItem.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
SynthContext getContext(JComponent c, Region region) {
|
||||
return getContext(c, region, getComponentState(c, region));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region, int state) {
|
||||
return SynthContext.getContext(c, region, accStyle, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
int state;
|
||||
|
||||
if (!c.isEnabled()) {
|
||||
return DISABLED;
|
||||
}
|
||||
if (menuItem.isArmed()) {
|
||||
state = MOUSE_OVER;
|
||||
}
|
||||
else {
|
||||
state = SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
if (menuItem.isSelected()) {
|
||||
state |= SELECTED;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c, Region region) {
|
||||
return getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize(JComponent c,
|
||||
Icon checkIcon,
|
||||
Icon arrowIcon,
|
||||
int defaultTextIconGap) {
|
||||
SynthContext context = getContext(c);
|
||||
SynthContext accContext = getContext(c, Region.MENU_ITEM_ACCELERATOR);
|
||||
Dimension value = SynthGraphicsUtils.getPreferredMenuItemSize(
|
||||
context, accContext, c, checkIcon, arrowIcon,
|
||||
defaultTextIconGap, acceleratorDelimiter,
|
||||
MenuItemLayoutHelper.useCheckAndArrow(menuItem),
|
||||
getPropertyPrefix());
|
||||
context.dispose();
|
||||
accContext.dispose();
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintMenuBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
SynthContext accContext = getContext(menuItem,
|
||||
Region.MENU_ITEM_ACCELERATOR);
|
||||
// Refetch the appropriate check indicator for the current state
|
||||
String prefix = getPropertyPrefix();
|
||||
Icon checkIcon = style.getIcon(context, prefix + ".checkIcon");
|
||||
Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
|
||||
SynthGraphicsUtils.paint(context, accContext, g, checkIcon, arrowIcon,
|
||||
acceleratorDelimiter, defaultTextIconGap, getPropertyPrefix());
|
||||
accContext.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintMenuBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e) ||
|
||||
(e.getPropertyName().equals("ancestor") && UIManager.getBoolean("Menu.useMenuBarForTopLevelMenus"))) {
|
||||
updateStyle((JMenu)e.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
284
jdkSrc/jdk8/javax/swing/plaf/synth/SynthOptionPaneUI.java
Normal file
284
jdkSrc/jdk8/javax/swing/plaf/synth/SynthOptionPaneUI.java
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import sun.swing.DefaultLookup;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @author James Gosling
|
||||
* @author Scott Violet
|
||||
* @author Amy Fowler
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthOptionPaneUI extends BasicOptionPaneUI implements
|
||||
PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthOptionPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(optionPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
optionPane.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
minimumSize = (Dimension)style.get(context,
|
||||
"OptionPane.minimumSize");
|
||||
if (minimumSize == null) {
|
||||
minimumSize = new Dimension(262, 90);
|
||||
}
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(optionPane, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
optionPane.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
optionPane.add(createMessageArea());
|
||||
|
||||
Container separator = createSeparator();
|
||||
if (separator != null) {
|
||||
optionPane.add(separator);
|
||||
SynthContext context = getContext(optionPane, ENABLED);
|
||||
optionPane.add(Box.createVerticalStrut(context.getStyle().
|
||||
getInt(context, "OptionPane.separatorPadding", 6)));
|
||||
context.dispose();
|
||||
}
|
||||
optionPane.add(createButtonArea());
|
||||
optionPane.applyComponentOrientation(optionPane.getComponentOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintOptionPaneBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintOptionPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JOptionPane)e.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected boolean getSizeButtonsToSameWidth() {
|
||||
return DefaultLookup.getBoolean(optionPane, this,
|
||||
"OptionPane.sameSizeButtons", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link #installComponents} to create a {@code Container}
|
||||
* containing the body of the message. The icon is the created by calling
|
||||
* {@link #addIcon}.
|
||||
*/
|
||||
@Override
|
||||
protected Container createMessageArea() {
|
||||
JPanel top = new JPanel();
|
||||
top.setName("OptionPane.messageArea");
|
||||
top.setLayout(new BorderLayout());
|
||||
|
||||
/* Fill the body. */
|
||||
Container body = new JPanel(new GridBagLayout());
|
||||
Container realBody = new JPanel(new BorderLayout());
|
||||
|
||||
body.setName("OptionPane.body");
|
||||
realBody.setName("OptionPane.realBody");
|
||||
|
||||
if (getIcon() != null) {
|
||||
JPanel sep = new JPanel();
|
||||
sep.setName("OptionPane.separator");
|
||||
sep.setPreferredSize(new Dimension(15, 1));
|
||||
realBody.add(sep, BorderLayout.BEFORE_LINE_BEGINS);
|
||||
}
|
||||
realBody.add(body, BorderLayout.CENTER);
|
||||
|
||||
GridBagConstraints cons = new GridBagConstraints();
|
||||
cons.gridx = cons.gridy = 0;
|
||||
cons.gridwidth = GridBagConstraints.REMAINDER;
|
||||
cons.gridheight = 1;
|
||||
|
||||
SynthContext context = getContext(optionPane, ENABLED);
|
||||
cons.anchor = context.getStyle().getInt(context,
|
||||
"OptionPane.messageAnchor", GridBagConstraints.CENTER);
|
||||
context.dispose();
|
||||
|
||||
cons.insets = new Insets(0,0,3,0);
|
||||
|
||||
addMessageComponents(body, cons, getMessage(),
|
||||
getMaxCharactersPerLineCount(), false);
|
||||
top.add(realBody, BorderLayout.CENTER);
|
||||
|
||||
addIcon(top);
|
||||
return top;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Container createSeparator() {
|
||||
JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL);
|
||||
|
||||
separator.setName("OptionPane.separator");
|
||||
return separator;
|
||||
}
|
||||
}
|
||||
2417
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPainter.java
Normal file
2417
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPainter.java
Normal file
File diff suppressed because it is too large
Load Diff
206
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPanelUI.java
Normal file
206
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPanelUI.java
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicPanelUI;
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JPanel}.
|
||||
*
|
||||
* @author Steve Wilson
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthPanelUI extends BasicPanelUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthPanelUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
JPanel p = (JPanel)c;
|
||||
|
||||
super.installUI(c);
|
||||
installListeners(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
JPanel p = (JPanel)c;
|
||||
|
||||
uninstallListeners(p);
|
||||
super.uninstallUI(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs listeners into the panel.
|
||||
*
|
||||
* @param p the {@code JPanel} object
|
||||
*/
|
||||
protected void installListeners(JPanel p) {
|
||||
p.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls listeners from the panel.
|
||||
*
|
||||
* @param p the {@code JPanel} object
|
||||
*/
|
||||
protected void uninstallListeners(JPanel p) {
|
||||
p.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults(JPanel p) {
|
||||
updateStyle(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults(JPanel p) {
|
||||
SynthContext context = getContext(p, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
private void updateStyle(JPanel c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintPanelBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
// do actual painting
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintPanelBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent pce) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(pce)) {
|
||||
updateStyle((JPanel)pce.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
1334
jdkSrc/jdk8/javax/swing/plaf/synth/SynthParser.java
Normal file
1334
jdkSrc/jdk8/javax/swing/plaf/synth/SynthParser.java
Normal file
File diff suppressed because it is too large
Load Diff
107
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPasswordFieldUI.java
Normal file
107
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPasswordFieldUI.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JPasswordField}.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthPasswordFieldUI extends SynthTextFieldUI {
|
||||
|
||||
/**
|
||||
* Creates a UI for a JPasswordField.
|
||||
*
|
||||
* @param c the JPasswordField
|
||||
* @return the UI
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthPasswordFieldUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the name used as a key to look up properties through the
|
||||
* UIManager. This is used as a prefix to all the standard
|
||||
* text properties.
|
||||
*
|
||||
* @return the name ("PasswordField")
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "PasswordField";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a view (PasswordView) for an element.
|
||||
*
|
||||
* @param elem the element
|
||||
* @return the view
|
||||
*/
|
||||
@Override
|
||||
public View create(Element elem) {
|
||||
return new PasswordView(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintPasswordFieldBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintPasswordFieldBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installKeyboardActions() {
|
||||
super.installKeyboardActions();
|
||||
ActionMap map = SwingUtilities.getUIActionMap(getComponent());
|
||||
if (map != null && map.get(DefaultEditorKit.selectWordAction) != null) {
|
||||
Action a = map.get(DefaultEditorKit.selectLineAction);
|
||||
if (a != null) {
|
||||
map.put(DefaultEditorKit.selectWordAction, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
201
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPopupMenuUI.java
Normal file
201
jdkSrc/jdk8/javax/swing/plaf/synth/SynthPopupMenuUI.java
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JPopupMenu}.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @author Arnaud Weber
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthPopupMenuUI extends BasicPopupMenuUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthPopupMenuUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void installDefaults() {
|
||||
if (popupMenu.getLayout() == null ||
|
||||
popupMenu.getLayout() instanceof UIResource) {
|
||||
popupMenu.setLayout(new SynthMenuLayout(popupMenu, BoxLayout.Y_AXIS));
|
||||
}
|
||||
updateStyle(popupMenu);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
popupMenu.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(popupMenu, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
if (popupMenu.getLayout() instanceof UIResource) {
|
||||
popupMenu.setLayout(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
popupMenu.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintPopupMenuBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintPopupMenuBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle(popupMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
481
jdkSrc/jdk8/javax/swing/plaf/synth/SynthProgressBarUI.java
Normal file
481
jdkSrc/jdk8/javax/swing/plaf/synth/SynthProgressBarUI.java
Normal file
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import sun.swing.SwingUtilities2;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JProgressBar}.
|
||||
*
|
||||
* @author Joshua Outwater
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthProgressBarUI extends BasicProgressBarUI
|
||||
implements SynthUI, PropertyChangeListener {
|
||||
private SynthStyle style;
|
||||
private int progressPadding;
|
||||
private boolean rotateText; // added for Nimbus LAF
|
||||
private boolean paintOutsideClip;
|
||||
private boolean tileWhenIndeterminate; //whether to tile indeterminate painting
|
||||
private int tileWidth; //the width of each tile
|
||||
private Dimension minBarSize; // minimal visible bar size
|
||||
private int glowWidth; // Glow around the bar foreground
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthProgressBarUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
progressBar.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
progressBar.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(progressBar);
|
||||
}
|
||||
|
||||
private void updateStyle(JProgressBar c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
setCellLength(style.getInt(context, "ProgressBar.cellLength", 1));
|
||||
setCellSpacing(style.getInt(context, "ProgressBar.cellSpacing", 0));
|
||||
progressPadding = style.getInt(context,
|
||||
"ProgressBar.progressPadding", 0);
|
||||
paintOutsideClip = style.getBoolean(context,
|
||||
"ProgressBar.paintOutsideClip", false);
|
||||
rotateText = style.getBoolean(context,
|
||||
"ProgressBar.rotateText", false);
|
||||
tileWhenIndeterminate = style.getBoolean(context, "ProgressBar.tileWhenIndeterminate", false);
|
||||
tileWidth = style.getInt(context, "ProgressBar.tileWidth", 15);
|
||||
// handle scaling for sizeVarients for special case components. The
|
||||
// key "JComponent.sizeVariant" scales for large/small/mini
|
||||
// components are based on Apples LAF
|
||||
String scaleKey = (String)progressBar.getClientProperty(
|
||||
"JComponent.sizeVariant");
|
||||
if (scaleKey != null){
|
||||
if ("large".equals(scaleKey)){
|
||||
tileWidth *= 1.15;
|
||||
} else if ("small".equals(scaleKey)){
|
||||
tileWidth *= 0.857;
|
||||
} else if ("mini".equals(scaleKey)){
|
||||
tileWidth *= 0.784;
|
||||
}
|
||||
}
|
||||
minBarSize = (Dimension)style.get(context, "ProgressBar.minBarSize");
|
||||
glowWidth = style.getInt(context, "ProgressBar.glowWidth", 0);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(progressBar, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getBaseline(JComponent c, int width, int height) {
|
||||
super.getBaseline(c, width, height);
|
||||
if (progressBar.isStringPainted() &&
|
||||
progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
|
||||
SynthContext context = getContext(c);
|
||||
Font font = context.getStyle().getFont(context);
|
||||
FontMetrics metrics = progressBar.getFontMetrics(font);
|
||||
context.dispose();
|
||||
return (height - metrics.getAscent() - metrics.getDescent()) / 2 +
|
||||
metrics.getAscent();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Rectangle getBox(Rectangle r) {
|
||||
if (tileWhenIndeterminate) {
|
||||
return SwingUtilities.calculateInnerArea(progressBar, r);
|
||||
} else {
|
||||
return super.getBox(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void setAnimationIndex(int newValue) {
|
||||
if (paintOutsideClip) {
|
||||
if (getAnimationIndex() == newValue) {
|
||||
return;
|
||||
}
|
||||
super.setAnimationIndex(newValue);
|
||||
progressBar.repaint();
|
||||
} else {
|
||||
super.setAnimationIndex(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintProgressBarBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight(),
|
||||
progressBar.getOrientation());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
JProgressBar pBar = (JProgressBar)context.getComponent();
|
||||
int x = 0, y = 0, width = 0, height = 0;
|
||||
if (!pBar.isIndeterminate()) {
|
||||
Insets pBarInsets = pBar.getInsets();
|
||||
double percentComplete = pBar.getPercentComplete();
|
||||
if (percentComplete != 0.0) {
|
||||
if (pBar.getOrientation() == JProgressBar.HORIZONTAL) {
|
||||
x = pBarInsets.left + progressPadding;
|
||||
y = pBarInsets.top + progressPadding;
|
||||
width = (int)(percentComplete * (pBar.getWidth()
|
||||
- (pBarInsets.left + progressPadding
|
||||
+ pBarInsets.right + progressPadding)));
|
||||
height = pBar.getHeight()
|
||||
- (pBarInsets.top + progressPadding
|
||||
+ pBarInsets.bottom + progressPadding);
|
||||
|
||||
if (!SynthLookAndFeel.isLeftToRight(pBar)) {
|
||||
x = pBar.getWidth() - pBarInsets.right - width
|
||||
- progressPadding - glowWidth;
|
||||
}
|
||||
} else { // JProgressBar.VERTICAL
|
||||
x = pBarInsets.left + progressPadding;
|
||||
width = pBar.getWidth()
|
||||
- (pBarInsets.left + progressPadding
|
||||
+ pBarInsets.right + progressPadding);
|
||||
height = (int)(percentComplete * (pBar.getHeight()
|
||||
- (pBarInsets.top + progressPadding
|
||||
+ pBarInsets.bottom + progressPadding)));
|
||||
y = pBar.getHeight() - pBarInsets.bottom - height
|
||||
- progressPadding;
|
||||
|
||||
if (SynthLookAndFeel.isLeftToRight(pBar)) {
|
||||
y -= glowWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boxRect = getBox(boxRect);
|
||||
x = boxRect.x + progressPadding;
|
||||
y = boxRect.y + progressPadding;
|
||||
width = boxRect.width - progressPadding - progressPadding;
|
||||
height = boxRect.height - progressPadding - progressPadding;
|
||||
}
|
||||
|
||||
//if tiling and indeterminate, then paint the progress bar foreground a
|
||||
//bit wider than it should be. Shift as needed to ensure that there is
|
||||
//an animated effect
|
||||
if (tileWhenIndeterminate && pBar.isIndeterminate()) {
|
||||
double percentComplete = (double)getAnimationIndex() / (double)getFrameCount();
|
||||
int offset = (int)(percentComplete * tileWidth);
|
||||
Shape clip = g.getClip();
|
||||
g.clipRect(x, y, width, height);
|
||||
if (pBar.getOrientation() == JProgressBar.HORIZONTAL) {
|
||||
//paint each tile horizontally
|
||||
for (int i=x-tileWidth+offset; i<=width; i+=tileWidth) {
|
||||
context.getPainter().paintProgressBarForeground(
|
||||
context, g, i, y, tileWidth, height, pBar.getOrientation());
|
||||
}
|
||||
} else { //JProgressBar.VERTICAL
|
||||
//paint each tile vertically
|
||||
for (int i=y-offset; i<height+tileWidth; i+=tileWidth) {
|
||||
context.getPainter().paintProgressBarForeground(
|
||||
context, g, x, i, width, tileWidth, pBar.getOrientation());
|
||||
}
|
||||
}
|
||||
g.setClip(clip);
|
||||
} else {
|
||||
if (minBarSize == null || (width >= minBarSize.width
|
||||
&& height >= minBarSize.height)) {
|
||||
context.getPainter().paintProgressBarForeground(context, g,
|
||||
x, y, width, height, pBar.getOrientation());
|
||||
}
|
||||
}
|
||||
|
||||
if (pBar.isStringPainted()) {
|
||||
paintText(context, g, pBar.getString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the component's text.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g {@code Graphics} object used for painting
|
||||
* @param title the text to paint
|
||||
*/
|
||||
protected void paintText(SynthContext context, Graphics g, String title) {
|
||||
if (progressBar.isStringPainted()) {
|
||||
SynthStyle style = context.getStyle();
|
||||
Font font = style.getFont(context);
|
||||
FontMetrics fm = SwingUtilities2.getFontMetrics(
|
||||
progressBar, g, font);
|
||||
int strLength = style.getGraphicsUtils(context).
|
||||
computeStringWidth(context, font, fm, title);
|
||||
Rectangle bounds = progressBar.getBounds();
|
||||
|
||||
if (rotateText &&
|
||||
progressBar.getOrientation() == JProgressBar.VERTICAL){
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
// Calculate the position for the text.
|
||||
Point textPos;
|
||||
AffineTransform rotation;
|
||||
if (progressBar.getComponentOrientation().isLeftToRight()){
|
||||
rotation = AffineTransform.getRotateInstance(-Math.PI/2);
|
||||
textPos = new Point(
|
||||
(bounds.width+fm.getAscent()-fm.getDescent())/2,
|
||||
(bounds.height+strLength)/2);
|
||||
} else {
|
||||
rotation = AffineTransform.getRotateInstance(Math.PI/2);
|
||||
textPos = new Point(
|
||||
(bounds.width-fm.getAscent()+fm.getDescent())/2,
|
||||
(bounds.height-strLength)/2);
|
||||
}
|
||||
|
||||
// Progress bar isn't wide enough for the font. Don't paint it.
|
||||
if (textPos.x < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Paint the text.
|
||||
font = font.deriveFont(rotation);
|
||||
g2.setFont(font);
|
||||
g2.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND));
|
||||
style.getGraphicsUtils(context).paintText(context, g, title,
|
||||
textPos.x, textPos.y, -1);
|
||||
} else {
|
||||
// Calculate the bounds for the text.
|
||||
Rectangle textRect = new Rectangle(
|
||||
(bounds.width / 2) - (strLength / 2),
|
||||
(bounds.height -
|
||||
(fm.getAscent() + fm.getDescent())) / 2,
|
||||
0, 0);
|
||||
|
||||
// Progress bar isn't tall enough for the font. Don't paint it.
|
||||
if (textRect.y < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Paint the text.
|
||||
g.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND));
|
||||
g.setFont(font);
|
||||
style.getGraphicsUtils(context).paintText(context, g, title,
|
||||
textRect.x, textRect.y, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintProgressBarBorder(context, g, x, y, w, h,
|
||||
progressBar.getOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e) ||
|
||||
"indeterminate".equals(e.getPropertyName())) {
|
||||
updateStyle((JProgressBar)e.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
Dimension size = null;
|
||||
Insets border = progressBar.getInsets();
|
||||
FontMetrics fontSizer = progressBar.getFontMetrics(progressBar.getFont());
|
||||
String progString = progressBar.getString();
|
||||
int stringHeight = fontSizer.getHeight() + fontSizer.getDescent();
|
||||
|
||||
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
|
||||
size = new Dimension(getPreferredInnerHorizontal());
|
||||
if (progressBar.isStringPainted()) {
|
||||
// adjust the height if necessary to make room for the string
|
||||
if (stringHeight > size.height) {
|
||||
size.height = stringHeight;
|
||||
}
|
||||
|
||||
// adjust the width if necessary to make room for the string
|
||||
int stringWidth = SwingUtilities2.stringWidth(
|
||||
progressBar, fontSizer, progString);
|
||||
if (stringWidth > size.width) {
|
||||
size.width = stringWidth;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
size = new Dimension(getPreferredInnerVertical());
|
||||
if (progressBar.isStringPainted()) {
|
||||
// make sure the width is big enough for the string
|
||||
if (stringHeight > size.width) {
|
||||
size.width = stringHeight;
|
||||
}
|
||||
|
||||
// make sure the height is big enough for the string
|
||||
int stringWidth = SwingUtilities2.stringWidth(
|
||||
progressBar, fontSizer, progString);
|
||||
if (stringWidth > size.height) {
|
||||
size.height = stringWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle scaling for sizeVarients for special case components. The
|
||||
// key "JComponent.sizeVariant" scales for large/small/mini
|
||||
// components are based on Apples LAF
|
||||
String scaleKey = (String)progressBar.getClientProperty(
|
||||
"JComponent.sizeVariant");
|
||||
if (scaleKey != null){
|
||||
if ("large".equals(scaleKey)){
|
||||
size.width *= 1.15f;
|
||||
size.height *= 1.15f;
|
||||
} else if ("small".equals(scaleKey)){
|
||||
size.width *= 0.90f;
|
||||
size.height *= 0.90f;
|
||||
} else if ("mini".equals(scaleKey)){
|
||||
size.width *= 0.784f;
|
||||
size.height *= 0.784f;
|
||||
}
|
||||
}
|
||||
|
||||
size.width += border.left + border.right;
|
||||
size.height += border.top + border.bottom;
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.plaf.*;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JRadioButtonMenuItem}.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthRadioButtonMenuItemUI extends SynthMenuItemUI {
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param b component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new SynthRadioButtonMenuItemUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "RadioButtonMenuItem";
|
||||
}
|
||||
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintRadioButtonMenuItemBackground(context, g, 0,
|
||||
0, c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintRadioButtonMenuItemBorder(context, g, x,
|
||||
y, w, h);
|
||||
}
|
||||
}
|
||||
85
jdkSrc/jdk8/javax/swing/plaf/synth/SynthRadioButtonUI.java
Normal file
85
jdkSrc/jdk8/javax/swing/plaf/synth/SynthRadioButtonUI.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JRadioButton}.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthRadioButtonUI extends SynthToggleButtonUI {
|
||||
|
||||
// ********************************
|
||||
// Create PLAF
|
||||
// ********************************
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param b component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new SynthRadioButtonUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "RadioButton.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Icon used in calculating the
|
||||
* preferred/minimum/maximum size.
|
||||
*/
|
||||
@Override
|
||||
protected Icon getSizingIcon(AbstractButton b) {
|
||||
return getIcon(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintRadioButtonBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintRadioButtonBorder(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
174
jdkSrc/jdk8/javax/swing/plaf/synth/SynthRootPaneUI.java
Normal file
174
jdkSrc/jdk8/javax/swing/plaf/synth/SynthRootPaneUI.java
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicRootPaneUI;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JRootPane}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthRootPaneUI extends BasicRootPaneUI implements SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthRootPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults(JRootPane c){
|
||||
updateStyle(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults(JRootPane root) {
|
||||
SynthContext context = getContext(root, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions((JRootPane)c);
|
||||
installKeyboardActions((JRootPane)c);
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintRootPaneBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintRootPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a property changes on the root pane. If the event
|
||||
* indicates the <code>defaultButton</code> has changed, this will
|
||||
* reinstall the keyboard actions.
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JRootPane)e.getSource());
|
||||
}
|
||||
super.propertyChange(e);
|
||||
}
|
||||
}
|
||||
475
jdkSrc/jdk8/javax/swing/plaf/synth/SynthScrollBarUI.java
Normal file
475
jdkSrc/jdk8/javax/swing/plaf/synth/SynthScrollBarUI.java
Normal file
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JScrollBar}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthScrollBarUI extends BasicScrollBarUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
|
||||
private SynthStyle style;
|
||||
private SynthStyle thumbStyle;
|
||||
private SynthStyle trackStyle;
|
||||
|
||||
private boolean validMinimumThumbSize;
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthScrollBarUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
trackHighlight = NO_HIGHLIGHT;
|
||||
if (scrollbar.getLayout() == null ||
|
||||
(scrollbar.getLayout() instanceof UIResource)) {
|
||||
scrollbar.setLayout(this);
|
||||
}
|
||||
configureScrollBarColors();
|
||||
updateStyle(scrollbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void configureScrollBarColors() {
|
||||
}
|
||||
|
||||
private void updateStyle(JScrollBar c) {
|
||||
SynthStyle oldStyle = style;
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
scrollBarWidth = style.getInt(context,"ScrollBar.thumbHeight", 14);
|
||||
minimumThumbSize = (Dimension)style.get(context,
|
||||
"ScrollBar.minimumThumbSize");
|
||||
if (minimumThumbSize == null) {
|
||||
minimumThumbSize = new Dimension();
|
||||
validMinimumThumbSize = false;
|
||||
}
|
||||
else {
|
||||
validMinimumThumbSize = true;
|
||||
}
|
||||
maximumThumbSize = (Dimension)style.get(context,
|
||||
"ScrollBar.maximumThumbSize");
|
||||
if (maximumThumbSize == null) {
|
||||
maximumThumbSize = new Dimension(4096, 4097);
|
||||
}
|
||||
|
||||
incrGap = style.getInt(context, "ScrollBar.incrementButtonGap", 0);
|
||||
decrGap = style.getInt(context, "ScrollBar.decrementButtonGap", 0);
|
||||
|
||||
// handle scaling for sizeVarients for special case components. The
|
||||
// key "JComponent.sizeVariant" scales for large/small/mini
|
||||
// components are based on Apples LAF
|
||||
String scaleKey = (String)scrollbar.getClientProperty(
|
||||
"JComponent.sizeVariant");
|
||||
if (scaleKey != null){
|
||||
if ("large".equals(scaleKey)){
|
||||
scrollBarWidth *= 1.15;
|
||||
incrGap *= 1.15;
|
||||
decrGap *= 1.15;
|
||||
} else if ("small".equals(scaleKey)){
|
||||
scrollBarWidth *= 0.857;
|
||||
incrGap *= 0.857;
|
||||
decrGap *= 0.857;
|
||||
} else if ("mini".equals(scaleKey)){
|
||||
scrollBarWidth *= 0.714;
|
||||
incrGap *= 0.714;
|
||||
decrGap *= 0.714;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
|
||||
context = getContext(c, Region.SCROLL_BAR_TRACK, ENABLED);
|
||||
trackStyle = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
|
||||
context = getContext(c, Region.SCROLL_BAR_THUMB, ENABLED);
|
||||
thumbStyle = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
scrollbar.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
scrollbar.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults(){
|
||||
SynthContext context = getContext(scrollbar, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
context = getContext(scrollbar, Region.SCROLL_BAR_TRACK, ENABLED);
|
||||
trackStyle.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
trackStyle = null;
|
||||
|
||||
context = getContext(scrollbar, Region.SCROLL_BAR_THUMB, ENABLED);
|
||||
thumbStyle.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
thumbStyle = null;
|
||||
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region) {
|
||||
return getContext(c, region, getComponentState(c, region));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region, int state) {
|
||||
SynthStyle style = trackStyle;
|
||||
|
||||
if (region == Region.SCROLL_BAR_THUMB) {
|
||||
style = thumbStyle;
|
||||
}
|
||||
return SynthContext.getContext(c, region, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c, Region region) {
|
||||
if (region == Region.SCROLL_BAR_THUMB && isThumbRollover() &&
|
||||
c.isEnabled()) {
|
||||
return MOUSE_OVER;
|
||||
}
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean getSupportsAbsolutePositioning() {
|
||||
SynthContext context = getContext(scrollbar);
|
||||
boolean value = style.getBoolean(context,
|
||||
"ScrollBar.allowsAbsolutePositioning", false);
|
||||
context.dispose();
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintScrollBarBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight(),
|
||||
scrollbar.getOrientation());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
SynthContext subcontext = getContext(scrollbar,
|
||||
Region.SCROLL_BAR_TRACK);
|
||||
paintTrack(subcontext, g, getTrackBounds());
|
||||
subcontext.dispose();
|
||||
|
||||
subcontext = getContext(scrollbar, Region.SCROLL_BAR_THUMB);
|
||||
paintThumb(subcontext, g, getThumbBounds());
|
||||
subcontext.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintScrollBarBorder(context, g, x, y, w, h,
|
||||
scrollbar.getOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the scrollbar track.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g {@code Graphics} object used for painting
|
||||
* @param trackBounds bounding box for the track
|
||||
*/
|
||||
protected void paintTrack(SynthContext context, Graphics g,
|
||||
Rectangle trackBounds) {
|
||||
SynthLookAndFeel.updateSubregion(context, g, trackBounds);
|
||||
context.getPainter().paintScrollBarTrackBackground(context, g, trackBounds.x,
|
||||
trackBounds.y, trackBounds.width, trackBounds.height,
|
||||
scrollbar.getOrientation());
|
||||
context.getPainter().paintScrollBarTrackBorder(context, g, trackBounds.x,
|
||||
trackBounds.y, trackBounds.width, trackBounds.height,
|
||||
scrollbar.getOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the scrollbar thumb.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g {@code Graphics} object used for painting
|
||||
* @param thumbBounds bounding box for the thumb
|
||||
*/
|
||||
protected void paintThumb(SynthContext context, Graphics g,
|
||||
Rectangle thumbBounds) {
|
||||
SynthLookAndFeel.updateSubregion(context, g, thumbBounds);
|
||||
int orientation = scrollbar.getOrientation();
|
||||
context.getPainter().paintScrollBarThumbBackground(context, g, thumbBounds.x,
|
||||
thumbBounds.y, thumbBounds.width, thumbBounds.height,
|
||||
orientation);
|
||||
context.getPainter().paintScrollBarThumbBorder(context, g, thumbBounds.x,
|
||||
thumbBounds.y, thumbBounds.width, thumbBounds.height,
|
||||
orientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* A vertical scrollbar's preferred width is the maximum of
|
||||
* preferred widths of the (non <code>null</code>)
|
||||
* increment/decrement buttons,
|
||||
* and the minimum width of the thumb. The preferred height is the
|
||||
* sum of the preferred heights of the same parts. The basis for
|
||||
* the preferred size of a horizontal scrollbar is similar.
|
||||
* <p>
|
||||
* The <code>preferredSize</code> is only computed once, subsequent
|
||||
* calls to this method just return a cached size.
|
||||
*
|
||||
* @param c the <code>JScrollBar</code> that's delegating this method to us
|
||||
* @return the preferred size of a Basic JScrollBar
|
||||
* @see #getMaximumSize
|
||||
* @see #getMinimumSize
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
Insets insets = c.getInsets();
|
||||
return (scrollbar.getOrientation() == JScrollBar.VERTICAL)
|
||||
? new Dimension(scrollBarWidth + insets.left + insets.right, 48)
|
||||
: new Dimension(48, scrollBarWidth + insets.top + insets.bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Dimension getMinimumThumbSize() {
|
||||
if (!validMinimumThumbSize) {
|
||||
if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
|
||||
minimumThumbSize.width = scrollBarWidth;
|
||||
minimumThumbSize.height = 7;
|
||||
} else {
|
||||
minimumThumbSize.width = 7;
|
||||
minimumThumbSize.height = scrollBarWidth;
|
||||
}
|
||||
}
|
||||
return minimumThumbSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected JButton createDecreaseButton(int orientation) {
|
||||
SynthArrowButton synthArrowButton = new SynthArrowButton(orientation) {
|
||||
@Override
|
||||
public boolean contains(int x, int y) {
|
||||
if (decrGap < 0) { //there is an overlap between the track and button
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
|
||||
//adjust the height by decrGap
|
||||
//Note: decrGap is negative!
|
||||
height += decrGap;
|
||||
} else {
|
||||
//adjust the width by decrGap
|
||||
//Note: decrGap is negative!
|
||||
width += decrGap;
|
||||
}
|
||||
return (x >= 0) && (x < width) && (y >= 0) && (y < height);
|
||||
}
|
||||
return super.contains(x, y);
|
||||
}
|
||||
};
|
||||
synthArrowButton.setName("ScrollBar.button");
|
||||
return synthArrowButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected JButton createIncreaseButton(int orientation) {
|
||||
SynthArrowButton synthArrowButton = new SynthArrowButton(orientation) {
|
||||
@Override
|
||||
public boolean contains(int x, int y) {
|
||||
if (incrGap < 0) { //there is an overlap between the track and button
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
|
||||
//adjust the height and y by incrGap
|
||||
//Note: incrGap is negative!
|
||||
height += incrGap;
|
||||
y += incrGap;
|
||||
} else {
|
||||
//adjust the width and x by incrGap
|
||||
//Note: incrGap is negative!
|
||||
width += incrGap;
|
||||
x += incrGap;
|
||||
}
|
||||
return (x >= 0) && (x < width) && (y >= 0) && (y < height);
|
||||
}
|
||||
return super.contains(x, y);
|
||||
}
|
||||
};
|
||||
synthArrowButton.setName("ScrollBar.button");
|
||||
return synthArrowButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void setThumbRollover(boolean active) {
|
||||
if (isThumbRollover() != active) {
|
||||
scrollbar.repaint(getThumbBounds());
|
||||
super.setThumbRollover(active);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateButtonDirections() {
|
||||
int orient = scrollbar.getOrientation();
|
||||
if (scrollbar.getComponentOrientation().isLeftToRight()) {
|
||||
((SynthArrowButton)incrButton).setDirection(
|
||||
orient == HORIZONTAL? EAST : SOUTH);
|
||||
((SynthArrowButton)decrButton).setDirection(
|
||||
orient == HORIZONTAL? WEST : NORTH);
|
||||
}
|
||||
else {
|
||||
((SynthArrowButton)incrButton).setDirection(
|
||||
orient == HORIZONTAL? WEST : SOUTH);
|
||||
((SynthArrowButton)decrButton).setDirection(
|
||||
orient == HORIZONTAL ? EAST : NORTH);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// PropertyChangeListener
|
||||
//
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
String propertyName = e.getPropertyName();
|
||||
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JScrollBar)e.getSource());
|
||||
}
|
||||
|
||||
if ("orientation" == propertyName) {
|
||||
updateButtonDirections();
|
||||
}
|
||||
else if ("componentOrientation" == propertyName) {
|
||||
updateButtonDirections();
|
||||
}
|
||||
}
|
||||
}
|
||||
308
jdkSrc/jdk8/javax/swing/plaf/synth/SynthScrollPaneUI.java
Normal file
308
jdkSrc/jdk8/javax/swing/plaf/synth/SynthScrollPaneUI.java
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ContainerListener;
|
||||
import java.awt.event.ContainerEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JScrollPane}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthScrollPaneUI extends BasicScrollPaneUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
private boolean viewportViewHasFocus = false;
|
||||
private ViewportViewFocusHandler viewportViewFocusHandler;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthScrollPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintScrollPaneBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
Border vpBorder = scrollpane.getViewportBorder();
|
||||
if (vpBorder != null) {
|
||||
Rectangle r = scrollpane.getViewportBorderBounds();
|
||||
vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintScrollPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults(JScrollPane scrollpane) {
|
||||
updateStyle(scrollpane);
|
||||
}
|
||||
|
||||
private void updateStyle(JScrollPane c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
Border vpBorder = scrollpane.getViewportBorder();
|
||||
if ((vpBorder == null) ||( vpBorder instanceof UIResource)) {
|
||||
scrollpane.setViewportBorder(new ViewportBorder(context));
|
||||
}
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions(c);
|
||||
installKeyboardActions(c);
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners(JScrollPane c) {
|
||||
super.installListeners(c);
|
||||
c.addPropertyChangeListener(this);
|
||||
if (UIManager.getBoolean("ScrollPane.useChildTextComponentFocus")){
|
||||
viewportViewFocusHandler = new ViewportViewFocusHandler();
|
||||
c.getViewport().addContainerListener(viewportViewFocusHandler);
|
||||
Component view = c.getViewport().getView();
|
||||
if (view instanceof JTextComponent) {
|
||||
view.addFocusListener(viewportViewFocusHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults(JScrollPane c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
|
||||
if (scrollpane.getViewportBorder() instanceof UIResource) {
|
||||
scrollpane.setViewportBorder(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners(JComponent c) {
|
||||
super.uninstallListeners(c);
|
||||
c.removePropertyChangeListener(this);
|
||||
if (viewportViewFocusHandler != null) {
|
||||
JViewport viewport = ((JScrollPane) c).getViewport();
|
||||
viewport.removeContainerListener(viewportViewFocusHandler);
|
||||
if (viewport.getView()!= null) {
|
||||
viewport.getView().removeFocusListener(viewportViewFocusHandler);
|
||||
}
|
||||
viewportViewFocusHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
int baseState = SynthLookAndFeel.getComponentState(c);
|
||||
if (viewportViewFocusHandler!=null && viewportViewHasFocus){
|
||||
baseState = baseState | FOCUSED;
|
||||
}
|
||||
return baseState;
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle(scrollpane);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class ViewportBorder extends AbstractBorder implements UIResource {
|
||||
private Insets insets;
|
||||
|
||||
ViewportBorder(SynthContext context) {
|
||||
this.insets = (Insets)context.getStyle().get(context,
|
||||
"ScrollPane.viewportBorderInsets");
|
||||
if (this.insets == null) {
|
||||
this.insets = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y,
|
||||
int width, int height) {
|
||||
JComponent jc = (JComponent)c;
|
||||
SynthContext context = getContext(jc);
|
||||
SynthStyle style = context.getStyle();
|
||||
if (style == null) {
|
||||
assert false: "SynthBorder is being used outside after the " +
|
||||
" UI has been uninstalled";
|
||||
return;
|
||||
}
|
||||
context.getPainter().paintViewportBorder(context, g, x, y, width,
|
||||
height);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
if (insets == null) {
|
||||
return new Insets(this.insets.top, this.insets.left,
|
||||
this.insets.bottom, this.insets.right);
|
||||
}
|
||||
insets.top = this.insets.top;
|
||||
insets.bottom = this.insets.bottom;
|
||||
insets.left = this.insets.left;
|
||||
insets.right = this.insets.left;
|
||||
return insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle keeping track of the viewport's view's focus
|
||||
*/
|
||||
private class ViewportViewFocusHandler implements ContainerListener,
|
||||
FocusListener{
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
if (e.getChild() instanceof JTextComponent) {
|
||||
e.getChild().addFocusListener(this);
|
||||
viewportViewHasFocus = e.getChild().isFocusOwner();
|
||||
scrollpane.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public void componentRemoved(ContainerEvent e) {
|
||||
if (e.getChild() instanceof JTextComponent) {
|
||||
e.getChild().removeFocusListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
viewportViewHasFocus = true;
|
||||
scrollpane.repaint();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
viewportViewHasFocus = false;
|
||||
scrollpane.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
259
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSeparatorUI.java
Normal file
259
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSeparatorUI.java
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.SeparatorUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.DimensionUIResource;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JSeparator}.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
* @author Joshua Outwater
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthSeparatorUI extends SeparatorUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthSeparatorUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
installDefaults((JSeparator)c);
|
||||
installListeners((JSeparator)c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
uninstallListeners((JSeparator)c);
|
||||
uninstallDefaults((JSeparator)c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs default setting. This method is called when a
|
||||
* {@code LookAndFeel} is installed.
|
||||
*/
|
||||
public void installDefaults(JSeparator c) {
|
||||
updateStyle(c);
|
||||
}
|
||||
|
||||
private void updateStyle(JSeparator sep) {
|
||||
SynthContext context = getContext(sep, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
|
||||
if (style != oldStyle) {
|
||||
if (sep instanceof JToolBar.Separator) {
|
||||
Dimension size = ((JToolBar.Separator)sep).getSeparatorSize();
|
||||
if (size == null || size instanceof UIResource) {
|
||||
size = (DimensionUIResource)style.get(
|
||||
context, "ToolBar.separatorSize");
|
||||
if (size == null) {
|
||||
size = new DimensionUIResource(10, 10);
|
||||
}
|
||||
((JToolBar.Separator)sep).setSeparatorSize(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls default setting. This method is called when a
|
||||
* {@code LookAndFeel} is uninstalled.
|
||||
*/
|
||||
public void uninstallDefaults(JSeparator c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs listeners. This method is called when a
|
||||
* {@code LookAndFeel} is installed.
|
||||
*/
|
||||
public void installListeners(JSeparator c) {
|
||||
c.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls listeners. This method is called when a
|
||||
* {@code LookAndFeel} is uninstalled.
|
||||
*/
|
||||
public void uninstallListeners(JSeparator c) {
|
||||
c.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
JSeparator separator = (JSeparator)context.getComponent();
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintSeparatorBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight(),
|
||||
separator.getOrientation());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
JSeparator separator = (JSeparator)context.getComponent();
|
||||
context.getPainter().paintSeparatorForeground(context, g, 0, 0,
|
||||
separator.getWidth(), separator.getHeight(),
|
||||
separator.getOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
JSeparator separator = (JSeparator)context.getComponent();
|
||||
context.getPainter().paintSeparatorBorder(context, g, x, y, w, h,
|
||||
separator.getOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
int thickness = style.getInt(context, "Separator.thickness", 2);
|
||||
Insets insets = c.getInsets();
|
||||
Dimension size;
|
||||
|
||||
if (((JSeparator)c).getOrientation() == JSeparator.VERTICAL) {
|
||||
size = new Dimension(insets.left + insets.right + thickness,
|
||||
insets.top + insets.bottom);
|
||||
} else {
|
||||
size = new Dimension(insets.left + insets.right,
|
||||
insets.top + insets.bottom + thickness);
|
||||
}
|
||||
context.dispose();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMinimumSize(JComponent c) {
|
||||
return getPreferredSize(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMaximumSize(JComponent c) {
|
||||
return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle((JSeparator)evt.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
1006
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSliderUI.java
Normal file
1006
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSliderUI.java
Normal file
File diff suppressed because it is too large
Load Diff
469
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSpinnerUI.java
Normal file
469
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSpinnerUI.java
Normal file
@@ -0,0 +1,469 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicSpinnerUI;
|
||||
import java.beans.*;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JSpinner}.
|
||||
*
|
||||
* @author Hans Muller
|
||||
* @author Joshua Outwater
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthSpinnerUI extends BasicSpinnerUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
/**
|
||||
* A FocusListener implementation which causes the entire spinner to be
|
||||
* repainted whenever the editor component (typically a text field) becomes
|
||||
* focused, or loses focus. This is necessary because since SynthSpinnerUI
|
||||
* is composed of an editor and two buttons, it is necessary that all three
|
||||
* components indicate that they are "focused" so that they can be drawn
|
||||
* appropriately. The repaint is used to ensure that the buttons are drawn
|
||||
* in the new focused or unfocused state, mirroring that of the editor.
|
||||
*/
|
||||
private EditorFocusHandler editorFocusHandler = new EditorFocusHandler();
|
||||
|
||||
/**
|
||||
* Returns a new instance of SynthSpinnerUI.
|
||||
*
|
||||
* @param c the JSpinner (not used)
|
||||
* @see ComponentUI#createUI
|
||||
* @return a new SynthSpinnerUI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthSpinnerUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
spinner.addPropertyChangeListener(this);
|
||||
JComponent editor = spinner.getEditor();
|
||||
if (editor instanceof JSpinner.DefaultEditor) {
|
||||
JTextField tf = ((JSpinner.DefaultEditor)editor).getTextField();
|
||||
if (tf != null) {
|
||||
tf.addFocusListener(editorFocusHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
spinner.removePropertyChangeListener(this);
|
||||
JComponent editor = spinner.getEditor();
|
||||
if (editor instanceof JSpinner.DefaultEditor) {
|
||||
JTextField tf = ((JSpinner.DefaultEditor)editor).getTextField();
|
||||
if (tf != null) {
|
||||
tf.removeFocusListener(editorFocusHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the <code>JSpinner</code> <code>border</code>,
|
||||
* <code>foreground</code>, and <code>background</code>, properties
|
||||
* based on the corresponding "Spinner.*" properties from defaults table.
|
||||
* The <code>JSpinners</code> layout is set to the value returned by
|
||||
* <code>createLayout</code>. This method is called by <code>installUI</code>.
|
||||
*
|
||||
* @see #uninstallDefaults
|
||||
* @see #installUI
|
||||
* @see #createLayout
|
||||
* @see LookAndFeel#installBorder
|
||||
* @see LookAndFeel#installColors
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
LayoutManager layout = spinner.getLayout();
|
||||
|
||||
if (layout == null || layout instanceof UIResource) {
|
||||
spinner.setLayout(createLayout());
|
||||
}
|
||||
updateStyle(spinner);
|
||||
}
|
||||
|
||||
|
||||
private void updateStyle(JSpinner c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
if (oldStyle != null) {
|
||||
// Only call installKeyboardActions as uninstall is not
|
||||
// public.
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>JSpinner's</code> layout manager to null. This
|
||||
* method is called by <code>uninstallUI</code>.
|
||||
*
|
||||
* @see #installDefaults
|
||||
* @see #uninstallUI
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
if (spinner.getLayout() instanceof UIResource) {
|
||||
spinner.setLayout(null);
|
||||
}
|
||||
|
||||
SynthContext context = getContext(spinner, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected LayoutManager createLayout() {
|
||||
return new SpinnerLayout();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Component createPreviousButton() {
|
||||
JButton b = new SynthArrowButton(SwingConstants.SOUTH);
|
||||
b.setName("Spinner.previousButton");
|
||||
installPreviousButtonListeners(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Component createNextButton() {
|
||||
JButton b = new SynthArrowButton(SwingConstants.NORTH);
|
||||
b.setName("Spinner.nextButton");
|
||||
installNextButtonListeners(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is called by installUI to get the editor component
|
||||
* of the <code>JSpinner</code>. By default it just returns
|
||||
* <code>JSpinner.getEditor()</code>. Subclasses can override
|
||||
* <code>createEditor</code> to return a component that contains
|
||||
* the spinner's editor or null, if they're going to handle adding
|
||||
* the editor to the <code>JSpinner</code> in an
|
||||
* <code>installUI</code> override.
|
||||
* <p>
|
||||
* Typically this method would be overridden to wrap the editor
|
||||
* with a container with a custom border, since one can't assume
|
||||
* that the editors border can be set directly.
|
||||
* <p>
|
||||
* The <code>replaceEditor</code> method is called when the spinners
|
||||
* editor is changed with <code>JSpinner.setEditor</code>. If you've
|
||||
* overriden this method, then you'll probably want to override
|
||||
* <code>replaceEditor</code> as well.
|
||||
*
|
||||
* @return the JSpinners editor JComponent, spinner.getEditor() by default
|
||||
* @see #installUI
|
||||
* @see #replaceEditor
|
||||
* @see JSpinner#getEditor
|
||||
*/
|
||||
@Override
|
||||
protected JComponent createEditor() {
|
||||
JComponent editor = spinner.getEditor();
|
||||
editor.setName("Spinner.editor");
|
||||
updateEditorAlignment(editor);
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the <code>PropertyChangeListener</code> when the
|
||||
* <code>JSpinner</code> editor property changes. It's the responsibility
|
||||
* of this method to remove the old editor and add the new one. By
|
||||
* default this operation is just:
|
||||
* <pre>
|
||||
* spinner.remove(oldEditor);
|
||||
* spinner.add(newEditor, "Editor");
|
||||
* </pre>
|
||||
* The implementation of <code>replaceEditor</code> should be coordinated
|
||||
* with the <code>createEditor</code> method.
|
||||
*
|
||||
* @see #createEditor
|
||||
* @see #createPropertyChangeListener
|
||||
*/
|
||||
@Override
|
||||
protected void replaceEditor(JComponent oldEditor, JComponent newEditor) {
|
||||
spinner.remove(oldEditor);
|
||||
spinner.add(newEditor, "Editor");
|
||||
if (oldEditor instanceof JSpinner.DefaultEditor) {
|
||||
JTextField tf = ((JSpinner.DefaultEditor)oldEditor).getTextField();
|
||||
if (tf != null) {
|
||||
tf.removeFocusListener(editorFocusHandler);
|
||||
}
|
||||
}
|
||||
if (newEditor instanceof JSpinner.DefaultEditor) {
|
||||
JTextField tf = ((JSpinner.DefaultEditor)newEditor).getTextField();
|
||||
if (tf != null) {
|
||||
tf.addFocusListener(editorFocusHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEditorAlignment(JComponent editor) {
|
||||
if (editor instanceof JSpinner.DefaultEditor) {
|
||||
SynthContext context = getContext(spinner);
|
||||
Integer alignment = (Integer)context.getStyle().get(
|
||||
context, "Spinner.editorAlignment");
|
||||
JTextField text = ((JSpinner.DefaultEditor)editor).getTextField();
|
||||
if (alignment != null) {
|
||||
text.setHorizontalAlignment(alignment);
|
||||
|
||||
}
|
||||
// copy across the sizeVariant property to the editor
|
||||
text.putClientProperty("JComponent.sizeVariant",
|
||||
spinner.getClientProperty("JComponent.sizeVariant"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintSpinnerBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintSpinnerBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple layout manager for the editor and the next/previous buttons.
|
||||
* See the SynthSpinnerUI javadoc for more information about exactly
|
||||
* how the components are arranged.
|
||||
*/
|
||||
private static class SpinnerLayout implements LayoutManager, UIResource
|
||||
{
|
||||
private Component nextButton = null;
|
||||
private Component previousButton = null;
|
||||
private Component editor = null;
|
||||
|
||||
public void addLayoutComponent(String name, Component c) {
|
||||
if ("Next".equals(name)) {
|
||||
nextButton = c;
|
||||
}
|
||||
else if ("Previous".equals(name)) {
|
||||
previousButton = c;
|
||||
}
|
||||
else if ("Editor".equals(name)) {
|
||||
editor = c;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLayoutComponent(Component c) {
|
||||
if (c == nextButton) {
|
||||
nextButton = null;
|
||||
}
|
||||
else if (c == previousButton) {
|
||||
previousButton = null;
|
||||
}
|
||||
else if (c == editor) {
|
||||
editor = null;
|
||||
}
|
||||
}
|
||||
|
||||
private Dimension preferredSize(Component c) {
|
||||
return (c == null) ? new Dimension(0, 0) : c.getPreferredSize();
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
Dimension nextD = preferredSize(nextButton);
|
||||
Dimension previousD = preferredSize(previousButton);
|
||||
Dimension editorD = preferredSize(editor);
|
||||
|
||||
/* Force the editors height to be a multiple of 2
|
||||
*/
|
||||
editorD.height = ((editorD.height + 1) / 2) * 2;
|
||||
|
||||
Dimension size = new Dimension(editorD.width, editorD.height);
|
||||
size.width += Math.max(nextD.width, previousD.width);
|
||||
Insets insets = parent.getInsets();
|
||||
size.width += insets.left + insets.right;
|
||||
size.height += insets.top + insets.bottom;
|
||||
return size;
|
||||
}
|
||||
|
||||
public Dimension minimumLayoutSize(Container parent) {
|
||||
return preferredLayoutSize(parent);
|
||||
}
|
||||
|
||||
private void setBounds(Component c, int x, int y, int width, int height) {
|
||||
if (c != null) {
|
||||
c.setBounds(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
public void layoutContainer(Container parent) {
|
||||
Insets insets = parent.getInsets();
|
||||
int availWidth = parent.getWidth() - (insets.left + insets.right);
|
||||
int availHeight = parent.getHeight() - (insets.top + insets.bottom);
|
||||
Dimension nextD = preferredSize(nextButton);
|
||||
Dimension previousD = preferredSize(previousButton);
|
||||
int nextHeight = availHeight / 2;
|
||||
int previousHeight = availHeight - nextHeight;
|
||||
int buttonsWidth = Math.max(nextD.width, previousD.width);
|
||||
int editorWidth = availWidth - buttonsWidth;
|
||||
|
||||
/* Deal with the spinners componentOrientation property.
|
||||
*/
|
||||
int editorX, buttonsX;
|
||||
if (parent.getComponentOrientation().isLeftToRight()) {
|
||||
editorX = insets.left;
|
||||
buttonsX = editorX + editorWidth;
|
||||
}
|
||||
else {
|
||||
buttonsX = insets.left;
|
||||
editorX = buttonsX + buttonsWidth;
|
||||
}
|
||||
|
||||
int previousY = insets.top + nextHeight;
|
||||
setBounds(editor, editorX, insets.top, editorWidth, availHeight);
|
||||
setBounds(nextButton, buttonsX, insets.top, buttonsWidth, nextHeight);
|
||||
setBounds(previousButton, buttonsX, previousY, buttonsWidth, previousHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
JSpinner spinner = (JSpinner)(e.getSource());
|
||||
SpinnerUI spinnerUI = spinner.getUI();
|
||||
|
||||
if (spinnerUI instanceof SynthSpinnerUI) {
|
||||
SynthSpinnerUI ui = (SynthSpinnerUI)spinnerUI;
|
||||
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
ui.updateStyle(spinner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Listen to editor text field focus changes and repaint whole spinner */
|
||||
private class EditorFocusHandler implements FocusListener{
|
||||
/** Invoked when a editor text field gains the keyboard focus. */
|
||||
@Override public void focusGained(FocusEvent e) {
|
||||
spinner.repaint();
|
||||
}
|
||||
|
||||
/** Invoked when a editor text field loses the keyboard focus. */
|
||||
@Override public void focusLost(FocusEvent e) {
|
||||
spinner.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
151
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSplitPaneDivider.java
Normal file
151
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSplitPaneDivider.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import sun.swing.DefaultLookup;
|
||||
|
||||
/**
|
||||
* Synth's SplitPaneDivider.
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class SynthSplitPaneDivider extends BasicSplitPaneDivider {
|
||||
public SynthSplitPaneDivider(BasicSplitPaneUI ui) {
|
||||
super(ui);
|
||||
}
|
||||
|
||||
protected void setMouseOver(boolean mouseOver) {
|
||||
if (isMouseOver() != mouseOver) {
|
||||
repaint();
|
||||
}
|
||||
super.setMouseOver(mouseOver);
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
super.propertyChange(e);
|
||||
if (e.getSource() == splitPane) {
|
||||
if (e.getPropertyName() == JSplitPane.ORIENTATION_PROPERTY) {
|
||||
if (leftButton instanceof SynthArrowButton) {
|
||||
((SynthArrowButton)leftButton).setDirection(
|
||||
mapDirection(true));
|
||||
}
|
||||
if (rightButton instanceof SynthArrowButton) {
|
||||
((SynthArrowButton)rightButton).setDirection(
|
||||
mapDirection(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
Graphics g2 = g.create();
|
||||
|
||||
SynthContext context = ((SynthSplitPaneUI)splitPaneUI).getContext(
|
||||
splitPane, Region.SPLIT_PANE_DIVIDER);
|
||||
Rectangle bounds = getBounds();
|
||||
bounds.x = bounds.y = 0;
|
||||
SynthLookAndFeel.updateSubregion(context, g, bounds);
|
||||
context.getPainter().paintSplitPaneDividerBackground(context,
|
||||
g, 0, 0, bounds.width, bounds.height,
|
||||
splitPane.getOrientation());
|
||||
|
||||
SynthPainter foreground = null;
|
||||
|
||||
context.getPainter().paintSplitPaneDividerForeground(context, g, 0, 0,
|
||||
getWidth(), getHeight(), splitPane.getOrientation());
|
||||
context.dispose();
|
||||
|
||||
// super.paint(g2);
|
||||
for (int counter = 0; counter < getComponentCount(); counter++) {
|
||||
Component child = getComponent(counter);
|
||||
Rectangle childBounds = child.getBounds();
|
||||
Graphics childG = g.create(childBounds.x, childBounds.y,
|
||||
childBounds.width, childBounds.height);
|
||||
child.paint(childG);
|
||||
childG.dispose();
|
||||
}
|
||||
g2.dispose();
|
||||
}
|
||||
|
||||
private int mapDirection(boolean isLeft) {
|
||||
if (isLeft) {
|
||||
if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT){
|
||||
return SwingConstants.WEST;
|
||||
}
|
||||
return SwingConstants.NORTH;
|
||||
}
|
||||
if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT){
|
||||
return SwingConstants.EAST;
|
||||
}
|
||||
return SwingConstants.SOUTH;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and return an instance of JButton that can be used to
|
||||
* collapse the left component in the split pane.
|
||||
*/
|
||||
protected JButton createLeftOneTouchButton() {
|
||||
SynthArrowButton b = new SynthArrowButton(SwingConstants.NORTH);
|
||||
int oneTouchSize = lookupOneTouchSize();
|
||||
|
||||
b.setName("SplitPaneDivider.leftOneTouchButton");
|
||||
b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));
|
||||
b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
b.setFocusPainted(false);
|
||||
b.setBorderPainted(false);
|
||||
b.setRequestFocusEnabled(false);
|
||||
b.setDirection(mapDirection(true));
|
||||
return b;
|
||||
}
|
||||
|
||||
private int lookupOneTouchSize() {
|
||||
return DefaultLookup.getInt(splitPaneUI.getSplitPane(), splitPaneUI,
|
||||
"SplitPaneDivider.oneTouchButtonSize", ONE_TOUCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and return an instance of JButton that can be used to
|
||||
* collapse the right component in the split pane.
|
||||
*/
|
||||
protected JButton createRightOneTouchButton() {
|
||||
SynthArrowButton b = new SynthArrowButton(SwingConstants.NORTH);
|
||||
int oneTouchSize = lookupOneTouchSize();
|
||||
|
||||
b.setName("SplitPaneDivider.rightOneTouchButton");
|
||||
b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));
|
||||
b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
b.setFocusPainted(false);
|
||||
b.setBorderPainted(false);
|
||||
b.setRequestFocusEnabled(false);
|
||||
b.setDirection(mapDirection(false));
|
||||
return b;
|
||||
}
|
||||
}
|
||||
358
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSplitPaneUI.java
Normal file
358
jdkSrc/jdk8/javax/swing/plaf/synth/SynthSplitPaneUI.java
Normal file
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.util.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JSplitPane}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthSplitPaneUI extends BasicSplitPaneUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
/**
|
||||
* Keys to use for forward focus traversal when the JComponent is
|
||||
* managing focus.
|
||||
*/
|
||||
private static Set<KeyStroke> managingFocusForwardTraversalKeys;
|
||||
|
||||
/**
|
||||
* Keys to use for backward focus traversal when the JComponent is
|
||||
* managing focus.
|
||||
*/
|
||||
private static Set<KeyStroke> managingFocusBackwardTraversalKeys;
|
||||
|
||||
/**
|
||||
* Style for the JSplitPane.
|
||||
*/
|
||||
private SynthStyle style;
|
||||
/**
|
||||
* Style for the divider.
|
||||
*/
|
||||
private SynthStyle dividerStyle;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SynthSplitPaneUI instance
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthSplitPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the UI defaults.
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(splitPane);
|
||||
|
||||
setOrientation(splitPane.getOrientation());
|
||||
setContinuousLayout(splitPane.isContinuousLayout());
|
||||
|
||||
resetLayoutManager();
|
||||
|
||||
/* Install the nonContinuousLayoutDivider here to avoid having to
|
||||
add/remove everything later. */
|
||||
if(nonContinuousLayoutDivider == null) {
|
||||
setNonContinuousLayoutDivider(
|
||||
createDefaultNonContinuousLayoutDivider(),
|
||||
true);
|
||||
} else {
|
||||
setNonContinuousLayoutDivider(nonContinuousLayoutDivider, true);
|
||||
}
|
||||
|
||||
// focus forward traversal key
|
||||
if (managingFocusForwardTraversalKeys==null) {
|
||||
managingFocusForwardTraversalKeys = new HashSet<KeyStroke>();
|
||||
managingFocusForwardTraversalKeys.add(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
|
||||
}
|
||||
splitPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
||||
managingFocusForwardTraversalKeys);
|
||||
// focus backward traversal key
|
||||
if (managingFocusBackwardTraversalKeys==null) {
|
||||
managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>();
|
||||
managingFocusBackwardTraversalKeys.add(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));
|
||||
}
|
||||
splitPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
|
||||
managingFocusBackwardTraversalKeys);
|
||||
}
|
||||
|
||||
private void updateStyle(JSplitPane splitPane) {
|
||||
SynthContext context = getContext(splitPane, Region.SPLIT_PANE_DIVIDER,
|
||||
ENABLED);
|
||||
SynthStyle oldDividerStyle = dividerStyle;
|
||||
dividerStyle = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
|
||||
context = getContext(splitPane, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
|
||||
if (style != oldStyle) {
|
||||
Object value = style.get(context, "SplitPane.size");
|
||||
if (value == null) {
|
||||
value = Integer.valueOf(6);
|
||||
}
|
||||
LookAndFeel.installProperty(splitPane, "dividerSize", value);
|
||||
|
||||
value = style.get(context, "SplitPane.oneTouchExpandable");
|
||||
if (value != null) {
|
||||
LookAndFeel.installProperty(splitPane, "oneTouchExpandable", value);
|
||||
}
|
||||
|
||||
if (divider != null) {
|
||||
splitPane.remove(divider);
|
||||
divider.setDividerSize(splitPane.getDividerSize());
|
||||
}
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
if (style != oldStyle || dividerStyle != oldDividerStyle) {
|
||||
// Only way to force BasicSplitPaneDivider to reread the
|
||||
// necessary properties.
|
||||
if (divider != null) {
|
||||
splitPane.remove(divider);
|
||||
}
|
||||
divider = createDefaultDivider();
|
||||
divider.setBasicSplitPaneUI(this);
|
||||
splitPane.add(divider, JSplitPane.DIVIDER);
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the event listeners for the UI.
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
splitPane.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls the UI defaults.
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(splitPane, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
context = getContext(splitPane, Region.SPLIT_PANE_DIVIDER, ENABLED);
|
||||
dividerStyle.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
dividerStyle = null;
|
||||
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Uninstalls the event listeners from the UI.
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
splitPane.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
SynthContext getContext(JComponent c, Region region) {
|
||||
return getContext(c, region, getComponentState(c, region));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region, int state) {
|
||||
if (region == Region.SPLIT_PANE_DIVIDER) {
|
||||
return SynthContext.getContext(c, region, dividerStyle, state);
|
||||
}
|
||||
return SynthContext.getContext(c, region, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c, Region subregion) {
|
||||
int state = SynthLookAndFeel.getComponentState(c);
|
||||
|
||||
if (divider.isMouseOver()) {
|
||||
state |= MOUSE_OVER;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JSplitPane)e.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the default divider.
|
||||
*/
|
||||
@Override
|
||||
public BasicSplitPaneDivider createDefaultDivider() {
|
||||
SynthSplitPaneDivider divider = new SynthSplitPaneDivider(this);
|
||||
|
||||
divider.setDividerSize(splitPane.getDividerSize());
|
||||
return divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Component createDefaultNonContinuousLayoutDivider() {
|
||||
return new Canvas() {
|
||||
public void paint(Graphics g) {
|
||||
paintDragDivider(g, 0, 0, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintSplitPaneBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
// This is done to update package private variables in
|
||||
// BasicSplitPaneUI
|
||||
super.paint(g, splitPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintSplitPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
private void paintDragDivider(Graphics g, int x, int y, int w, int h) {
|
||||
SynthContext context = getContext(splitPane,Region.SPLIT_PANE_DIVIDER);
|
||||
context.setComponentState(((context.getComponentState() | MOUSE_OVER) ^
|
||||
MOUSE_OVER) | PRESSED);
|
||||
Shape oldClip = g.getClip();
|
||||
g.clipRect(x, y, w, h);
|
||||
context.getPainter().paintSplitPaneDragDivider(context, g, x, y, w, h,
|
||||
splitPane.getOrientation());
|
||||
g.setClip(oldClip);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void finishedPaintingChildren(JSplitPane jc, Graphics g) {
|
||||
if(jc == splitPane && getLastDragLocation() != -1 &&
|
||||
!isContinuousLayout() && !draggingHW) {
|
||||
if(jc.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
|
||||
paintDragDivider(g, getLastDragLocation(), 0, dividerSize - 1,
|
||||
splitPane.getHeight() - 1);
|
||||
} else {
|
||||
paintDragDivider(g, 0, getLastDragLocation(),
|
||||
splitPane.getWidth() - 1, dividerSize - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1053
jdkSrc/jdk8/javax/swing/plaf/synth/SynthStyle.java
Normal file
1053
jdkSrc/jdk8/javax/swing/plaf/synth/SynthStyle.java
Normal file
File diff suppressed because it is too large
Load Diff
75
jdkSrc/jdk8/javax/swing/plaf/synth/SynthStyleFactory.java
Normal file
75
jdkSrc/jdk8/javax/swing/plaf/synth/SynthStyleFactory.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
* Factory used for obtaining <code>SynthStyle</code>s. Each of the
|
||||
* Synth <code>ComponentUI</code>s will call into the current
|
||||
* <code>SynthStyleFactory</code> to obtain a <code>SynthStyle</code>
|
||||
* for each of the distinct regions they have.
|
||||
* <p>
|
||||
* The following example creates a custom <code>SynthStyleFactory</code>
|
||||
* that returns a different style based on the <code>Region</code>:
|
||||
* <pre>
|
||||
* class MyStyleFactory extends SynthStyleFactory {
|
||||
* public SynthStyle getStyle(JComponent c, Region id) {
|
||||
* if (id == Region.BUTTON) {
|
||||
* return buttonStyle;
|
||||
* }
|
||||
* else if (id == Region.TREE) {
|
||||
* return treeStyle;
|
||||
* }
|
||||
* return defaultStyle;
|
||||
* }
|
||||
* }
|
||||
* SynthLookAndFeel laf = new SynthLookAndFeel();
|
||||
* UIManager.setLookAndFeel(laf);
|
||||
* SynthLookAndFeel.setStyleFactory(new MyStyleFactory());
|
||||
* </pre>
|
||||
*
|
||||
* @see SynthStyleFactory
|
||||
* @see SynthStyle
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Scott Violet
|
||||
*/
|
||||
public abstract class SynthStyleFactory {
|
||||
/**
|
||||
* Creates a <code>SynthStyleFactory</code>.
|
||||
*/
|
||||
public SynthStyleFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the style for the specified Component.
|
||||
*
|
||||
* @param c Component asking for
|
||||
* @param id Region identifier
|
||||
* @return SynthStyle for region.
|
||||
*/
|
||||
public abstract SynthStyle getStyle(JComponent c, Region id);
|
||||
}
|
||||
930
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTabbedPaneUI.java
Normal file
930
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTabbedPaneUI.java
Normal file
@@ -0,0 +1,930 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import javax.swing.text.View;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import sun.swing.SwingUtilities2;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JTabbedPane}.
|
||||
*
|
||||
* <p>Looks up the {@code selectedTabPadInsets} property from the Style,
|
||||
* which represents additional insets for the selected tab.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthTabbedPaneUI extends BasicTabbedPaneUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
|
||||
/**
|
||||
* <p>If non-zero, tabOverlap indicates the amount that the tab bounds
|
||||
* should be altered such that they would overlap with a tab on either the
|
||||
* leading or trailing end of a run (ie: in TOP, this would be on the left
|
||||
* or right).</p>
|
||||
|
||||
* <p>A positive overlap indicates that tabs should overlap right/down,
|
||||
* while a negative overlap indicates tha tabs should overlap left/up.</p>
|
||||
*
|
||||
* <p>When tabOverlap is specified, it both changes the x position and width
|
||||
* of the tab if in TOP or BOTTOM placement, and changes the y position and
|
||||
* height if in LEFT or RIGHT placement.</p>
|
||||
*
|
||||
* <p>This is done for the following reason. Consider a run of 10 tabs.
|
||||
* There are 9 gaps between these tabs. If you specified a tabOverlap of
|
||||
* "-1", then each of the tabs "x" values will be shifted left. This leaves
|
||||
* 9 pixels of space to the right of the right-most tab unpainted. So, each
|
||||
* tab's width is also extended by 1 pixel to make up the difference.</p>
|
||||
*
|
||||
* <p>This property respects the RTL component orientation.</p>
|
||||
*/
|
||||
private int tabOverlap = 0;
|
||||
|
||||
/**
|
||||
* When a tabbed pane has multiple rows of tabs, this indicates whether
|
||||
* the tabs in the upper row(s) should extend to the base of the tab area,
|
||||
* or whether they should remain at their normal tab height. This does not
|
||||
* affect the bounds of the tabs, only the bounds of area painted by the
|
||||
* tabs. The text position does not change. The result is that the bottom
|
||||
* border of the upper row of tabs becomes fully obscured by the lower tabs,
|
||||
* resulting in a cleaner look.
|
||||
*/
|
||||
private boolean extendTabsToBase = false;
|
||||
|
||||
private SynthContext tabAreaContext;
|
||||
private SynthContext tabContext;
|
||||
private SynthContext tabContentContext;
|
||||
|
||||
private SynthStyle style;
|
||||
private SynthStyle tabStyle;
|
||||
private SynthStyle tabAreaStyle;
|
||||
private SynthStyle tabContentStyle;
|
||||
|
||||
private Rectangle textRect = new Rectangle();
|
||||
private Rectangle iconRect = new Rectangle();
|
||||
|
||||
private Rectangle tabAreaBounds = new Rectangle();
|
||||
|
||||
//added for the Nimbus look and feel, where the tab area is painted differently depending on the
|
||||
//state for the selected tab
|
||||
private boolean tabAreaStatesMatchSelectedTab = false;
|
||||
//added for the Nimbus LAF to ensure that the labels don't move whether the tab is selected or not
|
||||
private boolean nudgeSelectedLabel = true;
|
||||
|
||||
private boolean selectedTabIsPressed = false;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthTabbedPaneUI();
|
||||
}
|
||||
|
||||
private boolean scrollableTabLayoutEnabled() {
|
||||
return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(tabPane);
|
||||
}
|
||||
|
||||
private void updateStyle(JTabbedPane c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
// Add properties other than JComponent colors, Borders and
|
||||
// opacity settings here:
|
||||
if (style != oldStyle) {
|
||||
tabRunOverlay =
|
||||
style.getInt(context, "TabbedPane.tabRunOverlay", 0);
|
||||
tabOverlap = style.getInt(context, "TabbedPane.tabOverlap", 0);
|
||||
extendTabsToBase = style.getBoolean(context,
|
||||
"TabbedPane.extendTabsToBase", false);
|
||||
textIconGap = style.getInt(context, "TabbedPane.textIconGap", 0);
|
||||
selectedTabPadInsets = (Insets)style.get(context,
|
||||
"TabbedPane.selectedTabPadInsets");
|
||||
if (selectedTabPadInsets == null) {
|
||||
selectedTabPadInsets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
tabAreaStatesMatchSelectedTab = style.getBoolean(context,
|
||||
"TabbedPane.tabAreaStatesMatchSelectedTab", false);
|
||||
nudgeSelectedLabel = style.getBoolean(context,
|
||||
"TabbedPane.nudgeSelectedLabel", true);
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
|
||||
if (tabContext != null) {
|
||||
tabContext.dispose();
|
||||
}
|
||||
tabContext = getContext(c, Region.TABBED_PANE_TAB, ENABLED);
|
||||
this.tabStyle = SynthLookAndFeel.updateStyle(tabContext, this);
|
||||
tabInsets = tabStyle.getInsets(tabContext, null);
|
||||
|
||||
|
||||
if (tabAreaContext != null) {
|
||||
tabAreaContext.dispose();
|
||||
}
|
||||
tabAreaContext = getContext(c, Region.TABBED_PANE_TAB_AREA, ENABLED);
|
||||
this.tabAreaStyle = SynthLookAndFeel.updateStyle(tabAreaContext, this);
|
||||
tabAreaInsets = tabAreaStyle.getInsets(tabAreaContext, null);
|
||||
|
||||
|
||||
if (tabContentContext != null) {
|
||||
tabContentContext.dispose();
|
||||
}
|
||||
tabContentContext = getContext(c, Region.TABBED_PANE_CONTENT, ENABLED);
|
||||
this.tabContentStyle = SynthLookAndFeel.updateStyle(tabContentContext,
|
||||
this);
|
||||
contentBorderInsets =
|
||||
tabContentStyle.getInsets(tabContentContext, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
tabPane.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
tabPane.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(tabPane, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
tabStyle.uninstallDefaults(tabContext);
|
||||
tabContext.dispose();
|
||||
tabContext = null;
|
||||
tabStyle = null;
|
||||
|
||||
tabAreaStyle.uninstallDefaults(tabAreaContext);
|
||||
tabAreaContext.dispose();
|
||||
tabAreaContext = null;
|
||||
tabAreaStyle = null;
|
||||
|
||||
tabContentStyle.uninstallDefaults(tabContentContext);
|
||||
tabContentContext.dispose();
|
||||
tabContentContext = null;
|
||||
tabContentStyle = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region subregion, int state){
|
||||
SynthStyle style = null;
|
||||
|
||||
if (subregion == Region.TABBED_PANE_TAB) {
|
||||
style = tabStyle;
|
||||
}
|
||||
else if (subregion == Region.TABBED_PANE_TAB_AREA) {
|
||||
style = tabAreaStyle;
|
||||
}
|
||||
else if (subregion == Region.TABBED_PANE_CONTENT) {
|
||||
style = tabContentStyle;
|
||||
}
|
||||
return SynthContext.getContext(c, subregion, style, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected JButton createScrollButton(int direction) {
|
||||
// added for Nimbus LAF so that it can use the basic arrow buttons
|
||||
// UIManager is queried directly here because this is called before
|
||||
// updateStyle is called so the style can not be queried directly
|
||||
if (UIManager.getBoolean("TabbedPane.useBasicArrows")) {
|
||||
JButton btn = super.createScrollButton(direction);
|
||||
btn.setBorder(BorderFactory.createEmptyBorder());
|
||||
return btn;
|
||||
}
|
||||
return new SynthScrollableTabButton(direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle(tabPane);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Overridden to keep track of whether the selected tab is also pressed.
|
||||
*/
|
||||
@Override
|
||||
protected MouseListener createMouseListener() {
|
||||
final MouseListener delegate = super.createMouseListener();
|
||||
final MouseMotionListener delegate2 = (MouseMotionListener)delegate;
|
||||
return new MouseListener() {
|
||||
public void mouseClicked(MouseEvent e) { delegate.mouseClicked(e); }
|
||||
public void mouseEntered(MouseEvent e) { delegate.mouseEntered(e); }
|
||||
public void mouseExited(MouseEvent e) { delegate.mouseExited(e); }
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (!tabPane.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int tabIndex = tabForCoordinate(tabPane, e.getX(), e.getY());
|
||||
if (tabIndex >= 0 && tabPane.isEnabledAt(tabIndex)) {
|
||||
if (tabIndex == tabPane.getSelectedIndex()) {
|
||||
// Clicking on selected tab
|
||||
selectedTabIsPressed = true;
|
||||
//TODO need to just repaint the tab area!
|
||||
tabPane.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
//forward the event (this will set the selected index, or none at all
|
||||
delegate.mousePressed(e);
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (selectedTabIsPressed) {
|
||||
selectedTabIsPressed = false;
|
||||
//TODO need to just repaint the tab area!
|
||||
tabPane.repaint();
|
||||
}
|
||||
//forward the event
|
||||
delegate.mouseReleased(e);
|
||||
|
||||
//hack: The super method *should* be setting the mouse-over property correctly
|
||||
//here, but it doesn't. That is, when the mouse is released, whatever tab is below the
|
||||
//released mouse should be in rollover state. But, if you select a tab and don't
|
||||
//move the mouse, this doesn't happen. Hence, forwarding the event.
|
||||
delegate2.mouseMoved(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) {
|
||||
if (nudgeSelectedLabel) {
|
||||
return super.getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) {
|
||||
if (nudgeSelectedLabel) {
|
||||
return super.getTabLabelShiftY(tabPlacement, tabIndex, isSelected);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintTabbedPaneBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected int getBaseline(int tab) {
|
||||
if (tabPane.getTabComponentAt(tab) != null ||
|
||||
getTextViewForTab(tab) != null) {
|
||||
return super.getBaseline(tab);
|
||||
}
|
||||
String title = tabPane.getTitleAt(tab);
|
||||
Font font = tabContext.getStyle().getFont(tabContext);
|
||||
FontMetrics metrics = getFontMetrics(font);
|
||||
Icon icon = getIconForTab(tab);
|
||||
textRect.setBounds(0, 0, 0, 0);
|
||||
iconRect.setBounds(0, 0, 0, 0);
|
||||
calcRect.setBounds(0, 0, Short.MAX_VALUE, maxTabHeight);
|
||||
tabContext.getStyle().getGraphicsUtils(tabContext).layoutText(
|
||||
tabContext, metrics, title, icon, SwingUtilities.CENTER,
|
||||
SwingUtilities.CENTER, SwingUtilities.LEADING,
|
||||
SwingUtilities.CENTER, calcRect,
|
||||
iconRect, textRect, textIconGap);
|
||||
return textRect.y + metrics.getAscent() + getBaselineOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintTabbedPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
int selectedIndex = tabPane.getSelectedIndex();
|
||||
int tabPlacement = tabPane.getTabPlacement();
|
||||
|
||||
ensureCurrentLayout();
|
||||
|
||||
// Paint tab area
|
||||
// If scrollable tabs are enabled, the tab area will be
|
||||
// painted by the scrollable tab panel instead.
|
||||
//
|
||||
if (!scrollableTabLayoutEnabled()) { // WRAP_TAB_LAYOUT
|
||||
Insets insets = tabPane.getInsets();
|
||||
int x = insets.left;
|
||||
int y = insets.top;
|
||||
int width = tabPane.getWidth() - insets.left - insets.right;
|
||||
int height = tabPane.getHeight() - insets.top - insets.bottom;
|
||||
int size;
|
||||
switch(tabPlacement) {
|
||||
case LEFT:
|
||||
width = calculateTabAreaWidth(tabPlacement, runCount,
|
||||
maxTabWidth);
|
||||
break;
|
||||
case RIGHT:
|
||||
size = calculateTabAreaWidth(tabPlacement, runCount,
|
||||
maxTabWidth);
|
||||
x = x + width - size;
|
||||
width = size;
|
||||
break;
|
||||
case BOTTOM:
|
||||
size = calculateTabAreaHeight(tabPlacement, runCount,
|
||||
maxTabHeight);
|
||||
y = y + height - size;
|
||||
height = size;
|
||||
break;
|
||||
case TOP:
|
||||
default:
|
||||
height = calculateTabAreaHeight(tabPlacement, runCount,
|
||||
maxTabHeight);
|
||||
}
|
||||
|
||||
tabAreaBounds.setBounds(x, y, width, height);
|
||||
|
||||
if (g.getClipBounds().intersects(tabAreaBounds)) {
|
||||
paintTabArea(tabAreaContext, g, tabPlacement,
|
||||
selectedIndex, tabAreaBounds);
|
||||
}
|
||||
}
|
||||
|
||||
// Paint content border
|
||||
paintContentBorder(tabContentContext, g, tabPlacement, selectedIndex);
|
||||
}
|
||||
|
||||
protected void paintTabArea(Graphics g, int tabPlacement,
|
||||
int selectedIndex) {
|
||||
// This can be invoked from ScrollabeTabPanel
|
||||
Insets insets = tabPane.getInsets();
|
||||
int x = insets.left;
|
||||
int y = insets.top;
|
||||
int width = tabPane.getWidth() - insets.left - insets.right;
|
||||
int height = tabPane.getHeight() - insets.top - insets.bottom;
|
||||
|
||||
paintTabArea(tabAreaContext, g, tabPlacement, selectedIndex,
|
||||
new Rectangle(x, y, width, height));
|
||||
}
|
||||
|
||||
private void paintTabArea(SynthContext ss, Graphics g,
|
||||
int tabPlacement, int selectedIndex,
|
||||
Rectangle tabAreaBounds) {
|
||||
Rectangle clipRect = g.getClipBounds();
|
||||
|
||||
//if the tab area's states should match that of the selected tab, then
|
||||
//first update the selected tab's states, then set the state
|
||||
//for the tab area to match
|
||||
//otherwise, restore the tab area's state to ENABLED (which is the
|
||||
//only supported state otherwise).
|
||||
if (tabAreaStatesMatchSelectedTab && selectedIndex >= 0) {
|
||||
updateTabContext(selectedIndex, true, selectedTabIsPressed,
|
||||
(getRolloverTab() == selectedIndex),
|
||||
(getFocusIndex() == selectedIndex));
|
||||
ss.setComponentState(tabContext.getComponentState());
|
||||
} else {
|
||||
ss.setComponentState(SynthConstants.ENABLED);
|
||||
}
|
||||
|
||||
// Paint the tab area.
|
||||
SynthLookAndFeel.updateSubregion(ss, g, tabAreaBounds);
|
||||
ss.getPainter().paintTabbedPaneTabAreaBackground(ss, g,
|
||||
tabAreaBounds.x, tabAreaBounds.y, tabAreaBounds.width,
|
||||
tabAreaBounds.height, tabPlacement);
|
||||
ss.getPainter().paintTabbedPaneTabAreaBorder(ss, g, tabAreaBounds.x,
|
||||
tabAreaBounds.y, tabAreaBounds.width, tabAreaBounds.height,
|
||||
tabPlacement);
|
||||
|
||||
int tabCount = tabPane.getTabCount();
|
||||
|
||||
iconRect.setBounds(0, 0, 0, 0);
|
||||
textRect.setBounds(0, 0, 0, 0);
|
||||
|
||||
// Paint tabRuns of tabs from back to front
|
||||
for (int i = runCount - 1; i >= 0; i--) {
|
||||
int start = tabRuns[i];
|
||||
int next = tabRuns[(i == runCount - 1)? 0 : i + 1];
|
||||
int end = (next != 0? next - 1: tabCount - 1);
|
||||
for (int j = start; j <= end; j++) {
|
||||
if (rects[j].intersects(clipRect) && selectedIndex != j) {
|
||||
paintTab(tabContext, g, tabPlacement, rects, j, iconRect,
|
||||
textRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedIndex >= 0) {
|
||||
if (rects[selectedIndex].intersects(clipRect)) {
|
||||
paintTab(tabContext, g, tabPlacement, rects, selectedIndex,
|
||||
iconRect, textRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void setRolloverTab(int index) {
|
||||
int oldRolloverTab = getRolloverTab();
|
||||
super.setRolloverTab(index);
|
||||
|
||||
Rectangle r = null;
|
||||
|
||||
if (oldRolloverTab != index && tabAreaStatesMatchSelectedTab) {
|
||||
//TODO need to just repaint the tab area!
|
||||
tabPane.repaint();
|
||||
} else {
|
||||
if ((oldRolloverTab >= 0) && (oldRolloverTab < tabPane.getTabCount())) {
|
||||
r = getTabBounds(tabPane, oldRolloverTab);
|
||||
if (r != null) {
|
||||
tabPane.repaint(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
r = getTabBounds(tabPane, index);
|
||||
if (r != null) {
|
||||
tabPane.repaint(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void paintTab(SynthContext ss, Graphics g,
|
||||
int tabPlacement, Rectangle[] rects, int tabIndex,
|
||||
Rectangle iconRect, Rectangle textRect) {
|
||||
Rectangle tabRect = rects[tabIndex];
|
||||
int selectedIndex = tabPane.getSelectedIndex();
|
||||
boolean isSelected = selectedIndex == tabIndex;
|
||||
updateTabContext(tabIndex, isSelected, isSelected && selectedTabIsPressed,
|
||||
(getRolloverTab() == tabIndex),
|
||||
(getFocusIndex() == tabIndex));
|
||||
|
||||
SynthLookAndFeel.updateSubregion(ss, g, tabRect);
|
||||
int x = tabRect.x;
|
||||
int y = tabRect.y;
|
||||
int height = tabRect.height;
|
||||
int width = tabRect.width;
|
||||
int placement = tabPane.getTabPlacement();
|
||||
if (extendTabsToBase && runCount > 1) {
|
||||
//paint this tab such that its edge closest to the base is equal to
|
||||
//edge of the selected tab closest to the base. In terms of the TOP
|
||||
//tab placement, this will cause the bottom of each tab to be
|
||||
//painted even with the bottom of the selected tab. This is because
|
||||
//in each tab placement (TOP, LEFT, BOTTOM, RIGHT) the selected tab
|
||||
//is closest to the base.
|
||||
if (selectedIndex >= 0) {
|
||||
Rectangle r = rects[selectedIndex];
|
||||
switch (placement) {
|
||||
case TOP:
|
||||
int bottomY = r.y + r.height;
|
||||
height = bottomY - tabRect.y;
|
||||
break;
|
||||
case LEFT:
|
||||
int rightX = r.x + r.width;
|
||||
width = rightX - tabRect.x;
|
||||
break;
|
||||
case BOTTOM:
|
||||
int topY = r.y;
|
||||
height = (tabRect.y + tabRect.height) - topY;
|
||||
y = topY;
|
||||
break;
|
||||
case RIGHT:
|
||||
int leftX = r.x;
|
||||
width = (tabRect.x + tabRect.width) - leftX;
|
||||
x = leftX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tabContext.getPainter().paintTabbedPaneTabBackground(tabContext, g,
|
||||
x, y, width, height, tabIndex, placement);
|
||||
tabContext.getPainter().paintTabbedPaneTabBorder(tabContext, g,
|
||||
x, y, width, height, tabIndex, placement);
|
||||
|
||||
if (tabPane.getTabComponentAt(tabIndex) == null) {
|
||||
String title = tabPane.getTitleAt(tabIndex);
|
||||
Font font = ss.getStyle().getFont(ss);
|
||||
FontMetrics metrics = SwingUtilities2.getFontMetrics(tabPane, g, font);
|
||||
Icon icon = getIconForTab(tabIndex);
|
||||
|
||||
layoutLabel(ss, tabPlacement, metrics, tabIndex, title, icon,
|
||||
tabRect, iconRect, textRect, isSelected);
|
||||
|
||||
paintText(ss, g, tabPlacement, font, metrics,
|
||||
tabIndex, title, textRect, isSelected);
|
||||
|
||||
paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
private void layoutLabel(SynthContext ss, int tabPlacement,
|
||||
FontMetrics metrics, int tabIndex,
|
||||
String title, Icon icon,
|
||||
Rectangle tabRect, Rectangle iconRect,
|
||||
Rectangle textRect, boolean isSelected ) {
|
||||
View v = getTextViewForTab(tabIndex);
|
||||
if (v != null) {
|
||||
tabPane.putClientProperty("html", v);
|
||||
}
|
||||
|
||||
textRect.x = textRect.y = iconRect.x = iconRect.y = 0;
|
||||
|
||||
ss.getStyle().getGraphicsUtils(ss).layoutText(ss, metrics, title,
|
||||
icon, SwingUtilities.CENTER, SwingUtilities.CENTER,
|
||||
SwingUtilities.LEADING, SwingUtilities.CENTER,
|
||||
tabRect, iconRect, textRect, textIconGap);
|
||||
|
||||
tabPane.putClientProperty("html", null);
|
||||
|
||||
int xNudge = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
|
||||
int yNudge = getTabLabelShiftY(tabPlacement, tabIndex, isSelected);
|
||||
iconRect.x += xNudge;
|
||||
iconRect.y += yNudge;
|
||||
textRect.x += xNudge;
|
||||
textRect.y += yNudge;
|
||||
}
|
||||
|
||||
private void paintText(SynthContext ss,
|
||||
Graphics g, int tabPlacement,
|
||||
Font font, FontMetrics metrics, int tabIndex,
|
||||
String title, Rectangle textRect,
|
||||
boolean isSelected) {
|
||||
g.setFont(font);
|
||||
|
||||
View v = getTextViewForTab(tabIndex);
|
||||
if (v != null) {
|
||||
// html
|
||||
v.paint(g, textRect);
|
||||
} else {
|
||||
// plain text
|
||||
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
|
||||
|
||||
g.setColor(ss.getStyle().getColor(ss, ColorType.TEXT_FOREGROUND));
|
||||
ss.getStyle().getGraphicsUtils(ss).paintText(ss, g, title,
|
||||
textRect, mnemIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void paintContentBorder(SynthContext ss, Graphics g,
|
||||
int tabPlacement, int selectedIndex) {
|
||||
int width = tabPane.getWidth();
|
||||
int height = tabPane.getHeight();
|
||||
Insets insets = tabPane.getInsets();
|
||||
|
||||
int x = insets.left;
|
||||
int y = insets.top;
|
||||
int w = width - insets.right - insets.left;
|
||||
int h = height - insets.top - insets.bottom;
|
||||
|
||||
switch(tabPlacement) {
|
||||
case LEFT:
|
||||
x += calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
|
||||
w -= (x - insets.left);
|
||||
break;
|
||||
case RIGHT:
|
||||
w -= calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
|
||||
break;
|
||||
case BOTTOM:
|
||||
h -= calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
|
||||
break;
|
||||
case TOP:
|
||||
default:
|
||||
y += calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
|
||||
h -= (y - insets.top);
|
||||
}
|
||||
SynthLookAndFeel.updateSubregion(ss, g, new Rectangle(x, y, w, h));
|
||||
ss.getPainter().paintTabbedPaneContentBackground(ss, g, x, y,
|
||||
w, h);
|
||||
ss.getPainter().paintTabbedPaneContentBorder(ss, g, x, y, w, h);
|
||||
}
|
||||
|
||||
private void ensureCurrentLayout() {
|
||||
if (!tabPane.isValid()) {
|
||||
tabPane.validate();
|
||||
}
|
||||
/* If tabPane doesn't have a peer yet, the validate() call will
|
||||
* silently fail. We handle that by forcing a layout if tabPane
|
||||
* is still invalid. See bug 4237677.
|
||||
*/
|
||||
if (!tabPane.isValid()) {
|
||||
TabbedPaneLayout layout = (TabbedPaneLayout)tabPane.getLayout();
|
||||
layout.calculateLayoutInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected int calculateMaxTabHeight(int tabPlacement) {
|
||||
FontMetrics metrics = getFontMetrics(tabContext.getStyle().getFont(
|
||||
tabContext));
|
||||
int tabCount = tabPane.getTabCount();
|
||||
int result = 0;
|
||||
int fontHeight = metrics.getHeight();
|
||||
for(int i = 0; i < tabCount; i++) {
|
||||
result = Math.max(calculateTabHeight(tabPlacement, i, fontHeight), result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected int calculateTabWidth(int tabPlacement, int tabIndex,
|
||||
FontMetrics metrics) {
|
||||
Icon icon = getIconForTab(tabIndex);
|
||||
Insets tabInsets = getTabInsets(tabPlacement, tabIndex);
|
||||
int width = tabInsets.left + tabInsets.right;
|
||||
Component tabComponent = tabPane.getTabComponentAt(tabIndex);
|
||||
if (tabComponent != null) {
|
||||
width += tabComponent.getPreferredSize().width;
|
||||
} else {
|
||||
if (icon != null) {
|
||||
width += icon.getIconWidth() + textIconGap;
|
||||
}
|
||||
View v = getTextViewForTab(tabIndex);
|
||||
if (v != null) {
|
||||
// html
|
||||
width += (int) v.getPreferredSpan(View.X_AXIS);
|
||||
} else {
|
||||
// plain text
|
||||
String title = tabPane.getTitleAt(tabIndex);
|
||||
width += tabContext.getStyle().getGraphicsUtils(tabContext).
|
||||
computeStringWidth(tabContext, metrics.getFont(),
|
||||
metrics, title);
|
||||
}
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected int calculateMaxTabWidth(int tabPlacement) {
|
||||
FontMetrics metrics = getFontMetrics(tabContext.getStyle().getFont(
|
||||
tabContext));
|
||||
int tabCount = tabPane.getTabCount();
|
||||
int result = 0;
|
||||
for(int i = 0; i < tabCount; i++) {
|
||||
result = Math.max(calculateTabWidth(tabPlacement, i, metrics),
|
||||
result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Insets getTabInsets(int tabPlacement, int tabIndex) {
|
||||
updateTabContext(tabIndex, false, false, false,
|
||||
(getFocusIndex() == tabIndex));
|
||||
return tabInsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected FontMetrics getFontMetrics() {
|
||||
return getFontMetrics(tabContext.getStyle().getFont(tabContext));
|
||||
}
|
||||
|
||||
private FontMetrics getFontMetrics(Font font) {
|
||||
return tabPane.getFontMetrics(font);
|
||||
}
|
||||
|
||||
private void updateTabContext(int index, boolean selected,
|
||||
boolean isMouseDown, boolean isMouseOver, boolean hasFocus) {
|
||||
int state = 0;
|
||||
if (!tabPane.isEnabled() || !tabPane.isEnabledAt(index)) {
|
||||
state |= SynthConstants.DISABLED;
|
||||
if (selected) {
|
||||
state |= SynthConstants.SELECTED;
|
||||
}
|
||||
}
|
||||
else if (selected) {
|
||||
state |= (SynthConstants.ENABLED | SynthConstants.SELECTED);
|
||||
if (isMouseOver && UIManager.getBoolean("TabbedPane.isTabRollover")) {
|
||||
state |= SynthConstants.MOUSE_OVER;
|
||||
}
|
||||
}
|
||||
else if (isMouseOver) {
|
||||
state |= (SynthConstants.ENABLED | SynthConstants.MOUSE_OVER);
|
||||
}
|
||||
else {
|
||||
state = SynthLookAndFeel.getComponentState(tabPane);
|
||||
state &= ~SynthConstants.FOCUSED; // don't use tabbedpane focus state
|
||||
}
|
||||
if (hasFocus && tabPane.hasFocus()) {
|
||||
state |= SynthConstants.FOCUSED; // individual tab has focus
|
||||
}
|
||||
if (isMouseDown) {
|
||||
state |= SynthConstants.PRESSED;
|
||||
}
|
||||
|
||||
tabContext.setComponentState(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Overridden to create a TabbedPaneLayout subclass which takes into
|
||||
* account tabOverlap.
|
||||
*/
|
||||
@Override
|
||||
protected LayoutManager createLayoutManager() {
|
||||
if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
|
||||
return super.createLayoutManager();
|
||||
} else { /* WRAP_TAB_LAYOUT */
|
||||
return new TabbedPaneLayout() {
|
||||
@Override
|
||||
public void calculateLayoutInfo() {
|
||||
super.calculateLayoutInfo();
|
||||
//shift all the tabs, if necessary
|
||||
if (tabOverlap != 0) {
|
||||
int tabCount = tabPane.getTabCount();
|
||||
//left-to-right/right-to-left only affects layout
|
||||
//when placement is TOP or BOTTOM
|
||||
boolean ltr = tabPane.getComponentOrientation().isLeftToRight();
|
||||
for (int i = runCount - 1; i >= 0; i--) {
|
||||
int start = tabRuns[i];
|
||||
int next = tabRuns[(i == runCount - 1)? 0 : i + 1];
|
||||
int end = (next != 0? next - 1: tabCount - 1);
|
||||
for (int j = start+1; j <= end; j++) {
|
||||
// xshift and yshift represent the amount &
|
||||
// direction to shift the tab in their
|
||||
// respective axis.
|
||||
int xshift = 0;
|
||||
int yshift = 0;
|
||||
// configure xshift and y shift based on tab
|
||||
// position and ltr/rtl
|
||||
switch (tabPane.getTabPlacement()) {
|
||||
case JTabbedPane.TOP:
|
||||
case JTabbedPane.BOTTOM:
|
||||
xshift = ltr ? tabOverlap : -tabOverlap;
|
||||
break;
|
||||
case JTabbedPane.LEFT:
|
||||
case JTabbedPane.RIGHT:
|
||||
yshift = tabOverlap;
|
||||
break;
|
||||
default: //do nothing
|
||||
}
|
||||
rects[j].x += xshift;
|
||||
rects[j].y += yshift;
|
||||
rects[j].width += Math.abs(xshift);
|
||||
rects[j].height += Math.abs(yshift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class SynthScrollableTabButton extends SynthArrowButton implements
|
||||
UIResource {
|
||||
public SynthScrollableTabButton(int direction) {
|
||||
super(direction);
|
||||
setName("TabbedPane.button");
|
||||
}
|
||||
}
|
||||
}
|
||||
276
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTableHeaderUI.java
Normal file
276
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTableHeaderUI.java
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import javax.swing.table.*;
|
||||
import sun.swing.table.*;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.table.JTableHeader}.
|
||||
*
|
||||
* @author Alan Chung
|
||||
* @author Philip Milne
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthTableHeaderUI extends BasicTableHeaderUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
|
||||
//
|
||||
// Instance Variables
|
||||
//
|
||||
|
||||
private TableCellRenderer prevRenderer = null;
|
||||
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param h component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent h) {
|
||||
return new SynthTableHeaderUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
prevRenderer = header.getDefaultRenderer();
|
||||
if (prevRenderer instanceof UIResource) {
|
||||
header.setDefaultRenderer(new HeaderRenderer());
|
||||
}
|
||||
updateStyle(header);
|
||||
}
|
||||
|
||||
private void updateStyle(JTableHeader c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
header.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
if (header.getDefaultRenderer() instanceof HeaderRenderer) {
|
||||
header.setDefaultRenderer(prevRenderer);
|
||||
}
|
||||
|
||||
SynthContext context = getContext(header, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
header.removePropertyChangeListener(this);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintTableHeaderBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
super.paint(g, context.getComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintTableHeaderBorder(context, g, x, y, w, h);
|
||||
}
|
||||
//
|
||||
// SynthUI
|
||||
//
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void rolloverColumnUpdated(int oldColumn, int newColumn) {
|
||||
header.repaint(header.getHeaderRect(oldColumn));
|
||||
header.repaint(header.getHeaderRect(newColumn));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle((JTableHeader)evt.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
private class HeaderRenderer extends DefaultTableCellHeaderRenderer {
|
||||
HeaderRenderer() {
|
||||
setHorizontalAlignment(JLabel.LEADING);
|
||||
setName("TableHeader.renderer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value,
|
||||
boolean isSelected,
|
||||
boolean hasFocus,
|
||||
int row, int column) {
|
||||
|
||||
boolean hasRollover = (column == getRolloverColumn());
|
||||
if (isSelected || hasRollover || hasFocus) {
|
||||
SynthLookAndFeel.setSelectedUI((SynthLabelUI)SynthLookAndFeel.
|
||||
getUIOfType(getUI(), SynthLabelUI.class),
|
||||
isSelected, hasFocus, table.isEnabled(),
|
||||
hasRollover);
|
||||
} else {
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
|
||||
//stuff a variable into the client property of this renderer indicating the sort order,
|
||||
//so that different rendering can be done for the header based on sorted state.
|
||||
RowSorter rs = table == null ? null : table.getRowSorter();
|
||||
java.util.List<? extends RowSorter.SortKey> sortKeys = rs == null ? null : rs.getSortKeys();
|
||||
if (sortKeys != null && sortKeys.size() > 0 && sortKeys.get(0).getColumn() ==
|
||||
table.convertColumnIndexToModel(column)) {
|
||||
switch(sortKeys.get(0).getSortOrder()) {
|
||||
case ASCENDING:
|
||||
putClientProperty("Table.sortOrder", "ASCENDING");
|
||||
break;
|
||||
case DESCENDING:
|
||||
putClientProperty("Table.sortOrder", "DESCENDING");
|
||||
break;
|
||||
case UNSORTED:
|
||||
putClientProperty("Table.sortOrder", "UNSORTED");
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Cannot happen");
|
||||
}
|
||||
} else {
|
||||
putClientProperty("Table.sortOrder", "UNSORTED");
|
||||
}
|
||||
|
||||
super.getTableCellRendererComponent(table, value, isSelected,
|
||||
hasFocus, row, column);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBorder(Border border) {
|
||||
if (border instanceof SynthBorder) {
|
||||
super.setBorder(border);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
830
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTableUI.java
Normal file
830
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTableUI.java
Normal file
@@ -0,0 +1,830 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.text.DateFormat;
|
||||
import java.text.Format;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Date;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicTableUI;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JTable}.
|
||||
*
|
||||
* @author Philip Milne
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthTableUI extends BasicTableUI
|
||||
implements SynthUI, PropertyChangeListener {
|
||||
//
|
||||
// Instance Variables
|
||||
//
|
||||
|
||||
private SynthStyle style;
|
||||
|
||||
private boolean useTableColors;
|
||||
private boolean useUIBorder;
|
||||
private Color alternateColor; //the background color to use for cells for alternate cells
|
||||
|
||||
// TableCellRenderer installed on the JTable at the time we're installed,
|
||||
// cached so that we can reinstall them at uninstallUI time.
|
||||
private TableCellRenderer dateRenderer;
|
||||
private TableCellRenderer numberRenderer;
|
||||
private TableCellRenderer doubleRender;
|
||||
private TableCellRenderer floatRenderer;
|
||||
private TableCellRenderer iconRenderer;
|
||||
private TableCellRenderer imageIconRenderer;
|
||||
private TableCellRenderer booleanRenderer;
|
||||
private TableCellRenderer objectRenderer;
|
||||
|
||||
//
|
||||
// The installation/uninstall procedures and support
|
||||
//
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthTableUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes JTable properties, such as font, foreground, and background.
|
||||
* The font, foreground, and background properties are only set if their
|
||||
* current value is either null or a UIResource, other properties are set
|
||||
* if the current value is null.
|
||||
*
|
||||
* @see #installUI
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
dateRenderer = installRendererIfPossible(Date.class, null);
|
||||
numberRenderer = installRendererIfPossible(Number.class, null);
|
||||
doubleRender = installRendererIfPossible(Double.class, null);
|
||||
floatRenderer = installRendererIfPossible(Float.class, null);
|
||||
iconRenderer = installRendererIfPossible(Icon.class, null);
|
||||
imageIconRenderer = installRendererIfPossible(ImageIcon.class, null);
|
||||
booleanRenderer = installRendererIfPossible(Boolean.class,
|
||||
new SynthBooleanTableCellRenderer());
|
||||
objectRenderer = installRendererIfPossible(Object.class,
|
||||
new SynthTableCellRenderer());
|
||||
updateStyle(table);
|
||||
}
|
||||
|
||||
private TableCellRenderer installRendererIfPossible(Class objectClass,
|
||||
TableCellRenderer renderer) {
|
||||
TableCellRenderer currentRenderer = table.getDefaultRenderer(
|
||||
objectClass);
|
||||
if (currentRenderer instanceof UIResource) {
|
||||
table.setDefaultRenderer(objectClass, renderer);
|
||||
}
|
||||
return currentRenderer;
|
||||
}
|
||||
|
||||
private void updateStyle(JTable c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
context.setComponentState(ENABLED | SELECTED);
|
||||
|
||||
Color sbg = table.getSelectionBackground();
|
||||
if (sbg == null || sbg instanceof UIResource) {
|
||||
table.setSelectionBackground(style.getColor(
|
||||
context, ColorType.TEXT_BACKGROUND));
|
||||
}
|
||||
|
||||
Color sfg = table.getSelectionForeground();
|
||||
if (sfg == null || sfg instanceof UIResource) {
|
||||
table.setSelectionForeground(style.getColor(
|
||||
context, ColorType.TEXT_FOREGROUND));
|
||||
}
|
||||
|
||||
context.setComponentState(ENABLED);
|
||||
|
||||
Color gridColor = table.getGridColor();
|
||||
if (gridColor == null || gridColor instanceof UIResource) {
|
||||
gridColor = (Color)style.get(context, "Table.gridColor");
|
||||
if (gridColor == null) {
|
||||
gridColor = style.getColor(context, ColorType.FOREGROUND);
|
||||
}
|
||||
table.setGridColor(gridColor == null ? new ColorUIResource(Color.GRAY) : gridColor);
|
||||
}
|
||||
|
||||
useTableColors = style.getBoolean(context,
|
||||
"Table.rendererUseTableColors", true);
|
||||
useUIBorder = style.getBoolean(context,
|
||||
"Table.rendererUseUIBorder", true);
|
||||
|
||||
Object rowHeight = style.get(context, "Table.rowHeight");
|
||||
if (rowHeight != null) {
|
||||
LookAndFeel.installProperty(table, "rowHeight", rowHeight);
|
||||
}
|
||||
boolean showGrid = style.getBoolean(context, "Table.showGrid", true);
|
||||
if (!showGrid) {
|
||||
table.setShowGrid(false);
|
||||
}
|
||||
Dimension d = table.getIntercellSpacing();
|
||||
// if (d == null || d instanceof UIResource) {
|
||||
if (d != null) {
|
||||
d = (Dimension)style.get(context, "Table.intercellSpacing");
|
||||
}
|
||||
alternateColor = (Color)style.get(context, "Table.alternateRowColor");
|
||||
if (d != null) {
|
||||
table.setIntercellSpacing(d);
|
||||
}
|
||||
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches listeners to the JTable.
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
table.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
table.setDefaultRenderer(Date.class, dateRenderer);
|
||||
table.setDefaultRenderer(Number.class, numberRenderer);
|
||||
table.setDefaultRenderer(Double.class, doubleRender);
|
||||
table.setDefaultRenderer(Float.class, floatRenderer);
|
||||
table.setDefaultRenderer(Icon.class, iconRenderer);
|
||||
table.setDefaultRenderer(ImageIcon.class, imageIconRenderer);
|
||||
table.setDefaultRenderer(Boolean.class, booleanRenderer);
|
||||
table.setDefaultRenderer(Object.class, objectRenderer);
|
||||
|
||||
if (table.getTransferHandler() instanceof UIResource) {
|
||||
table.setTransferHandler(null);
|
||||
}
|
||||
SynthContext context = getContext(table, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
table.removePropertyChangeListener(this);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
//
|
||||
// SynthUI
|
||||
//
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
//
|
||||
// Paint methods and support
|
||||
//
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintTableBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintTableBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
Rectangle clip = g.getClipBounds();
|
||||
|
||||
Rectangle bounds = table.getBounds();
|
||||
// account for the fact that the graphics has already been translated
|
||||
// into the table's bounds
|
||||
bounds.x = bounds.y = 0;
|
||||
|
||||
if (table.getRowCount() <= 0 || table.getColumnCount() <= 0 ||
|
||||
// this check prevents us from painting the entire table
|
||||
// when the clip doesn't intersect our bounds at all
|
||||
!bounds.intersects(clip)) {
|
||||
|
||||
paintDropLines(context, g);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean ltr = table.getComponentOrientation().isLeftToRight();
|
||||
|
||||
Point upperLeft = clip.getLocation();
|
||||
|
||||
Point lowerRight = new Point(clip.x + clip.width - 1,
|
||||
clip.y + clip.height - 1);
|
||||
|
||||
int rMin = table.rowAtPoint(upperLeft);
|
||||
int rMax = table.rowAtPoint(lowerRight);
|
||||
// This should never happen (as long as our bounds intersect the clip,
|
||||
// which is why we bail above if that is the case).
|
||||
if (rMin == -1) {
|
||||
rMin = 0;
|
||||
}
|
||||
// If the table does not have enough rows to fill the view we'll get -1.
|
||||
// (We could also get -1 if our bounds don't intersect the clip,
|
||||
// which is why we bail above if that is the case).
|
||||
// Replace this with the index of the last row.
|
||||
if (rMax == -1) {
|
||||
rMax = table.getRowCount()-1;
|
||||
}
|
||||
|
||||
int cMin = table.columnAtPoint(ltr ? upperLeft : lowerRight);
|
||||
int cMax = table.columnAtPoint(ltr ? lowerRight : upperLeft);
|
||||
// This should never happen.
|
||||
if (cMin == -1) {
|
||||
cMin = 0;
|
||||
}
|
||||
// If the table does not have enough columns to fill the view we'll get -1.
|
||||
// Replace this with the index of the last column.
|
||||
if (cMax == -1) {
|
||||
cMax = table.getColumnCount()-1;
|
||||
}
|
||||
|
||||
// Paint the cells.
|
||||
paintCells(context, g, rMin, rMax, cMin, cMax);
|
||||
|
||||
// Paint the grid.
|
||||
// it is important to paint the grid after the cells, otherwise the grid will be overpainted
|
||||
// because in Synth cell renderers are likely to be opaque
|
||||
paintGrid(context, g, rMin, rMax, cMin, cMax);
|
||||
|
||||
paintDropLines(context, g);
|
||||
}
|
||||
|
||||
private void paintDropLines(SynthContext context, Graphics g) {
|
||||
JTable.DropLocation loc = table.getDropLocation();
|
||||
if (loc == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = (Color)style.get(context, "Table.dropLineColor");
|
||||
Color shortColor = (Color)style.get(context, "Table.dropLineShortColor");
|
||||
if (color == null && shortColor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Rectangle rect;
|
||||
|
||||
rect = getHDropLineRect(loc);
|
||||
if (rect != null) {
|
||||
int x = rect.x;
|
||||
int w = rect.width;
|
||||
if (color != null) {
|
||||
extendRect(rect, true);
|
||||
g.setColor(color);
|
||||
g.fillRect(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
if (!loc.isInsertColumn() && shortColor != null) {
|
||||
g.setColor(shortColor);
|
||||
g.fillRect(x, rect.y, w, rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
rect = getVDropLineRect(loc);
|
||||
if (rect != null) {
|
||||
int y = rect.y;
|
||||
int h = rect.height;
|
||||
if (color != null) {
|
||||
extendRect(rect, false);
|
||||
g.setColor(color);
|
||||
g.fillRect(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
if (!loc.isInsertRow() && shortColor != null) {
|
||||
g.setColor(shortColor);
|
||||
g.fillRect(rect.x, y, rect.width, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle getHDropLineRect(JTable.DropLocation loc) {
|
||||
if (!loc.isInsertRow()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int row = loc.getRow();
|
||||
int col = loc.getColumn();
|
||||
if (col >= table.getColumnCount()) {
|
||||
col--;
|
||||
}
|
||||
|
||||
Rectangle rect = table.getCellRect(row, col, true);
|
||||
|
||||
if (row >= table.getRowCount()) {
|
||||
row--;
|
||||
Rectangle prevRect = table.getCellRect(row, col, true);
|
||||
rect.y = prevRect.y + prevRect.height;
|
||||
}
|
||||
|
||||
if (rect.y == 0) {
|
||||
rect.y = -1;
|
||||
} else {
|
||||
rect.y -= 2;
|
||||
}
|
||||
|
||||
rect.height = 3;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
private Rectangle getVDropLineRect(JTable.DropLocation loc) {
|
||||
if (!loc.isInsertColumn()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean ltr = table.getComponentOrientation().isLeftToRight();
|
||||
int col = loc.getColumn();
|
||||
Rectangle rect = table.getCellRect(loc.getRow(), col, true);
|
||||
|
||||
if (col >= table.getColumnCount()) {
|
||||
col--;
|
||||
rect = table.getCellRect(loc.getRow(), col, true);
|
||||
if (ltr) {
|
||||
rect.x = rect.x + rect.width;
|
||||
}
|
||||
} else if (!ltr) {
|
||||
rect.x = rect.x + rect.width;
|
||||
}
|
||||
|
||||
if (rect.x == 0) {
|
||||
rect.x = -1;
|
||||
} else {
|
||||
rect.x -= 2;
|
||||
}
|
||||
|
||||
rect.width = 3;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
private Rectangle extendRect(Rectangle rect, boolean horizontal) {
|
||||
if (rect == null) {
|
||||
return rect;
|
||||
}
|
||||
|
||||
if (horizontal) {
|
||||
rect.x = 0;
|
||||
rect.width = table.getWidth();
|
||||
} else {
|
||||
rect.y = 0;
|
||||
|
||||
if (table.getRowCount() != 0) {
|
||||
Rectangle lastRect = table.getCellRect(table.getRowCount() - 1, 0, true);
|
||||
rect.height = lastRect.y + lastRect.height;
|
||||
} else {
|
||||
rect.height = table.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
/*
|
||||
* Paints the grid lines within <I>aRect</I>, using the grid
|
||||
* color set with <I>setGridColor</I>. Paints vertical lines
|
||||
* if <code>getShowVerticalLines()</code> returns true and paints
|
||||
* horizontal lines if <code>getShowHorizontalLines()</code>
|
||||
* returns true.
|
||||
*/
|
||||
private void paintGrid(SynthContext context, Graphics g, int rMin,
|
||||
int rMax, int cMin, int cMax) {
|
||||
g.setColor(table.getGridColor());
|
||||
|
||||
Rectangle minCell = table.getCellRect(rMin, cMin, true);
|
||||
Rectangle maxCell = table.getCellRect(rMax, cMax, true);
|
||||
Rectangle damagedArea = minCell.union( maxCell );
|
||||
SynthGraphicsUtils synthG = context.getStyle().getGraphicsUtils(
|
||||
context);
|
||||
|
||||
if (table.getShowHorizontalLines()) {
|
||||
int tableWidth = damagedArea.x + damagedArea.width;
|
||||
int y = damagedArea.y;
|
||||
for (int row = rMin; row <= rMax; row++) {
|
||||
y += table.getRowHeight(row);
|
||||
synthG.drawLine(context, "Table.grid",
|
||||
g, damagedArea.x, y - 1, tableWidth - 1,y - 1);
|
||||
}
|
||||
}
|
||||
if (table.getShowVerticalLines()) {
|
||||
TableColumnModel cm = table.getColumnModel();
|
||||
int tableHeight = damagedArea.y + damagedArea.height;
|
||||
int x;
|
||||
if (table.getComponentOrientation().isLeftToRight()) {
|
||||
x = damagedArea.x;
|
||||
for (int column = cMin; column <= cMax; column++) {
|
||||
int w = cm.getColumn(column).getWidth();
|
||||
x += w;
|
||||
synthG.drawLine(context, "Table.grid", g, x - 1, 0,
|
||||
x - 1, tableHeight - 1);
|
||||
}
|
||||
} else {
|
||||
x = damagedArea.x;
|
||||
for (int column = cMax; column >= cMin; column--) {
|
||||
int w = cm.getColumn(column).getWidth();
|
||||
x += w;
|
||||
synthG.drawLine(context, "Table.grid", g, x - 1, 0, x - 1,
|
||||
tableHeight - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int viewIndexForColumn(TableColumn aColumn) {
|
||||
TableColumnModel cm = table.getColumnModel();
|
||||
for (int column = 0; column < cm.getColumnCount(); column++) {
|
||||
if (cm.getColumn(column) == aColumn) {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void paintCells(SynthContext context, Graphics g, int rMin,
|
||||
int rMax, int cMin, int cMax) {
|
||||
JTableHeader header = table.getTableHeader();
|
||||
TableColumn draggedColumn = (header == null) ? null : header.getDraggedColumn();
|
||||
|
||||
TableColumnModel cm = table.getColumnModel();
|
||||
int columnMargin = cm.getColumnMargin();
|
||||
|
||||
Rectangle cellRect;
|
||||
TableColumn aColumn;
|
||||
int columnWidth;
|
||||
if (table.getComponentOrientation().isLeftToRight()) {
|
||||
for(int row = rMin; row <= rMax; row++) {
|
||||
cellRect = table.getCellRect(row, cMin, false);
|
||||
for(int column = cMin; column <= cMax; column++) {
|
||||
aColumn = cm.getColumn(column);
|
||||
columnWidth = aColumn.getWidth();
|
||||
cellRect.width = columnWidth - columnMargin;
|
||||
if (aColumn != draggedColumn) {
|
||||
paintCell(context, g, cellRect, row, column);
|
||||
}
|
||||
cellRect.x += columnWidth;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int row = rMin; row <= rMax; row++) {
|
||||
cellRect = table.getCellRect(row, cMin, false);
|
||||
aColumn = cm.getColumn(cMin);
|
||||
if (aColumn != draggedColumn) {
|
||||
columnWidth = aColumn.getWidth();
|
||||
cellRect.width = columnWidth - columnMargin;
|
||||
paintCell(context, g, cellRect, row, cMin);
|
||||
}
|
||||
for(int column = cMin+1; column <= cMax; column++) {
|
||||
aColumn = cm.getColumn(column);
|
||||
columnWidth = aColumn.getWidth();
|
||||
cellRect.width = columnWidth - columnMargin;
|
||||
cellRect.x -= columnWidth;
|
||||
if (aColumn != draggedColumn) {
|
||||
paintCell(context, g, cellRect, row, column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Paint the dragged column if we are dragging.
|
||||
if (draggedColumn != null) {
|
||||
paintDraggedArea(context, g, rMin, rMax, draggedColumn, header.getDraggedDistance());
|
||||
}
|
||||
|
||||
// Remove any renderers that may be left in the rendererPane.
|
||||
rendererPane.removeAll();
|
||||
}
|
||||
|
||||
private void paintDraggedArea(SynthContext context, Graphics g, int rMin, int rMax, TableColumn draggedColumn, int distance) {
|
||||
int draggedColumnIndex = viewIndexForColumn(draggedColumn);
|
||||
|
||||
Rectangle minCell = table.getCellRect(rMin, draggedColumnIndex, true);
|
||||
Rectangle maxCell = table.getCellRect(rMax, draggedColumnIndex, true);
|
||||
|
||||
Rectangle vacatedColumnRect = minCell.union(maxCell);
|
||||
|
||||
// Paint a gray well in place of the moving column.
|
||||
g.setColor(table.getParent().getBackground());
|
||||
g.fillRect(vacatedColumnRect.x, vacatedColumnRect.y,
|
||||
vacatedColumnRect.width, vacatedColumnRect.height);
|
||||
|
||||
// Move to the where the cell has been dragged.
|
||||
vacatedColumnRect.x += distance;
|
||||
|
||||
// Fill the background.
|
||||
g.setColor(context.getStyle().getColor(context, ColorType.BACKGROUND));
|
||||
g.fillRect(vacatedColumnRect.x, vacatedColumnRect.y,
|
||||
vacatedColumnRect.width, vacatedColumnRect.height);
|
||||
|
||||
SynthGraphicsUtils synthG = context.getStyle().getGraphicsUtils(
|
||||
context);
|
||||
|
||||
|
||||
// Paint the vertical grid lines if necessary.
|
||||
if (table.getShowVerticalLines()) {
|
||||
g.setColor(table.getGridColor());
|
||||
int x1 = vacatedColumnRect.x;
|
||||
int y1 = vacatedColumnRect.y;
|
||||
int x2 = x1 + vacatedColumnRect.width - 1;
|
||||
int y2 = y1 + vacatedColumnRect.height - 1;
|
||||
// Left
|
||||
synthG.drawLine(context, "Table.grid", g, x1-1, y1, x1-1, y2);
|
||||
// Right
|
||||
synthG.drawLine(context, "Table.grid", g, x2, y1, x2, y2);
|
||||
}
|
||||
|
||||
for(int row = rMin; row <= rMax; row++) {
|
||||
// Render the cell value
|
||||
Rectangle r = table.getCellRect(row, draggedColumnIndex, false);
|
||||
r.x += distance;
|
||||
paintCell(context, g, r, row, draggedColumnIndex);
|
||||
|
||||
// Paint the (lower) horizontal grid line if necessary.
|
||||
if (table.getShowHorizontalLines()) {
|
||||
g.setColor(table.getGridColor());
|
||||
Rectangle rcr = table.getCellRect(row, draggedColumnIndex, true);
|
||||
rcr.x += distance;
|
||||
int x1 = rcr.x;
|
||||
int y1 = rcr.y;
|
||||
int x2 = x1 + rcr.width - 1;
|
||||
int y2 = y1 + rcr.height - 1;
|
||||
synthG.drawLine(context, "Table.grid", g, x1, y2, x2, y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void paintCell(SynthContext context, Graphics g,
|
||||
Rectangle cellRect, int row, int column) {
|
||||
if (table.isEditing() && table.getEditingRow()==row &&
|
||||
table.getEditingColumn()==column) {
|
||||
Component component = table.getEditorComponent();
|
||||
component.setBounds(cellRect);
|
||||
component.validate();
|
||||
}
|
||||
else {
|
||||
TableCellRenderer renderer = table.getCellRenderer(row, column);
|
||||
Component component = table.prepareRenderer(renderer, row, column);
|
||||
Color b = component.getBackground();
|
||||
if ((b == null || b instanceof UIResource
|
||||
|| component instanceof SynthBooleanTableCellRenderer)
|
||||
&& !table.isCellSelected(row, column)) {
|
||||
if (alternateColor != null && row % 2 != 0) {
|
||||
component.setBackground(alternateColor);
|
||||
}
|
||||
}
|
||||
rendererPane.paintComponent(g, component, table, cellRect.x,
|
||||
cellRect.y, cellRect.width, cellRect.height, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(event)) {
|
||||
updateStyle((JTable)event.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class SynthBooleanTableCellRenderer extends JCheckBox implements
|
||||
TableCellRenderer {
|
||||
private boolean isRowSelected;
|
||||
|
||||
public SynthBooleanTableCellRenderer() {
|
||||
setHorizontalAlignment(JLabel.CENTER);
|
||||
setName("Table.cellRenderer");
|
||||
}
|
||||
|
||||
public Component getTableCellRendererComponent(
|
||||
JTable table, Object value, boolean isSelected,
|
||||
boolean hasFocus, int row, int column) {
|
||||
isRowSelected = isSelected;
|
||||
|
||||
if (isSelected) {
|
||||
setForeground(unwrap(table.getSelectionForeground()));
|
||||
setBackground(unwrap(table.getSelectionBackground()));
|
||||
} else {
|
||||
setForeground(unwrap(table.getForeground()));
|
||||
setBackground(unwrap(table.getBackground()));
|
||||
}
|
||||
|
||||
setSelected((value != null && ((Boolean)value).booleanValue()));
|
||||
return this;
|
||||
}
|
||||
|
||||
private Color unwrap(Color c) {
|
||||
if (c instanceof UIResource) {
|
||||
return new Color(c.getRGB());
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public boolean isOpaque() {
|
||||
return isRowSelected ? true : super.isOpaque();
|
||||
}
|
||||
}
|
||||
|
||||
private class SynthTableCellRenderer extends DefaultTableCellRenderer {
|
||||
private Object numberFormat;
|
||||
private Object dateFormat;
|
||||
private boolean opaque;
|
||||
|
||||
public void setOpaque(boolean isOpaque) {
|
||||
opaque = isOpaque;
|
||||
}
|
||||
|
||||
public boolean isOpaque() {
|
||||
return opaque;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String name = super.getName();
|
||||
if (name == null) {
|
||||
return "Table.cellRenderer";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setBorder(Border b) {
|
||||
if (useUIBorder || b instanceof SynthBorder) {
|
||||
super.setBorder(b);
|
||||
}
|
||||
}
|
||||
|
||||
public Component getTableCellRendererComponent(
|
||||
JTable table, Object value, boolean isSelected,
|
||||
boolean hasFocus, int row, int column) {
|
||||
if (!useTableColors && (isSelected || hasFocus)) {
|
||||
SynthLookAndFeel.setSelectedUI((SynthLabelUI)SynthLookAndFeel.
|
||||
getUIOfType(getUI(), SynthLabelUI.class),
|
||||
isSelected, hasFocus, table.isEnabled(), false);
|
||||
}
|
||||
else {
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
super.getTableCellRendererComponent(table, value, isSelected,
|
||||
hasFocus, row, column);
|
||||
|
||||
setIcon(null);
|
||||
if (table != null) {
|
||||
configureValue(value, table.getColumnClass(column));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void configureValue(Object value, Class columnClass) {
|
||||
if (columnClass == Object.class || columnClass == null) {
|
||||
setHorizontalAlignment(JLabel.LEADING);
|
||||
} else if (columnClass == Float.class || columnClass == Double.class) {
|
||||
if (numberFormat == null) {
|
||||
numberFormat = NumberFormat.getInstance();
|
||||
}
|
||||
setHorizontalAlignment(JLabel.TRAILING);
|
||||
setText((value == null) ? "" : ((NumberFormat)numberFormat).format(value));
|
||||
}
|
||||
else if (columnClass == Number.class) {
|
||||
setHorizontalAlignment(JLabel.TRAILING);
|
||||
// Super will have set value.
|
||||
}
|
||||
else if (columnClass == Icon.class || columnClass == ImageIcon.class) {
|
||||
setHorizontalAlignment(JLabel.CENTER);
|
||||
setIcon((value instanceof Icon) ? (Icon)value : null);
|
||||
setText("");
|
||||
}
|
||||
else if (columnClass == Date.class) {
|
||||
if (dateFormat == null) {
|
||||
dateFormat = DateFormat.getDateInstance();
|
||||
}
|
||||
setHorizontalAlignment(JLabel.LEADING);
|
||||
setText((value == null) ? "" : ((Format)dateFormat).format(value));
|
||||
}
|
||||
else {
|
||||
configureValue(value, columnClass.getSuperclass());
|
||||
}
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
204
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTextAreaUI.java
Normal file
204
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTextAreaUI.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicTextAreaUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Provides the look and feel for a plain text editor in the
|
||||
* Synth look and feel. In this implementation the default UI
|
||||
* is extended to act as a simple view factory.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI {
|
||||
private Handler handler = new Handler();
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a UI object for a JTextArea.
|
||||
*
|
||||
* @param ta a text area
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent ta) {
|
||||
return new SynthTextAreaUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
// Installs the text cursor on the component
|
||||
super.installDefaults();
|
||||
updateStyle(getComponent());
|
||||
getComponent().addFocusListener(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(getComponent(), ENABLED);
|
||||
|
||||
getComponent().putClientProperty("caretAspectRatio", null);
|
||||
getComponent().removeFocusListener(handler);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
private void updateStyle(JTextComponent comp) {
|
||||
SynthContext context = getContext(comp, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
|
||||
if (style != oldStyle) {
|
||||
SynthTextFieldUI.updateStyle(comp, context, getPropertyPrefix());
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintTextAreaBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
super.paint(g, getComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Overridden to do nothing.
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
// Overriden to do nothing, all our painting is done from update/paint.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintTextAreaBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a bound property is changed
|
||||
* on the associated JTextComponent. This is a hook
|
||||
* which UI implementations may change to reflect how the
|
||||
* UI displays bound properties of JTextComponent subclasses.
|
||||
* This is implemented to rebuild the View when the
|
||||
* <em>WrapLine</em> or the <em>WrapStyleWord</em> property changes.
|
||||
*
|
||||
* @param evt the property change event
|
||||
*/
|
||||
@Override
|
||||
protected void propertyChange(PropertyChangeEvent evt) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle((JTextComponent)evt.getSource());
|
||||
}
|
||||
super.propertyChange(evt);
|
||||
}
|
||||
|
||||
private final class Handler implements FocusListener {
|
||||
public void focusGained(FocusEvent e) {
|
||||
getComponent().repaint();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
getComponent().repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
278
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTextFieldUI.java
Normal file
278
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTextFieldUI.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicTextFieldUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for {@link javax.swing.JTextField}.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI {
|
||||
private Handler handler = new Handler();
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a UI for a JTextField.
|
||||
*
|
||||
* @param c the text field
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthTextFieldUI();
|
||||
}
|
||||
|
||||
private void updateStyle(JTextComponent comp) {
|
||||
SynthContext context = getContext(comp, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
|
||||
if (style != oldStyle) {
|
||||
SynthTextFieldUI.updateStyle(comp, context, getPropertyPrefix());
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
static void updateStyle(JTextComponent comp, SynthContext context,
|
||||
String prefix) {
|
||||
SynthStyle style = context.getStyle();
|
||||
|
||||
Color color = comp.getCaretColor();
|
||||
if (color == null || color instanceof UIResource) {
|
||||
comp.setCaretColor(
|
||||
(Color)style.get(context, prefix + ".caretForeground"));
|
||||
}
|
||||
|
||||
Color fg = comp.getForeground();
|
||||
if (fg == null || fg instanceof UIResource) {
|
||||
fg = style.getColorForState(context, ColorType.TEXT_FOREGROUND);
|
||||
if (fg != null) {
|
||||
comp.setForeground(fg);
|
||||
}
|
||||
}
|
||||
|
||||
Object ar = style.get(context, prefix + ".caretAspectRatio");
|
||||
if (ar instanceof Number) {
|
||||
comp.putClientProperty("caretAspectRatio", ar);
|
||||
}
|
||||
|
||||
context.setComponentState(SELECTED | FOCUSED);
|
||||
|
||||
Color s = comp.getSelectionColor();
|
||||
if (s == null || s instanceof UIResource) {
|
||||
comp.setSelectionColor(
|
||||
style.getColor(context, ColorType.TEXT_BACKGROUND));
|
||||
}
|
||||
|
||||
Color sfg = comp.getSelectedTextColor();
|
||||
if (sfg == null || sfg instanceof UIResource) {
|
||||
comp.setSelectedTextColor(
|
||||
style.getColor(context, ColorType.TEXT_FOREGROUND));
|
||||
}
|
||||
|
||||
context.setComponentState(DISABLED);
|
||||
|
||||
Color dfg = comp.getDisabledTextColor();
|
||||
if (dfg == null || dfg instanceof UIResource) {
|
||||
comp.setDisabledTextColor(
|
||||
style.getColor(context, ColorType.TEXT_FOREGROUND));
|
||||
}
|
||||
|
||||
Insets margin = comp.getMargin();
|
||||
if (margin == null || margin instanceof UIResource) {
|
||||
margin = (Insets)style.get(context, prefix + ".margin");
|
||||
|
||||
if (margin == null) {
|
||||
// Some places assume margins are non-null.
|
||||
margin = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
|
||||
}
|
||||
comp.setMargin(margin);
|
||||
}
|
||||
|
||||
Caret caret = comp.getCaret();
|
||||
if (caret instanceof UIResource) {
|
||||
Object o = style.get(context, prefix + ".caretBlinkRate");
|
||||
if (o != null && o instanceof Integer) {
|
||||
Integer rate = (Integer)o;
|
||||
caret.setBlinkRate(rate.intValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
paintBackground(context, g, c);
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
* <p>This is routed to the {@link #paintSafely} method under
|
||||
* the guarantee that the model does not change from the view of this
|
||||
* thread while it is rendering (if the associated model is
|
||||
* derived from {@code AbstractDocument}). This enables the
|
||||
* model to potentially be updated asynchronously.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
super.paint(g, getComponent());
|
||||
}
|
||||
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintTextFieldBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintTextFieldBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* Overridden to do nothing.
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
// Overriden to do nothing, all our painting is done from update/paint.
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a bound property is changed
|
||||
* on the associated JTextComponent. This is a hook
|
||||
* which UI implementations may change to reflect how the
|
||||
* UI displays bound properties of JTextComponent subclasses.
|
||||
* This is implemented to do nothing (i.e. the response to
|
||||
* properties in JTextComponent itself are handled prior
|
||||
* to calling this method).
|
||||
*
|
||||
* @param evt the property change event
|
||||
*/
|
||||
@Override
|
||||
protected void propertyChange(PropertyChangeEvent evt) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
|
||||
updateStyle((JTextComponent)evt.getSource());
|
||||
}
|
||||
super.propertyChange(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
// Installs the text cursor on the component
|
||||
super.installDefaults();
|
||||
updateStyle(getComponent());
|
||||
getComponent().addFocusListener(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(getComponent(), ENABLED);
|
||||
|
||||
getComponent().putClientProperty("caretAspectRatio", null);
|
||||
getComponent().removeFocusListener(handler);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
super.uninstallDefaults();
|
||||
}
|
||||
|
||||
private final class Handler implements FocusListener {
|
||||
public void focusGained(FocusEvent e) {
|
||||
getComponent().repaint();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
getComponent().repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
195
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTextPaneUI.java
Normal file
195
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTextPaneUI.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Provides the look and feel for a styled text editor in the
|
||||
* Synth look and feel.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthTextPaneUI extends SynthEditorPaneUI {
|
||||
|
||||
/**
|
||||
* Creates a UI for the JTextPane.
|
||||
*
|
||||
* @param c the JTextPane object
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthTextPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the name used as a key to lookup properties through the
|
||||
* UIManager. This is used as a prefix to all the standard
|
||||
* text properties.
|
||||
*
|
||||
* @return the name ("TextPane")
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "TextPane";
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the UI for a component. This does the following
|
||||
* things.
|
||||
* <ol>
|
||||
* <li>
|
||||
* Sets opaqueness of the associated component according to its style,
|
||||
* if the opaque property has not already been set by the client program.
|
||||
* <li>
|
||||
* Installs the default caret and highlighter into the
|
||||
* associated component. These properties are only set if their
|
||||
* current value is either {@code null} or an instance of
|
||||
* {@link UIResource}.
|
||||
* <li>
|
||||
* Attaches to the editor and model. If there is no
|
||||
* model, a default one is created.
|
||||
* <li>
|
||||
* Creates the view factory and the view hierarchy used
|
||||
* to represent the model.
|
||||
* </ol>
|
||||
*
|
||||
* @param c the editor component
|
||||
* @see javax.swing.plaf.basic.BasicTextUI#installUI
|
||||
* @see ComponentUI#installUI
|
||||
*/
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
updateForeground(c.getForeground());
|
||||
updateFont(c.getFont());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a bound property is changed
|
||||
* on the associated JTextComponent. This is a hook
|
||||
* which UI implementations may change to reflect how the
|
||||
* UI displays bound properties of JTextComponent subclasses.
|
||||
* If the font, foreground or document has changed, the
|
||||
* the appropriate property is set in the default style of
|
||||
* the document.
|
||||
*
|
||||
* @param evt the property change event
|
||||
*/
|
||||
@Override
|
||||
protected void propertyChange(PropertyChangeEvent evt) {
|
||||
super.propertyChange(evt);
|
||||
|
||||
String name = evt.getPropertyName();
|
||||
|
||||
if (name.equals("foreground")) {
|
||||
updateForeground((Color)evt.getNewValue());
|
||||
} else if (name.equals("font")) {
|
||||
updateFont((Font)evt.getNewValue());
|
||||
} else if (name.equals("document")) {
|
||||
JComponent comp = getComponent();
|
||||
updateForeground(comp.getForeground());
|
||||
updateFont(comp.getFont());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the color in the default style of the document.
|
||||
*
|
||||
* @param color the new color to use or null to remove the color attribute
|
||||
* from the document's style
|
||||
*/
|
||||
private void updateForeground(Color color) {
|
||||
StyledDocument doc = (StyledDocument)getComponent().getDocument();
|
||||
Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
|
||||
|
||||
if (style == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (color == null) {
|
||||
style.removeAttribute(StyleConstants.Foreground);
|
||||
} else {
|
||||
StyleConstants.setForeground(style, color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the font in the default style of the document.
|
||||
*
|
||||
* @param font the new font to use or null to remove the font attribute
|
||||
* from the document's style
|
||||
*/
|
||||
private void updateFont(Font font) {
|
||||
StyledDocument doc = (StyledDocument)getComponent().getDocument();
|
||||
Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
|
||||
|
||||
if (style == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (font == null) {
|
||||
style.removeAttribute(StyleConstants.FontFamily);
|
||||
style.removeAttribute(StyleConstants.FontSize);
|
||||
style.removeAttribute(StyleConstants.Bold);
|
||||
style.removeAttribute(StyleConstants.Italic);
|
||||
} else {
|
||||
StyleConstants.setFontFamily(style, font.getName());
|
||||
StyleConstants.setFontSize(style, font.getSize());
|
||||
StyleConstants.setBold(style, font.isBold());
|
||||
StyleConstants.setItalic(style, font.isItalic());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
context.getPainter().paintTextPaneBackground(context, g, 0, 0,
|
||||
c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintTextPaneBorder(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
80
jdkSrc/jdk8/javax/swing/plaf/synth/SynthToggleButtonUI.java
Normal file
80
jdkSrc/jdk8/javax/swing/plaf/synth/SynthToggleButtonUI.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JToggleButton}.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthToggleButtonUI extends SynthButtonUI {
|
||||
// ********************************
|
||||
// Create PLAF
|
||||
// ********************************
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param b component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new SynthToggleButtonUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected String getPropertyPrefix() {
|
||||
return "ToggleButton.";
|
||||
}
|
||||
|
||||
@Override
|
||||
void paintBackground(SynthContext context, Graphics g, JComponent c) {
|
||||
if (((AbstractButton) c).isContentAreaFilled()) {
|
||||
int x = 0, y = 0, w = c.getWidth(), h = c.getHeight();
|
||||
SynthPainter painter = context.getPainter();
|
||||
painter.paintToggleButtonBackground(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintToggleButtonBorder(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
561
jdkSrc/jdk8/javax/swing/plaf/synth/SynthToolBarUI.java
Normal file
561
jdkSrc/jdk8/javax/swing/plaf/synth/SynthToolBarUI.java
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.Rectangle;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicToolBarUI;
|
||||
import sun.swing.plaf.synth.SynthIcon;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JToolBar}.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthToolBarUI extends BasicToolBarUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private Icon handleIcon = null;
|
||||
private Rectangle contentRect = new Rectangle();
|
||||
|
||||
private SynthStyle style;
|
||||
private SynthStyle contentStyle;
|
||||
private SynthStyle dragWindowStyle;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthToolBarUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
toolBar.setLayout(createLayout());
|
||||
updateStyle(toolBar);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
toolBar.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
toolBar.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
private void updateStyle(JToolBar c) {
|
||||
SynthContext context = getContext(
|
||||
c, Region.TOOL_BAR_CONTENT, null, ENABLED);
|
||||
contentStyle = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
|
||||
context = getContext(c, Region.TOOL_BAR_DRAG_WINDOW, null, ENABLED);
|
||||
dragWindowStyle = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
|
||||
context = getContext(c, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (oldStyle != style) {
|
||||
handleIcon =
|
||||
style.getIcon(context, "ToolBar.handleIcon");
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(toolBar, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
handleIcon = null;
|
||||
|
||||
context = getContext(toolBar, Region.TOOL_BAR_CONTENT,
|
||||
contentStyle, ENABLED);
|
||||
contentStyle.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
contentStyle = null;
|
||||
|
||||
context = getContext(toolBar, Region.TOOL_BAR_DRAG_WINDOW,
|
||||
dragWindowStyle, ENABLED);
|
||||
dragWindowStyle.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
dragWindowStyle = null;
|
||||
|
||||
toolBar.setLayout(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installComponents() {}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallComponents() {}
|
||||
|
||||
/**
|
||||
* Creates a {@code LayoutManager} to use with the toolbar.
|
||||
*
|
||||
* @return a {@code LayoutManager} instance
|
||||
*/
|
||||
protected LayoutManager createLayout() {
|
||||
return new SynthToolBarLayoutManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region, SynthStyle style) {
|
||||
return SynthContext.getContext(c, region,
|
||||
style, getComponentState(c, region));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region,
|
||||
SynthStyle style, int state) {
|
||||
return SynthContext.getContext(c, region, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c, Region region) {
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintToolBarBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight(),
|
||||
toolBar.getOrientation());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintToolBarBorder(context, g, x, y, w, h,
|
||||
toolBar.getOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation does nothing, because the {@code rollover}
|
||||
* property of the {@code JToolBar} class is not used
|
||||
* in the Synth Look and Feel.
|
||||
*/
|
||||
@Override
|
||||
protected void setBorderToNonRollover(Component c) {}
|
||||
|
||||
/**
|
||||
* This implementation does nothing, because the {@code rollover}
|
||||
* property of the {@code JToolBar} class is not used
|
||||
* in the Synth Look and Feel.
|
||||
*/
|
||||
@Override
|
||||
protected void setBorderToRollover(Component c) {}
|
||||
|
||||
/**
|
||||
* This implementation does nothing, because the {@code rollover}
|
||||
* property of the {@code JToolBar} class is not used
|
||||
* in the Synth Look and Feel.
|
||||
*/
|
||||
@Override
|
||||
protected void setBorderToNormal(Component c) {}
|
||||
|
||||
/**
|
||||
* Paints the toolbar.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
if (handleIcon != null && toolBar.isFloatable()) {
|
||||
int startX = toolBar.getComponentOrientation().isLeftToRight() ?
|
||||
0 : toolBar.getWidth() -
|
||||
SynthIcon.getIconWidth(handleIcon, context);
|
||||
SynthIcon.paintIcon(handleIcon, context, g, startX, 0,
|
||||
SynthIcon.getIconWidth(handleIcon, context),
|
||||
SynthIcon.getIconHeight(handleIcon, context));
|
||||
}
|
||||
|
||||
SynthContext subcontext = getContext(
|
||||
toolBar, Region.TOOL_BAR_CONTENT, contentStyle);
|
||||
paintContent(subcontext, g, contentRect);
|
||||
subcontext.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the toolbar content.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g {@code Graphics} object used for painting
|
||||
* @param bounds bounding box for the toolbar
|
||||
*/
|
||||
protected void paintContent(SynthContext context, Graphics g,
|
||||
Rectangle bounds) {
|
||||
SynthLookAndFeel.updateSubregion(context, g, bounds);
|
||||
context.getPainter().paintToolBarContentBackground(context, g,
|
||||
bounds.x, bounds.y, bounds.width, bounds.height,
|
||||
toolBar.getOrientation());
|
||||
context.getPainter().paintToolBarContentBorder(context, g,
|
||||
bounds.x, bounds.y, bounds.width, bounds.height,
|
||||
toolBar.getOrientation());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintDragWindow(Graphics g) {
|
||||
int w = dragWindow.getWidth();
|
||||
int h = dragWindow.getHeight();
|
||||
SynthContext context = getContext(
|
||||
toolBar, Region.TOOL_BAR_DRAG_WINDOW, dragWindowStyle);
|
||||
SynthLookAndFeel.updateSubregion(
|
||||
context, g, new Rectangle(0, 0, w, h));
|
||||
context.getPainter().paintToolBarDragWindowBackground(context,
|
||||
g, 0, 0, w, h,
|
||||
dragWindow.getOrientation());
|
||||
context.getPainter().paintToolBarDragWindowBorder(context, g, 0, 0, w, h,
|
||||
dragWindow.getOrientation());
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
//
|
||||
// PropertyChangeListener
|
||||
//
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JToolBar)e.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SynthToolBarLayoutManager implements LayoutManager {
|
||||
public void addLayoutComponent(String name, Component comp) {}
|
||||
|
||||
public void removeLayoutComponent(Component comp) {}
|
||||
|
||||
public Dimension minimumLayoutSize(Container parent) {
|
||||
JToolBar tb = (JToolBar)parent;
|
||||
Insets insets = tb.getInsets();
|
||||
Dimension dim = new Dimension();
|
||||
SynthContext context = getContext(tb);
|
||||
|
||||
if (tb.getOrientation() == JToolBar.HORIZONTAL) {
|
||||
dim.width = tb.isFloatable() ?
|
||||
SynthIcon.getIconWidth(handleIcon, context) : 0;
|
||||
Dimension compDim;
|
||||
for (int i = 0; i < tb.getComponentCount(); i++) {
|
||||
Component component = tb.getComponent(i);
|
||||
if (component.isVisible()) {
|
||||
compDim = component.getMinimumSize();
|
||||
dim.width += compDim.width;
|
||||
dim.height = Math.max(dim.height, compDim.height);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dim.height = tb.isFloatable() ?
|
||||
SynthIcon.getIconHeight(handleIcon, context) : 0;
|
||||
Dimension compDim;
|
||||
for (int i = 0; i < tb.getComponentCount(); i++) {
|
||||
Component component = tb.getComponent(i);
|
||||
if (component.isVisible()) {
|
||||
compDim = component.getMinimumSize();
|
||||
dim.width = Math.max(dim.width, compDim.width);
|
||||
dim.height += compDim.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
dim.width += insets.left + insets.right;
|
||||
dim.height += insets.top + insets.bottom;
|
||||
|
||||
context.dispose();
|
||||
return dim;
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
JToolBar tb = (JToolBar)parent;
|
||||
Insets insets = tb.getInsets();
|
||||
Dimension dim = new Dimension();
|
||||
SynthContext context = getContext(tb);
|
||||
|
||||
if (tb.getOrientation() == JToolBar.HORIZONTAL) {
|
||||
dim.width = tb.isFloatable() ?
|
||||
SynthIcon.getIconWidth(handleIcon, context) : 0;
|
||||
Dimension compDim;
|
||||
for (int i = 0; i < tb.getComponentCount(); i++) {
|
||||
Component component = tb.getComponent(i);
|
||||
if (component.isVisible()) {
|
||||
compDim = component.getPreferredSize();
|
||||
dim.width += compDim.width;
|
||||
dim.height = Math.max(dim.height, compDim.height);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dim.height = tb.isFloatable() ?
|
||||
SynthIcon.getIconHeight(handleIcon, context) : 0;
|
||||
Dimension compDim;
|
||||
for (int i = 0; i < tb.getComponentCount(); i++) {
|
||||
Component component = tb.getComponent(i);
|
||||
if (component.isVisible()) {
|
||||
compDim = component.getPreferredSize();
|
||||
dim.width = Math.max(dim.width, compDim.width);
|
||||
dim.height += compDim.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
dim.width += insets.left + insets.right;
|
||||
dim.height += insets.top + insets.bottom;
|
||||
|
||||
context.dispose();
|
||||
return dim;
|
||||
}
|
||||
|
||||
public void layoutContainer(Container parent) {
|
||||
JToolBar tb = (JToolBar)parent;
|
||||
Insets insets = tb.getInsets();
|
||||
boolean ltr = tb.getComponentOrientation().isLeftToRight();
|
||||
SynthContext context = getContext(tb);
|
||||
|
||||
Component c;
|
||||
Dimension d;
|
||||
|
||||
// JToolBar by default uses a somewhat modified BoxLayout as
|
||||
// its layout manager. For compatibility reasons, we want to
|
||||
// support Box "glue" as a way to move things around on the
|
||||
// toolbar. "glue" is represented in BoxLayout as a Box.Filler
|
||||
// with a minimum and preferred size of (0,0).
|
||||
// So what we do here is find the number of such glue fillers
|
||||
// and figure out how much space should be allocated to them.
|
||||
int glueCount = 0;
|
||||
for (int i=0; i<tb.getComponentCount(); i++) {
|
||||
if (isGlue(tb.getComponent(i))) glueCount++;
|
||||
}
|
||||
|
||||
if (tb.getOrientation() == JToolBar.HORIZONTAL) {
|
||||
int handleWidth = tb.isFloatable() ?
|
||||
SynthIcon.getIconWidth(handleIcon, context) : 0;
|
||||
|
||||
// Note: contentRect does not take insets into account
|
||||
// since it is used for determining the bounds that are
|
||||
// passed to paintToolBarContentBackground().
|
||||
contentRect.x = ltr ? handleWidth : 0;
|
||||
contentRect.y = 0;
|
||||
contentRect.width = tb.getWidth() - handleWidth;
|
||||
contentRect.height = tb.getHeight();
|
||||
|
||||
// However, we do take the insets into account here for
|
||||
// the purposes of laying out the toolbar child components.
|
||||
int x = ltr ?
|
||||
handleWidth + insets.left :
|
||||
tb.getWidth() - handleWidth - insets.right;
|
||||
int baseY = insets.top;
|
||||
int baseH = tb.getHeight() - insets.top - insets.bottom;
|
||||
|
||||
// we need to get the minimum width for laying things out
|
||||
// so that we can calculate how much empty space needs to
|
||||
// be distributed among the "glue", if any
|
||||
int extraSpacePerGlue = 0;
|
||||
if (glueCount > 0) {
|
||||
int minWidth = minimumLayoutSize(parent).width;
|
||||
extraSpacePerGlue = (tb.getWidth() - minWidth) / glueCount;
|
||||
if (extraSpacePerGlue < 0) extraSpacePerGlue = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tb.getComponentCount(); i++) {
|
||||
c = tb.getComponent(i);
|
||||
if (c.isVisible()) {
|
||||
d = c.getPreferredSize();
|
||||
int y, h;
|
||||
if (d.height >= baseH || c instanceof JSeparator) {
|
||||
// Fill available height
|
||||
y = baseY;
|
||||
h = baseH;
|
||||
} else {
|
||||
// Center component vertically in the available space
|
||||
y = baseY + (baseH / 2) - (d.height / 2);
|
||||
h = d.height;
|
||||
}
|
||||
//if the component is a "glue" component then add to its
|
||||
//width the extraSpacePerGlue it is due
|
||||
if (isGlue(c)) d.width += extraSpacePerGlue;
|
||||
c.setBounds(ltr ? x : x - d.width, y, d.width, h);
|
||||
x = ltr ? x + d.width : x - d.width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int handleHeight = tb.isFloatable() ?
|
||||
SynthIcon.getIconHeight(handleIcon, context) : 0;
|
||||
|
||||
// See notes above regarding the use of insets
|
||||
contentRect.x = 0;
|
||||
contentRect.y = handleHeight;
|
||||
contentRect.width = tb.getWidth();
|
||||
contentRect.height = tb.getHeight() - handleHeight;
|
||||
|
||||
int baseX = insets.left;
|
||||
int baseW = tb.getWidth() - insets.left - insets.right;
|
||||
int y = handleHeight + insets.top;
|
||||
|
||||
// we need to get the minimum height for laying things out
|
||||
// so that we can calculate how much empty space needs to
|
||||
// be distributed among the "glue", if any
|
||||
int extraSpacePerGlue = 0;
|
||||
if (glueCount > 0) {
|
||||
int minHeight = minimumLayoutSize(parent).height;
|
||||
extraSpacePerGlue = (tb.getHeight() - minHeight) / glueCount;
|
||||
if (extraSpacePerGlue < 0) extraSpacePerGlue = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tb.getComponentCount(); i++) {
|
||||
c = tb.getComponent(i);
|
||||
if (c.isVisible()) {
|
||||
d = c.getPreferredSize();
|
||||
int x, w;
|
||||
if (d.width >= baseW || c instanceof JSeparator) {
|
||||
// Fill available width
|
||||
x = baseX;
|
||||
w = baseW;
|
||||
} else {
|
||||
// Center component horizontally in the available space
|
||||
x = baseX + (baseW / 2) - (d.width / 2);
|
||||
w = d.width;
|
||||
}
|
||||
//if the component is a "glue" component then add to its
|
||||
//height the extraSpacePerGlue it is due
|
||||
if (isGlue(c)) d.height += extraSpacePerGlue;
|
||||
c.setBounds(x, y, w, d.height);
|
||||
y += d.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
private boolean isGlue(Component c) {
|
||||
if (c.isVisible() && c instanceof Box.Filler) {
|
||||
Box.Filler f = (Box.Filler)c;
|
||||
Dimension min = f.getMinimumSize();
|
||||
Dimension pref = f.getPreferredSize();
|
||||
return min.width == 0 && min.height == 0 &&
|
||||
pref.width == 0 && pref.height == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
244
jdkSrc/jdk8/javax/swing/plaf/synth/SynthToolTipUI.java
Normal file
244
jdkSrc/jdk8/javax/swing/plaf/synth/SynthToolTipUI.java
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.plaf.basic.BasicToolTipUI;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.text.View;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JToolTip}.
|
||||
*
|
||||
* @author Joshua Outwater
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthToolTipUI extends BasicToolTipUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthToolTipUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults(JComponent c) {
|
||||
updateStyle(c);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners(JComponent c) {
|
||||
c.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners(JComponent c) {
|
||||
c.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c) {
|
||||
JComponent comp = ((JToolTip)c).getComponent();
|
||||
|
||||
if (comp != null && !comp.isEnabled()) {
|
||||
return DISABLED;
|
||||
}
|
||||
return SynthLookAndFeel.getComponentState(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintToolTipBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintToolTipBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
JToolTip tip = (JToolTip)context.getComponent();
|
||||
|
||||
Insets insets = tip.getInsets();
|
||||
View v = (View)tip.getClientProperty(BasicHTML.propertyKey);
|
||||
if (v != null) {
|
||||
Rectangle paintTextR = new Rectangle(insets.left, insets.top,
|
||||
tip.getWidth() - (insets.left + insets.right),
|
||||
tip.getHeight() - (insets.top + insets.bottom));
|
||||
v.paint(g, paintTextR);
|
||||
} else {
|
||||
g.setColor(context.getStyle().getColor(context,
|
||||
ColorType.TEXT_FOREGROUND));
|
||||
g.setFont(style.getFont(context));
|
||||
context.getStyle().getGraphicsUtils(context).paintText(
|
||||
context, g, tip.getTipText(), insets.left, insets.top, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
Insets insets = c.getInsets();
|
||||
Dimension prefSize = new Dimension(insets.left+insets.right,
|
||||
insets.top+insets.bottom);
|
||||
String text = ((JToolTip)c).getTipText();
|
||||
|
||||
if (text != null) {
|
||||
View v = (c != null) ? (View) c.getClientProperty("html") : null;
|
||||
if (v != null) {
|
||||
prefSize.width += (int) v.getPreferredSpan(View.X_AXIS);
|
||||
prefSize.height += (int) v.getPreferredSpan(View.Y_AXIS);
|
||||
} else {
|
||||
Font font = context.getStyle().getFont(context);
|
||||
FontMetrics fm = c.getFontMetrics(font);
|
||||
prefSize.width += context.getStyle().getGraphicsUtils(context).
|
||||
computeStringWidth(context, font, fm, text);
|
||||
prefSize.height += fm.getHeight();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
return prefSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JToolTip)e.getSource());
|
||||
}
|
||||
String name = e.getPropertyName();
|
||||
if (name.equals("tiptext") || "font".equals(name) ||
|
||||
"foreground".equals(name)) {
|
||||
// remove the old html view client property if one
|
||||
// existed, and install a new one if the text installed
|
||||
// into the JLabel is html source.
|
||||
JToolTip tip = ((JToolTip) e.getSource());
|
||||
String text = tip.getTipText();
|
||||
BasicHTML.updateRenderer(tip, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
821
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTreeUI.java
Normal file
821
jdkSrc/jdk8/javax/swing/plaf/synth/SynthTreeUI.java
Normal file
@@ -0,0 +1,821 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Enumeration;
|
||||
import javax.swing.DefaultCellEditor;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.DefaultTreeCellEditor;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.TreeCellEditor;
|
||||
import javax.swing.tree.TreeCellRenderer;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import sun.swing.plaf.synth.SynthIcon;
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JTree}.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthTreeUI extends BasicTreeUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
private SynthStyle cellStyle;
|
||||
|
||||
private SynthContext paintContext;
|
||||
|
||||
private boolean drawHorizontalLines;
|
||||
private boolean drawVerticalLines;
|
||||
|
||||
private Object linesStyle;
|
||||
|
||||
private int padding;
|
||||
|
||||
private boolean useTreeColors;
|
||||
|
||||
private Icon expandedIconWrapper = new ExpandedIconWrapper();
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param x component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new SynthTreeUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Icon getExpandedIcon() {
|
||||
return expandedIconWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
updateStyle(tree);
|
||||
}
|
||||
|
||||
private void updateStyle(JTree tree) {
|
||||
SynthContext context = getContext(tree, ENABLED);
|
||||
SynthStyle oldStyle = style;
|
||||
|
||||
style = SynthLookAndFeel.updateStyle(context, this);
|
||||
if (style != oldStyle) {
|
||||
Object value;
|
||||
|
||||
setExpandedIcon(style.getIcon(context, "Tree.expandedIcon"));
|
||||
setCollapsedIcon(style.getIcon(context, "Tree.collapsedIcon"));
|
||||
|
||||
setLeftChildIndent(style.getInt(context, "Tree.leftChildIndent",
|
||||
0));
|
||||
setRightChildIndent(style.getInt(context, "Tree.rightChildIndent",
|
||||
0));
|
||||
|
||||
drawHorizontalLines = style.getBoolean(
|
||||
context, "Tree.drawHorizontalLines",true);
|
||||
drawVerticalLines = style.getBoolean(
|
||||
context, "Tree.drawVerticalLines", true);
|
||||
linesStyle = style.get(context, "Tree.linesStyle");
|
||||
|
||||
value = style.get(context, "Tree.rowHeight");
|
||||
if (value != null) {
|
||||
LookAndFeel.installProperty(tree, "rowHeight", value);
|
||||
}
|
||||
|
||||
value = style.get(context, "Tree.scrollsOnExpand");
|
||||
LookAndFeel.installProperty(tree, "scrollsOnExpand",
|
||||
value != null? value : Boolean.TRUE);
|
||||
|
||||
padding = style.getInt(context, "Tree.padding", 0);
|
||||
|
||||
largeModel = (tree.isLargeModel() && tree.getRowHeight() > 0);
|
||||
|
||||
useTreeColors = style.getBoolean(context,
|
||||
"Tree.rendererUseTreeColors", true);
|
||||
|
||||
Boolean showsRootHandles = style.getBoolean(
|
||||
context, "Tree.showsRootHandles", Boolean.TRUE);
|
||||
LookAndFeel.installProperty(
|
||||
tree, JTree.SHOWS_ROOT_HANDLES_PROPERTY, showsRootHandles);
|
||||
|
||||
if (oldStyle != null) {
|
||||
uninstallKeyboardActions();
|
||||
installKeyboardActions();
|
||||
}
|
||||
}
|
||||
context.dispose();
|
||||
|
||||
context = getContext(tree, Region.TREE_CELL, ENABLED);
|
||||
cellStyle = SynthLookAndFeel.updateStyle(context, this);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
tree.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region) {
|
||||
return getContext(c, region, getComponentState(c, region));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, Region region, int state) {
|
||||
return SynthContext.getContext(c, region, cellStyle, state);
|
||||
}
|
||||
|
||||
private int getComponentState(JComponent c, Region region) {
|
||||
// Always treat the cell as selected, will be adjusted appropriately
|
||||
// when painted.
|
||||
return ENABLED | SELECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected TreeCellEditor createDefaultCellEditor() {
|
||||
TreeCellRenderer renderer = tree.getCellRenderer();
|
||||
DefaultTreeCellEditor editor;
|
||||
|
||||
if(renderer != null && (renderer instanceof DefaultTreeCellRenderer)) {
|
||||
editor = new SynthTreeCellEditor(tree, (DefaultTreeCellRenderer)
|
||||
renderer);
|
||||
}
|
||||
else {
|
||||
editor = new SynthTreeCellEditor(tree, null);
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected TreeCellRenderer createDefaultCellRenderer() {
|
||||
return new SynthTreeCellRenderer();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
SynthContext context = getContext(tree, ENABLED);
|
||||
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
|
||||
context = getContext(tree, Region.TREE_CELL, ENABLED);
|
||||
cellStyle.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
cellStyle = null;
|
||||
|
||||
|
||||
if (tree.getTransferHandler() instanceof UIResource) {
|
||||
tree.setTransferHandler(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
tree.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintTreeBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
context.getPainter().paintTreeBorder(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
paintContext = context;
|
||||
|
||||
updateLeadSelectionRow();
|
||||
|
||||
Rectangle paintBounds = g.getClipBounds();
|
||||
Insets insets = tree.getInsets();
|
||||
TreePath initialPath = getClosestPathForLocation(tree, 0,
|
||||
paintBounds.y);
|
||||
Enumeration paintingEnumerator = treeState.getVisiblePathsFrom
|
||||
(initialPath);
|
||||
int row = treeState.getRowForPath(initialPath);
|
||||
int endY = paintBounds.y + paintBounds.height;
|
||||
TreeModel treeModel = tree.getModel();
|
||||
SynthContext cellContext = getContext(tree, Region.TREE_CELL);
|
||||
|
||||
drawingCache.clear();
|
||||
|
||||
setHashColor(context.getStyle().getColor(context,
|
||||
ColorType.FOREGROUND));
|
||||
|
||||
if (paintingEnumerator != null) {
|
||||
// First pass, draw the rows
|
||||
|
||||
boolean done = false;
|
||||
boolean isExpanded;
|
||||
boolean hasBeenExpanded;
|
||||
boolean isLeaf;
|
||||
Rectangle rowBounds = new Rectangle(0, 0, tree.getWidth(),0);
|
||||
Rectangle bounds;
|
||||
TreePath path;
|
||||
TreeCellRenderer renderer = tree.getCellRenderer();
|
||||
DefaultTreeCellRenderer dtcr = (renderer instanceof
|
||||
DefaultTreeCellRenderer) ? (DefaultTreeCellRenderer)
|
||||
renderer : null;
|
||||
|
||||
configureRenderer(cellContext);
|
||||
while (!done && paintingEnumerator.hasMoreElements()) {
|
||||
path = (TreePath)paintingEnumerator.nextElement();
|
||||
bounds = getPathBounds(tree, path);
|
||||
if ((path != null) && (bounds != null)) {
|
||||
isLeaf = treeModel.isLeaf(path.getLastPathComponent());
|
||||
if (isLeaf) {
|
||||
isExpanded = hasBeenExpanded = false;
|
||||
}
|
||||
else {
|
||||
isExpanded = treeState.getExpandedState(path);
|
||||
hasBeenExpanded = tree.hasBeenExpanded(path);
|
||||
}
|
||||
rowBounds.y = bounds.y;
|
||||
rowBounds.height = bounds.height;
|
||||
paintRow(renderer, dtcr, context, cellContext, g,
|
||||
paintBounds, insets, bounds, rowBounds, path,
|
||||
row, isExpanded, hasBeenExpanded, isLeaf);
|
||||
if ((bounds.y + bounds.height) >= endY) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
done = true;
|
||||
}
|
||||
row++;
|
||||
}
|
||||
|
||||
// Draw the connecting lines and controls.
|
||||
// Find each parent and have them draw a line to their last child
|
||||
boolean rootVisible = tree.isRootVisible();
|
||||
TreePath parentPath = initialPath;
|
||||
parentPath = parentPath.getParentPath();
|
||||
while (parentPath != null) {
|
||||
paintVerticalPartOfLeg(g, paintBounds, insets, parentPath);
|
||||
drawingCache.put(parentPath, Boolean.TRUE);
|
||||
parentPath = parentPath.getParentPath();
|
||||
}
|
||||
done = false;
|
||||
paintingEnumerator = treeState.getVisiblePathsFrom(initialPath);
|
||||
while (!done && paintingEnumerator.hasMoreElements()) {
|
||||
path = (TreePath)paintingEnumerator.nextElement();
|
||||
bounds = getPathBounds(tree, path);
|
||||
if ((path != null) && (bounds != null)) {
|
||||
isLeaf = treeModel.isLeaf(path.getLastPathComponent());
|
||||
if (isLeaf) {
|
||||
isExpanded = hasBeenExpanded = false;
|
||||
}
|
||||
else {
|
||||
isExpanded = treeState.getExpandedState(path);
|
||||
hasBeenExpanded = tree.hasBeenExpanded(path);
|
||||
}
|
||||
// See if the vertical line to the parent has been drawn.
|
||||
parentPath = path.getParentPath();
|
||||
if (parentPath != null) {
|
||||
if (drawingCache.get(parentPath) == null) {
|
||||
paintVerticalPartOfLeg(g, paintBounds, insets,
|
||||
parentPath);
|
||||
drawingCache.put(parentPath, Boolean.TRUE);
|
||||
}
|
||||
paintHorizontalPartOfLeg(g,
|
||||
paintBounds, insets, bounds,
|
||||
path, row, isExpanded,
|
||||
hasBeenExpanded, isLeaf);
|
||||
}
|
||||
else if (rootVisible && row == 0) {
|
||||
paintHorizontalPartOfLeg(g,
|
||||
paintBounds, insets, bounds,
|
||||
path, row, isExpanded,
|
||||
hasBeenExpanded, isLeaf);
|
||||
}
|
||||
if (shouldPaintExpandControl(path, row, isExpanded,
|
||||
hasBeenExpanded, isLeaf)) {
|
||||
paintExpandControl(g, paintBounds,
|
||||
insets, bounds, path, row,
|
||||
isExpanded, hasBeenExpanded,isLeaf);
|
||||
}
|
||||
if ((bounds.y + bounds.height) >= endY) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
done = true;
|
||||
}
|
||||
row++;
|
||||
}
|
||||
}
|
||||
cellContext.dispose();
|
||||
|
||||
paintDropLine(g);
|
||||
|
||||
// Empty out the renderer pane, allowing renderers to be gc'ed.
|
||||
rendererPane.removeAll();
|
||||
|
||||
paintContext = null;
|
||||
}
|
||||
|
||||
private void configureRenderer(SynthContext context) {
|
||||
TreeCellRenderer renderer = tree.getCellRenderer();
|
||||
|
||||
if (renderer instanceof DefaultTreeCellRenderer) {
|
||||
DefaultTreeCellRenderer r = (DefaultTreeCellRenderer)renderer;
|
||||
SynthStyle style = context.getStyle();
|
||||
|
||||
context.setComponentState(ENABLED | SELECTED);
|
||||
Color color = r.getTextSelectionColor();
|
||||
if (color == null || (color instanceof UIResource)) {
|
||||
r.setTextSelectionColor(style.getColor(
|
||||
context, ColorType.TEXT_FOREGROUND));
|
||||
}
|
||||
color = r.getBackgroundSelectionColor();
|
||||
if (color == null || (color instanceof UIResource)) {
|
||||
r.setBackgroundSelectionColor(style.getColor(
|
||||
context, ColorType.TEXT_BACKGROUND));
|
||||
}
|
||||
|
||||
context.setComponentState(ENABLED);
|
||||
color = r.getTextNonSelectionColor();
|
||||
if (color == null || color instanceof UIResource) {
|
||||
r.setTextNonSelectionColor(style.getColorForState(
|
||||
context, ColorType.TEXT_FOREGROUND));
|
||||
}
|
||||
color = r.getBackgroundNonSelectionColor();
|
||||
if (color == null || color instanceof UIResource) {
|
||||
r.setBackgroundNonSelectionColor(style.getColorForState(
|
||||
context, ColorType.TEXT_BACKGROUND));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
|
||||
Insets insets, Rectangle bounds,
|
||||
TreePath path, int row,
|
||||
boolean isExpanded,
|
||||
boolean hasBeenExpanded, boolean
|
||||
isLeaf) {
|
||||
if (drawHorizontalLines) {
|
||||
super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds,
|
||||
path, row, isExpanded,
|
||||
hasBeenExpanded, isLeaf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintHorizontalLine(Graphics g, JComponent c, int y,
|
||||
int left, int right) {
|
||||
paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
|
||||
paintContext, "Tree.horizontalLine", g, left, y, right, y, linesStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintVerticalPartOfLeg(Graphics g,
|
||||
Rectangle clipBounds, Insets insets,
|
||||
TreePath path) {
|
||||
if (drawVerticalLines) {
|
||||
super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,
|
||||
int bottom) {
|
||||
paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
|
||||
paintContext, "Tree.verticalLine", g, x, top, x, bottom, linesStyle);
|
||||
}
|
||||
|
||||
private void paintRow(TreeCellRenderer renderer,
|
||||
DefaultTreeCellRenderer dtcr, SynthContext treeContext,
|
||||
SynthContext cellContext, Graphics g, Rectangle clipBounds,
|
||||
Insets insets, Rectangle bounds, Rectangle rowBounds,
|
||||
TreePath path, int row, boolean isExpanded,
|
||||
boolean hasBeenExpanded, boolean isLeaf) {
|
||||
// Don't paint the renderer if editing this row.
|
||||
boolean selected = tree.isRowSelected(row);
|
||||
|
||||
JTree.DropLocation dropLocation = tree.getDropLocation();
|
||||
boolean isDrop = dropLocation != null
|
||||
&& dropLocation.getChildIndex() == -1
|
||||
&& path == dropLocation.getPath();
|
||||
|
||||
int state = ENABLED;
|
||||
if (selected || isDrop) {
|
||||
state |= SELECTED;
|
||||
}
|
||||
|
||||
if (tree.isFocusOwner() && row == getLeadSelectionRow()) {
|
||||
state |= FOCUSED;
|
||||
}
|
||||
|
||||
cellContext.setComponentState(state);
|
||||
|
||||
if (dtcr != null && (dtcr.getBorderSelectionColor() instanceof
|
||||
UIResource)) {
|
||||
dtcr.setBorderSelectionColor(style.getColor(
|
||||
cellContext, ColorType.FOCUS));
|
||||
}
|
||||
SynthLookAndFeel.updateSubregion(cellContext, g, rowBounds);
|
||||
cellContext.getPainter().paintTreeCellBackground(cellContext, g,
|
||||
rowBounds.x, rowBounds.y, rowBounds.width,
|
||||
rowBounds.height);
|
||||
cellContext.getPainter().paintTreeCellBorder(cellContext, g,
|
||||
rowBounds.x, rowBounds.y, rowBounds.width,
|
||||
rowBounds.height);
|
||||
if (editingComponent != null && editingRow == row) {
|
||||
return;
|
||||
}
|
||||
|
||||
int leadIndex;
|
||||
|
||||
if (tree.hasFocus()) {
|
||||
leadIndex = getLeadSelectionRow();
|
||||
}
|
||||
else {
|
||||
leadIndex = -1;
|
||||
}
|
||||
|
||||
Component component = renderer.getTreeCellRendererComponent(
|
||||
tree, path.getLastPathComponent(),
|
||||
selected, isExpanded, isLeaf, row,
|
||||
(leadIndex == row));
|
||||
|
||||
rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y,
|
||||
bounds.width, bounds.height, true);
|
||||
}
|
||||
|
||||
private int findCenteredX(int x, int iconWidth) {
|
||||
return tree.getComponentOrientation().isLeftToRight()
|
||||
? x - (int)Math.ceil(iconWidth / 2.0)
|
||||
: x - (int)Math.floor(iconWidth / 2.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintExpandControl(Graphics g, Rectangle clipBounds,
|
||||
Insets insets, Rectangle bounds, TreePath path, int row,
|
||||
boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) {
|
||||
//modify the paintContext's state to match the state for the row
|
||||
//this is a hack in that it requires knowledge of the subsequent
|
||||
//method calls. The point is, the context used in drawCentered
|
||||
//should reflect the state of the row, not of the tree.
|
||||
boolean isSelected = tree.getSelectionModel().isPathSelected(path);
|
||||
int state = paintContext.getComponentState();
|
||||
if (isSelected) {
|
||||
paintContext.setComponentState(state | SynthConstants.SELECTED);
|
||||
}
|
||||
super.paintExpandControl(g, clipBounds, insets, bounds, path, row,
|
||||
isExpanded, hasBeenExpanded, isLeaf);
|
||||
paintContext.setComponentState(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void drawCentered(Component c, Graphics graphics, Icon icon,
|
||||
int x, int y) {
|
||||
int w = SynthIcon.getIconWidth(icon, paintContext);
|
||||
int h = SynthIcon.getIconHeight(icon, paintContext);
|
||||
|
||||
SynthIcon.paintIcon(icon, paintContext, graphics,
|
||||
findCenteredX(x, w),
|
||||
y - h/2, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(event)) {
|
||||
updateStyle((JTree)event.getSource());
|
||||
}
|
||||
|
||||
if ("dropLocation" == event.getPropertyName()) {
|
||||
JTree.DropLocation oldValue = (JTree.DropLocation)event.getOldValue();
|
||||
repaintDropLocation(oldValue);
|
||||
repaintDropLocation(tree.getDropLocation());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void paintDropLine(Graphics g) {
|
||||
JTree.DropLocation loc = tree.getDropLocation();
|
||||
if (!isDropLine(loc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Color c = (Color)style.get(paintContext, "Tree.dropLineColor");
|
||||
if (c != null) {
|
||||
g.setColor(c);
|
||||
Rectangle rect = getDropLineRect(loc);
|
||||
g.fillRect(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void repaintDropLocation(JTree.DropLocation loc) {
|
||||
if (loc == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Rectangle r;
|
||||
|
||||
if (isDropLine(loc)) {
|
||||
r = getDropLineRect(loc);
|
||||
} else {
|
||||
r = tree.getPathBounds(loc.getPath());
|
||||
if (r != null) {
|
||||
r.x = 0;
|
||||
r.width = tree.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
if (r != null) {
|
||||
tree.repaint(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected int getRowX(int row, int depth) {
|
||||
return super.getRowX(row, depth) + padding;
|
||||
}
|
||||
|
||||
|
||||
private class SynthTreeCellRenderer extends DefaultTreeCellRenderer
|
||||
implements UIResource {
|
||||
SynthTreeCellRenderer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Tree.cellRenderer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value,
|
||||
boolean sel,
|
||||
boolean expanded,
|
||||
boolean leaf, int row,
|
||||
boolean hasFocus) {
|
||||
if (!useTreeColors && (sel || hasFocus)) {
|
||||
SynthLookAndFeel.setSelectedUI((SynthLabelUI)SynthLookAndFeel.
|
||||
getUIOfType(getUI(), SynthLabelUI.class),
|
||||
sel, hasFocus, tree.isEnabled(), false);
|
||||
}
|
||||
else {
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
return super.getTreeCellRendererComponent(tree, value, sel,
|
||||
expanded, leaf, row, hasFocus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
paintComponent(g);
|
||||
if (hasFocus) {
|
||||
SynthContext context = getContext(tree, Region.TREE_CELL);
|
||||
|
||||
if (context.getStyle() == null) {
|
||||
assert false: "SynthTreeCellRenderer is being used " +
|
||||
"outside of UI that created it";
|
||||
return;
|
||||
}
|
||||
int imageOffset = 0;
|
||||
Icon currentI = getIcon();
|
||||
|
||||
if(currentI != null && getText() != null) {
|
||||
imageOffset = currentI.getIconWidth() +
|
||||
Math.max(0, getIconTextGap() - 1);
|
||||
}
|
||||
if (selected) {
|
||||
context.setComponentState(ENABLED | SELECTED);
|
||||
}
|
||||
else {
|
||||
context.setComponentState(ENABLED);
|
||||
}
|
||||
if(getComponentOrientation().isLeftToRight()) {
|
||||
context.getPainter().paintTreeCellFocus(context, g,
|
||||
imageOffset, 0, getWidth() - imageOffset,
|
||||
getHeight());
|
||||
}
|
||||
else {
|
||||
context.getPainter().paintTreeCellFocus(context, g,
|
||||
0, 0, getWidth() - imageOffset, getHeight());
|
||||
}
|
||||
context.dispose();
|
||||
}
|
||||
SynthLookAndFeel.resetSelectedUI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SynthTreeCellEditor extends DefaultTreeCellEditor {
|
||||
public SynthTreeCellEditor(JTree tree,
|
||||
DefaultTreeCellRenderer renderer) {
|
||||
super(tree, renderer);
|
||||
setBorderSelectionColor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TreeCellEditor createTreeCellEditor() {
|
||||
JTextField tf = new JTextField() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Tree.cellEditor";
|
||||
}
|
||||
};
|
||||
DefaultCellEditor editor = new DefaultCellEditor(tf);
|
||||
|
||||
// One click to edit.
|
||||
editor.setClickCountToStart(1);
|
||||
return editor;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// BasicTreeUI directly uses expandIcon outside of the Synth methods.
|
||||
// To get the correct context we return an instance of this that fetches
|
||||
// the SynthContext as needed.
|
||||
//
|
||||
private class ExpandedIconWrapper extends SynthIcon {
|
||||
public void paintIcon(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
if (context == null) {
|
||||
context = getContext(tree);
|
||||
SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);
|
||||
context.dispose();
|
||||
}
|
||||
else {
|
||||
SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
public int getIconWidth(SynthContext context) {
|
||||
int width;
|
||||
if (context == null) {
|
||||
context = getContext(tree);
|
||||
width = SynthIcon.getIconWidth(expandedIcon, context);
|
||||
context.dispose();
|
||||
}
|
||||
else {
|
||||
width = SynthIcon.getIconWidth(expandedIcon, context);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getIconHeight(SynthContext context) {
|
||||
int height;
|
||||
if (context == null) {
|
||||
context = getContext(tree);
|
||||
height = SynthIcon.getIconHeight(expandedIcon, context);
|
||||
context.dispose();
|
||||
}
|
||||
else {
|
||||
height = SynthIcon.getIconHeight(expandedIcon, context);
|
||||
}
|
||||
return height;
|
||||
}
|
||||
}
|
||||
}
|
||||
58
jdkSrc/jdk8/javax/swing/plaf/synth/SynthUI.java
Normal file
58
jdkSrc/jdk8/javax/swing/plaf/synth/SynthUI.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
* SynthUI is used to fetch the SynthContext for a particular Component.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface SynthUI extends SynthConstants {
|
||||
|
||||
/**
|
||||
* Returns the Context for the specified component.
|
||||
*
|
||||
* @param c Component requesting SynthContext.
|
||||
* @return SynthContext describing component.
|
||||
*/
|
||||
public SynthContext getContext(JComponent c);
|
||||
|
||||
/**
|
||||
* Paints the border.
|
||||
*
|
||||
* @param context a component context
|
||||
* @param g {@code Graphics} to paint on
|
||||
* @param x the X coordinate
|
||||
* @param y the Y coordinate
|
||||
* @param w width of the border
|
||||
* @param h height of the border
|
||||
*/
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h);
|
||||
}
|
||||
227
jdkSrc/jdk8/javax/swing/plaf/synth/SynthViewportUI.java
Normal file
227
jdkSrc/jdk8/javax/swing/plaf/synth/SynthViewportUI.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf.synth;
|
||||
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import java.awt.*;
|
||||
|
||||
|
||||
/**
|
||||
* Provides the Synth L&F UI delegate for
|
||||
* {@link javax.swing.JViewport}.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public class SynthViewportUI extends ViewportUI
|
||||
implements PropertyChangeListener, SynthUI {
|
||||
private SynthStyle style;
|
||||
|
||||
/**
|
||||
* Creates a new UI object for the given component.
|
||||
*
|
||||
* @param c component to create UI object for
|
||||
* @return the UI object
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new SynthViewportUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
installDefaults(c);
|
||||
installListeners(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
super.uninstallUI(c);
|
||||
uninstallListeners(c);
|
||||
uninstallDefaults(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs defaults for a viewport.
|
||||
*
|
||||
* @param c a {@code JViewport} object
|
||||
*/
|
||||
protected void installDefaults(JComponent c) {
|
||||
updateStyle(c);
|
||||
}
|
||||
|
||||
private void updateStyle(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
|
||||
// Note: JViewport is special cased as it does not allow for
|
||||
// a border to be set. JViewport.setBorder is overriden to throw
|
||||
// an IllegalArgumentException. Refer to SynthScrollPaneUI for
|
||||
// details of this.
|
||||
SynthStyle newStyle = SynthLookAndFeel.getStyle(context.getComponent(),
|
||||
context.getRegion());
|
||||
SynthStyle oldStyle = context.getStyle();
|
||||
|
||||
if (newStyle != oldStyle) {
|
||||
if (oldStyle != null) {
|
||||
oldStyle.uninstallDefaults(context);
|
||||
}
|
||||
context.setStyle(newStyle);
|
||||
newStyle.installDefaults(context);
|
||||
}
|
||||
this.style = newStyle;
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs listeners into the viewport.
|
||||
*
|
||||
* @param c a {@code JViewport} object
|
||||
*/
|
||||
protected void installListeners(JComponent c) {
|
||||
c.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls listeners from the viewport.
|
||||
*
|
||||
* @param c a {@code JViewport} object
|
||||
*/
|
||||
protected void uninstallListeners(JComponent c) {
|
||||
c.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls defaults from a viewport.
|
||||
*
|
||||
* @param c a {@code JViewport} object
|
||||
*/
|
||||
protected void uninstallDefaults(JComponent c) {
|
||||
SynthContext context = getContext(c, ENABLED);
|
||||
style.uninstallDefaults(context);
|
||||
context.dispose();
|
||||
style = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SynthContext getContext(JComponent c) {
|
||||
return getContext(c, SynthLookAndFeel.getComponentState(c));
|
||||
}
|
||||
|
||||
private SynthContext getContext(JComponent c, int state) {
|
||||
return SynthContext.getContext(c, style, state);
|
||||
}
|
||||
|
||||
private Region getRegion(JComponent c) {
|
||||
return SynthLookAndFeel.getRegion(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this UI delegate to repaint the specified component.
|
||||
* This method paints the component background, then calls
|
||||
* the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* <p>In general, this method does not need to be overridden by subclasses.
|
||||
* All Look and Feel rendering code should reside in the {@code paint} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
SynthLookAndFeel.update(context, g);
|
||||
context.getPainter().paintViewportBackground(context,
|
||||
g, 0, 0, c.getWidth(), c.getHeight());
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the border. The method is never called,
|
||||
* because the {@code JViewport} class does not support a border.
|
||||
* This implementation does nothing.
|
||||
*
|
||||
* @param context a component context
|
||||
* @param g the {@code Graphics} to paint on
|
||||
* @param x the X coordinate
|
||||
* @param y the Y coordinate
|
||||
* @param w width of the border
|
||||
* @param h height of the border
|
||||
*/
|
||||
@Override
|
||||
public void paintBorder(SynthContext context, Graphics g, int x,
|
||||
int y, int w, int h) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component according to the Look and Feel.
|
||||
* <p>This method is not used by Synth Look and Feel.
|
||||
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
|
||||
*
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @param c the component being painted
|
||||
* @see #paint(SynthContext,Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
SynthContext context = getContext(c);
|
||||
|
||||
paint(context, g);
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the specified component. This implementation does nothing.
|
||||
*
|
||||
* @param context context for the component being painted
|
||||
* @param g the {@code Graphics} object used for painting
|
||||
* @see #update(Graphics,JComponent)
|
||||
*/
|
||||
protected void paint(SynthContext context, Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
|
||||
updateStyle((JComponent)e.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user