|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package javax.swing.plaf.basic; |
|
|
|
import sun.swing.SwingUtilities2; |
|
import sun.swing.DefaultLookup; |
|
import sun.swing.UIAction; |
|
import sun.awt.AppContext; |
|
|
|
import javax.swing.*; |
|
import javax.swing.plaf.*; |
|
import javax.swing.text.View; |
|
|
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
import java.awt.event.KeyEvent; |
|
import java.awt.Component; |
|
import java.awt.Container; |
|
import java.awt.Dimension; |
|
import java.awt.Rectangle; |
|
import java.awt.Insets; |
|
import java.awt.Color; |
|
import java.awt.Graphics; |
|
import java.awt.Font; |
|
import java.awt.FontMetrics; |
|
import java.beans.PropertyChangeEvent; |
|
import java.beans.PropertyChangeListener; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class BasicLabelUI extends LabelUI implements PropertyChangeListener |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected static BasicLabelUI labelUI = new BasicLabelUI(); |
|
private static final Object BASIC_LABEL_UI_KEY = new Object(); |
|
|
|
private Rectangle paintIconR = new Rectangle(); |
|
private Rectangle paintTextR = new Rectangle(); |
|
|
|
static void loadActionMap(LazyActionMap map) { |
|
map.put(new Actions(Actions.PRESS)); |
|
map.put(new Actions(Actions.RELEASE)); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected String layoutCL( |
|
JLabel label, |
|
FontMetrics fontMetrics, |
|
String text, |
|
Icon icon, |
|
Rectangle viewR, |
|
Rectangle iconR, |
|
Rectangle textR) |
|
{ |
|
return SwingUtilities.layoutCompoundLabel( |
|
(JComponent) label, |
|
fontMetrics, |
|
text, |
|
icon, |
|
label.getVerticalAlignment(), |
|
label.getHorizontalAlignment(), |
|
label.getVerticalTextPosition(), |
|
label.getHorizontalTextPosition(), |
|
viewR, |
|
iconR, |
|
textR, |
|
label.getIconTextGap()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) |
|
{ |
|
int mnemIndex = l.getDisplayedMnemonicIndex(); |
|
g.setColor(l.getForeground()); |
|
SwingUtilities2.drawStringUnderlineCharAt(l, g, s, mnemIndex, |
|
textX, textY); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void paintDisabledText(JLabel l, Graphics g, String s, int textX, int textY) |
|
{ |
|
int accChar = l.getDisplayedMnemonicIndex(); |
|
Color background = l.getBackground(); |
|
g.setColor(background.brighter()); |
|
SwingUtilities2.drawStringUnderlineCharAt(l, g, s, accChar, |
|
textX + 1, textY + 1); |
|
g.setColor(background.darker()); |
|
SwingUtilities2.drawStringUnderlineCharAt(l, g, s, accChar, |
|
textX, textY); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void paint(Graphics g, JComponent c) |
|
{ |
|
JLabel label = (JLabel)c; |
|
String text = label.getText(); |
|
Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon(); |
|
|
|
if ((icon == null) && (text == null)) { |
|
return; |
|
} |
|
|
|
FontMetrics fm = SwingUtilities2.getFontMetrics(label, g); |
|
String clippedText = layout(label, fm, c.getWidth(), c.getHeight()); |
|
|
|
if (icon != null) { |
|
icon.paintIcon(c, g, paintIconR.x, paintIconR.y); |
|
} |
|
|
|
if (text != null) { |
|
View v = (View) c.getClientProperty(BasicHTML.propertyKey); |
|
if (v != null) { |
|
v.paint(g, paintTextR); |
|
} else { |
|
int textX = paintTextR.x; |
|
int textY = paintTextR.y + fm.getAscent(); |
|
|
|
if (label.isEnabled()) { |
|
paintEnabledText(label, g, clippedText, textX, textY); |
|
} |
|
else { |
|
paintDisabledText(label, g, clippedText, textX, textY); |
|
} |
|
} |
|
} |
|
} |
|
|
|
private String layout(JLabel label, FontMetrics fm, |
|
int width, int height) { |
|
Insets insets = label.getInsets(null); |
|
String text = label.getText(); |
|
Icon icon = (label.isEnabled()) ? label.getIcon() : |
|
label.getDisabledIcon(); |
|
Rectangle paintViewR = new Rectangle(); |
|
paintViewR.x = insets.left; |
|
paintViewR.y = insets.top; |
|
paintViewR.width = width - (insets.left + insets.right); |
|
paintViewR.height = height - (insets.top + insets.bottom); |
|
paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0; |
|
paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0; |
|
return layoutCL(label, fm, text, icon, paintViewR, paintIconR, |
|
paintTextR); |
|
} |
|
|
|
public Dimension getPreferredSize(JComponent c) |
|
{ |
|
JLabel label = (JLabel)c; |
|
String text = label.getText(); |
|
Icon icon = (label.isEnabled()) ? label.getIcon() : |
|
label.getDisabledIcon(); |
|
Insets insets = label.getInsets(null); |
|
Font font = label.getFont(); |
|
|
|
int dx = insets.left + insets.right; |
|
int dy = insets.top + insets.bottom; |
|
|
|
if ((icon == null) && |
|
((text == null) || |
|
((text != null) && (font == null)))) { |
|
return new Dimension(dx, dy); |
|
} |
|
else if ((text == null) || ((icon != null) && (font == null))) { |
|
return new Dimension(icon.getIconWidth() + dx, |
|
icon.getIconHeight() + dy); |
|
} |
|
else { |
|
FontMetrics fm = label.getFontMetrics(font); |
|
Rectangle iconR = new Rectangle(); |
|
Rectangle textR = new Rectangle(); |
|
Rectangle viewR = new Rectangle(); |
|
|
|
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; |
|
|
|
layoutCL(label, fm, text, icon, viewR, iconR, textR); |
|
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; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public Dimension getMinimumSize(JComponent c) { |
|
Dimension d = getPreferredSize(c); |
|
View v = (View) c.getClientProperty(BasicHTML.propertyKey); |
|
if (v != null) { |
|
d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS); |
|
} |
|
return d; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public Dimension getMaximumSize(JComponent c) { |
|
Dimension d = getPreferredSize(c); |
|
View v = (View) c.getClientProperty(BasicHTML.propertyKey); |
|
if (v != null) { |
|
d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS); |
|
} |
|
return d; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public int getBaseline(JComponent c, int width, int height) { |
|
super.getBaseline(c, width, height); |
|
JLabel label = (JLabel)c; |
|
String text = label.getText(); |
|
if (text == null || "".equals(text) || label.getFont() == null) { |
|
return -1; |
|
} |
|
FontMetrics fm = label.getFontMetrics(label.getFont()); |
|
layout(label, fm, width, height); |
|
return BasicHTML.getBaseline(label, paintTextR.y, fm.getAscent(), |
|
paintTextR.width, paintTextR.height); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Component.BaselineResizeBehavior getBaselineResizeBehavior( |
|
JComponent c) { |
|
super.getBaselineResizeBehavior(c); |
|
if (c.getClientProperty(BasicHTML.propertyKey) != null) { |
|
return Component.BaselineResizeBehavior.OTHER; |
|
} |
|
switch(((JLabel)c).getVerticalAlignment()) { |
|
case JLabel.TOP: |
|
return Component.BaselineResizeBehavior.CONSTANT_ASCENT; |
|
case JLabel.BOTTOM: |
|
return Component.BaselineResizeBehavior.CONSTANT_DESCENT; |
|
case JLabel.CENTER: |
|
return Component.BaselineResizeBehavior.CENTER_OFFSET; |
|
} |
|
return Component.BaselineResizeBehavior.OTHER; |
|
} |
|
|
|
|
|
public void installUI(JComponent c) { |
|
installDefaults((JLabel)c); |
|
installComponents((JLabel)c); |
|
installListeners((JLabel)c); |
|
installKeyboardActions((JLabel)c); |
|
} |
|
|
|
|
|
public void uninstallUI(JComponent c) { |
|
uninstallDefaults((JLabel) c); |
|
uninstallComponents((JLabel) c); |
|
uninstallListeners((JLabel) c); |
|
uninstallKeyboardActions((JLabel) c); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void installDefaults(JLabel c){ |
|
LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground", "Label.font"); |
|
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void installListeners(JLabel c){ |
|
c.addPropertyChangeListener(this); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void installComponents(JLabel c){ |
|
BasicHTML.updateRenderer(c, c.getText()); |
|
c.setInheritsPopupMenu(true); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void installKeyboardActions(JLabel l) { |
|
int dka = l.getDisplayedMnemonic(); |
|
Component lf = l.getLabelFor(); |
|
if ((dka != 0) && (lf != null)) { |
|
LazyActionMap.installLazyActionMap(l, BasicLabelUI.class, |
|
"Label.actionMap"); |
|
InputMap inputMap = SwingUtilities.getUIInputMap |
|
(l, JComponent.WHEN_IN_FOCUSED_WINDOW); |
|
if (inputMap == null) { |
|
inputMap = new ComponentInputMapUIResource(l); |
|
SwingUtilities.replaceUIInputMap(l, |
|
JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap); |
|
} |
|
inputMap.clear(); |
|
inputMap.put(KeyStroke.getKeyStroke(dka, BasicLookAndFeel.getFocusAcceleratorKeyMask(), false), "press"); |
|
} |
|
else { |
|
InputMap inputMap = SwingUtilities.getUIInputMap |
|
(l, JComponent.WHEN_IN_FOCUSED_WINDOW); |
|
if (inputMap != null) { |
|
inputMap.clear(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void uninstallDefaults(JLabel c){ |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void uninstallListeners(JLabel c){ |
|
c.removePropertyChangeListener(this); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void uninstallComponents(JLabel c){ |
|
BasicHTML.updateRenderer(c, ""); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected void uninstallKeyboardActions(JLabel c) { |
|
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, null); |
|
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_IN_FOCUSED_WINDOW, |
|
null); |
|
SwingUtilities.replaceUIActionMap(c, null); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static ComponentUI createUI(JComponent c) { |
|
if (System.getSecurityManager() != null) { |
|
AppContext appContext = AppContext.getAppContext(); |
|
BasicLabelUI safeBasicLabelUI = |
|
(BasicLabelUI) appContext.get(BASIC_LABEL_UI_KEY); |
|
if (safeBasicLabelUI == null) { |
|
safeBasicLabelUI = new BasicLabelUI(); |
|
appContext.put(BASIC_LABEL_UI_KEY, safeBasicLabelUI); |
|
} |
|
return safeBasicLabelUI; |
|
} |
|
return labelUI; |
|
} |
|
|
|
public void propertyChange(PropertyChangeEvent e) { |
|
String name = e.getPropertyName(); |
|
if (name == "text" || "font" == name || "foreground" == name) { |
|
// remove the old html view client property if one |
|
// existed, and install a new one if the text installed |
|
|
|
JLabel lbl = ((JLabel) e.getSource()); |
|
String text = lbl.getText(); |
|
BasicHTML.updateRenderer(lbl, text); |
|
} |
|
else if (name == "labelFor" || name == "displayedMnemonic") { |
|
installKeyboardActions((JLabel) e.getSource()); |
|
} |
|
} |
|
|
|
// When the accelerator is pressed, temporarily make the JLabel |
|
// focusTraversable by registering a WHEN_FOCUSED action for the |
|
// release of the accelerator. Then give it focus so it can |
|
|
|
private static class Actions extends UIAction { |
|
private static final String PRESS = "press"; |
|
private static final String RELEASE = "release"; |
|
|
|
Actions(String key) { |
|
super(key); |
|
} |
|
|
|
public void actionPerformed(ActionEvent e) { |
|
JLabel label = (JLabel)e.getSource(); |
|
String key = getName(); |
|
if (key == PRESS) { |
|
doPress(label); |
|
} |
|
else if (key == RELEASE) { |
|
doRelease(label, e.getActionCommand() != null); |
|
} |
|
} |
|
|
|
private void doPress(JLabel label) { |
|
Component labelFor = label.getLabelFor(); |
|
if (labelFor != null && labelFor.isEnabled()) { |
|
InputMap inputMap = SwingUtilities.getUIInputMap(label, JComponent.WHEN_FOCUSED); |
|
if (inputMap == null) { |
|
inputMap = new InputMapUIResource(); |
|
SwingUtilities.replaceUIInputMap(label, JComponent.WHEN_FOCUSED, inputMap); |
|
} |
|
int dka = label.getDisplayedMnemonic(); |
|
putOnRelease(inputMap, dka, BasicLookAndFeel |
|
.getFocusAcceleratorKeyMask()); |
|
|
|
putOnRelease(inputMap, dka, 0); |
|
|
|
putOnRelease(inputMap, KeyEvent.VK_ALT, 0); |
|
label.requestFocus(); |
|
} |
|
} |
|
|
|
private void doRelease(JLabel label, boolean isCommand) { |
|
Component labelFor = label.getLabelFor(); |
|
if (labelFor != null && labelFor.isEnabled()) { |
|
if (label.hasFocus()) { |
|
InputMap inputMap = SwingUtilities.getUIInputMap(label, |
|
JComponent.WHEN_FOCUSED); |
|
if (inputMap != null) { |
|
|
|
int dka = label.getDisplayedMnemonic(); |
|
removeOnRelease(inputMap, dka, BasicLookAndFeel |
|
.getFocusAcceleratorKeyMask()); |
|
removeOnRelease(inputMap, dka, 0); |
|
removeOnRelease(inputMap, KeyEvent.VK_ALT, 0); |
|
} |
|
inputMap = SwingUtilities.getUIInputMap(label, |
|
JComponent.WHEN_IN_FOCUSED_WINDOW); |
|
if (inputMap == null) { |
|
inputMap = new InputMapUIResource(); |
|
SwingUtilities.replaceUIInputMap(label, |
|
JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap); |
|
} |
|
int dka = label.getDisplayedMnemonic(); |
|
if (isCommand) { |
|
putOnRelease(inputMap, KeyEvent.VK_ALT, 0); |
|
} else { |
|
putOnRelease(inputMap, dka, BasicLookAndFeel |
|
.getFocusAcceleratorKeyMask()); |
|
|
|
putOnRelease(inputMap, dka, 0); |
|
} |
|
if (labelFor instanceof Container && |
|
((Container) labelFor).isFocusCycleRoot()) { |
|
labelFor.requestFocus(); |
|
} else { |
|
SwingUtilities2.compositeRequestFocus(labelFor); |
|
} |
|
} else { |
|
InputMap inputMap = SwingUtilities.getUIInputMap(label, |
|
JComponent.WHEN_IN_FOCUSED_WINDOW); |
|
int dka = label.getDisplayedMnemonic(); |
|
if (inputMap != null) { |
|
if (isCommand) { |
|
removeOnRelease(inputMap, dka, BasicLookAndFeel |
|
.getFocusAcceleratorKeyMask()); |
|
removeOnRelease(inputMap, dka, 0); |
|
} else { |
|
removeOnRelease(inputMap, KeyEvent.VK_ALT, 0); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
private void putOnRelease(InputMap inputMap, int keyCode, int modifiers) { |
|
inputMap.put(KeyStroke.getKeyStroke(keyCode, modifiers, true), |
|
RELEASE); |
|
} |
|
|
|
private void removeOnRelease(InputMap inputMap, int keyCode, int modifiers) { |
|
inputMap.remove(KeyStroke.getKeyStroke(keyCode, modifiers, true)); |
|
} |
|
|
|
} |
|
} |