feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,308 @@
/*
* Copyright (c) 1997, 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.basic;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.*;
import javax.swing.plaf.UIResource;
/**
* JButton object that draws a scaled Arrow in one of the cardinal directions.
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author David Kloba
*/
public class BasicArrowButton extends JButton implements SwingConstants
{
/**
* The direction of the arrow. One of
* {@code SwingConstants.NORTH}, {@code SwingConstants.SOUTH},
* {@code SwingConstants.EAST} or {@code SwingConstants.WEST}.
*/
protected int direction;
private Color shadow;
private Color darkShadow;
private Color highlight;
/**
* Creates a {@code BasicArrowButton} whose arrow
* is drawn in the specified direction and with the specified
* colors.
*
* @param direction the direction of the arrow; one of
* {@code SwingConstants.NORTH}, {@code SwingConstants.SOUTH},
* {@code SwingConstants.EAST} or {@code SwingConstants.WEST}
* @param background the background color of the button
* @param shadow the color of the shadow
* @param darkShadow the color of the dark shadow
* @param highlight the color of the highlight
* @since 1.4
*/
public BasicArrowButton(int direction, Color background, Color shadow,
Color darkShadow, Color highlight) {
super();
setRequestFocusEnabled(false);
setDirection(direction);
setBackground(background);
this.shadow = shadow;
this.darkShadow = darkShadow;
this.highlight = highlight;
}
/**
* Creates a {@code BasicArrowButton} whose arrow
* is drawn in the specified direction.
*
* @param direction the direction of the arrow; one of
* {@code SwingConstants.NORTH}, {@code SwingConstants.SOUTH},
* {@code SwingConstants.EAST} or {@code SwingConstants.WEST}
*/
public BasicArrowButton(int direction) {
this(direction, UIManager.getColor("control"), UIManager.getColor("controlShadow"),
UIManager.getColor("controlDkShadow"), UIManager.getColor("controlLtHighlight"));
}
/**
* Returns the direction of the arrow.
*/
public int getDirection() {
return direction;
}
/**
* Sets the direction of the arrow.
*
* @param direction the direction of the arrow; one of
* of {@code SwingConstants.NORTH},
* {@code SwingConstants.SOUTH},
* {@code SwingConstants.EAST} or {@code SwingConstants.WEST}
*/
public void setDirection(int direction) {
this.direction = direction;
}
public void paint(Graphics g) {
Color origColor;
boolean isPressed, isEnabled;
int w, h, size;
w = getSize().width;
h = getSize().height;
origColor = g.getColor();
isPressed = getModel().isPressed();
isEnabled = isEnabled();
g.setColor(getBackground());
g.fillRect(1, 1, w-2, h-2);
/// Draw the proper Border
if (getBorder() != null && !(getBorder() instanceof UIResource)) {
paintBorder(g);
} else if (isPressed) {
g.setColor(shadow);
g.drawRect(0, 0, w-1, h-1);
} else {
// Using the background color set above
g.drawLine(0, 0, 0, h-1);
g.drawLine(1, 0, w-2, 0);
g.setColor(highlight); // inner 3D border
g.drawLine(1, 1, 1, h-3);
g.drawLine(2, 1, w-3, 1);
g.setColor(shadow); // inner 3D border
g.drawLine(1, h-2, w-2, h-2);
g.drawLine(w-2, 1, w-2, h-3);
g.setColor(darkShadow); // black drop shadow __|
g.drawLine(0, h-1, w-1, h-1);
g.drawLine(w-1, h-1, w-1, 0);
}
// If there's no room to draw arrow, bail
if(h < 5 || w < 5) {
g.setColor(origColor);
return;
}
if (isPressed) {
g.translate(1, 1);
}
// Draw the arrow
size = Math.min((h - 4) / 3, (w - 4) / 3);
size = Math.max(size, 2);
paintTriangle(g, (w - size) / 2, (h - size) / 2,
size, direction, isEnabled);
// Reset the Graphics back to it's original settings
if (isPressed) {
g.translate(-1, -1);
}
g.setColor(origColor);
}
/**
* Returns the preferred size of the {@code BasicArrowButton}.
*
* @return the preferred size
*/
public Dimension getPreferredSize() {
return new Dimension(16, 16);
}
/**
* Returns the minimum size of the {@code BasicArrowButton}.
*
* @return the minimum size
*/
public Dimension getMinimumSize() {
return new Dimension(5, 5);
}
/**
* Returns the maximum size of the {@code BasicArrowButton}.
*
* @return the maximum size
*/
public Dimension getMaximumSize() {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Returns whether the arrow button should get the focus.
* {@code BasicArrowButton}s are used as a child component of
* composite components such as {@code JScrollBar} and
* {@code JComboBox}. Since the composite component typically gets the
* focus, this method is overriden to return {@code false}.
*
* @return {@code false}
*/
public boolean isFocusTraversable() {
return false;
}
/**
* Paints a triangle.
*
* @param g the {@code Graphics} to draw to
* @param x the x coordinate
* @param y the y coordinate
* @param size the size of the triangle to draw
* @param direction the direction in which to draw the arrow;
* one of {@code SwingConstants.NORTH},
* {@code SwingConstants.SOUTH}, {@code SwingConstants.EAST} or
* {@code SwingConstants.WEST}
* @param isEnabled whether or not the arrow is drawn enabled
*/
public void paintTriangle(Graphics g, int x, int y, int size,
int direction, boolean isEnabled) {
Color oldColor = g.getColor();
int mid, i, j;
j = 0;
size = Math.max(size, 2);
mid = (size / 2) - 1;
g.translate(x, y);
if(isEnabled)
g.setColor(darkShadow);
else
g.setColor(shadow);
switch(direction) {
case NORTH:
for(i = 0; i < size; i++) {
g.drawLine(mid-i, i, mid+i, i);
}
if(!isEnabled) {
g.setColor(highlight);
g.drawLine(mid-i+2, i, mid+i, i);
}
break;
case SOUTH:
if(!isEnabled) {
g.translate(1, 1);
g.setColor(highlight);
for(i = size-1; i >= 0; i--) {
g.drawLine(mid-i, j, mid+i, j);
j++;
}
g.translate(-1, -1);
g.setColor(shadow);
}
j = 0;
for(i = size-1; i >= 0; i--) {
g.drawLine(mid-i, j, mid+i, j);
j++;
}
break;
case WEST:
for(i = 0; i < size; i++) {
g.drawLine(i, mid-i, i, mid+i);
}
if(!isEnabled) {
g.setColor(highlight);
g.drawLine(i, mid-i+2, i, mid+i);
}
break;
case EAST:
if(!isEnabled) {
g.translate(1, 1);
g.setColor(highlight);
for(i = size-1; i >= 0; i--) {
g.drawLine(j, mid-i, j, mid+i);
j++;
}
g.translate(-1, -1);
g.setColor(shadow);
}
j = 0;
for(i = size-1; i >= 0; i--) {
g.drawLine(j, mid-i, j, mid+i);
j++;
}
break;
}
g.translate(-x, -y);
g.setColor(oldColor);
}
}

View File

@@ -0,0 +1,602 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.text.JTextComponent;
import java.awt.Component;
import java.awt.Insets;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.Graphics;
import sun.swing.SwingUtilities2;
/**
* Factory object that can vend Borders appropriate for the basic L &amp; F.
* @author Georges Saab
* @author Amy Fowler
*/
public class BasicBorders {
public static Border getButtonBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border buttonBorder = new BorderUIResource.CompoundBorderUIResource(
new BasicBorders.ButtonBorder(
table.getColor("Button.shadow"),
table.getColor("Button.darkShadow"),
table.getColor("Button.light"),
table.getColor("Button.highlight")),
new MarginBorder());
return buttonBorder;
}
public static Border getRadioButtonBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border radioButtonBorder = new BorderUIResource.CompoundBorderUIResource(
new BasicBorders.RadioButtonBorder(
table.getColor("RadioButton.shadow"),
table.getColor("RadioButton.darkShadow"),
table.getColor("RadioButton.light"),
table.getColor("RadioButton.highlight")),
new MarginBorder());
return radioButtonBorder;
}
public static Border getToggleButtonBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
new BasicBorders.ToggleButtonBorder(
table.getColor("ToggleButton.shadow"),
table.getColor("ToggleButton.darkShadow"),
table.getColor("ToggleButton.light"),
table.getColor("ToggleButton.highlight")),
new MarginBorder());
return toggleButtonBorder;
}
public static Border getMenuBarBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border menuBarBorder = new BasicBorders.MenuBarBorder(
table.getColor("MenuBar.shadow"),
table.getColor("MenuBar.highlight")
);
return menuBarBorder;
}
public static Border getSplitPaneBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border splitPaneBorder = new BasicBorders.SplitPaneBorder(
table.getColor("SplitPane.highlight"),
table.getColor("SplitPane.darkShadow"));
return splitPaneBorder;
}
/**
* Returns a border instance for a JSplitPane divider
* @since 1.3
*/
public static Border getSplitPaneDividerBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border splitPaneBorder = new BasicBorders.SplitPaneDividerBorder(
table.getColor("SplitPane.highlight"),
table.getColor("SplitPane.darkShadow"));
return splitPaneBorder;
}
public static Border getTextFieldBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border textFieldBorder = new BasicBorders.FieldBorder(
table.getColor("TextField.shadow"),
table.getColor("TextField.darkShadow"),
table.getColor("TextField.light"),
table.getColor("TextField.highlight"));
return textFieldBorder;
}
public static Border getProgressBarBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border progressBarBorder = new BorderUIResource.LineBorderUIResource(Color.green, 2);
return progressBarBorder;
}
public static Border getInternalFrameBorder() {
UIDefaults table = UIManager.getLookAndFeelDefaults();
Border internalFrameBorder = new BorderUIResource.CompoundBorderUIResource(
new BevelBorder(BevelBorder.RAISED,
table.getColor("InternalFrame.borderLight"),
table.getColor("InternalFrame.borderHighlight"),
table.getColor("InternalFrame.borderDarkShadow"),
table.getColor("InternalFrame.borderShadow")),
BorderFactory.createLineBorder(
table.getColor("InternalFrame.borderColor"), 1));
return internalFrameBorder;
}
/**
* Special thin border for rollover toolbar buttons.
* @since 1.4
*/
public static class RolloverButtonBorder extends ButtonBorder {
public RolloverButtonBorder(Color shadow, Color darkShadow,
Color highlight, Color lightHighlight) {
super(shadow, darkShadow, highlight, lightHighlight);
}
public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Color shade = shadow;
Component p = b.getParent();
if (p != null && p.getBackground().equals(shadow)) {
shade = darkShadow;
}
if ((model.isRollover() && !(model.isPressed() && !model.isArmed())) ||
model.isSelected()) {
Color oldColor = g.getColor();
g.translate(x, y);
if (model.isPressed() && model.isArmed() || model.isSelected()) {
// Draw the pressd button
g.setColor(shade);
g.drawRect(0, 0, w-1, h-1);
g.setColor(lightHighlight);
g.drawLine(w-1, 0, w-1, h-1);
g.drawLine(0, h-1, w-1, h-1);
} else {
// Draw a rollover button
g.setColor(lightHighlight);
g.drawRect(0, 0, w-1, h-1);
g.setColor(shade);
g.drawLine(w-1, 0, w-1, h-1);
g.drawLine(0, h-1, w-1, h-1);
}
g.translate(-x, -y);
g.setColor(oldColor);
}
}
}
/**
* A border which is like a Margin border but it will only honor the margin
* if the margin has been explicitly set by the developer.
*
* Note: This is identical to the package private class
* MetalBorders.RolloverMarginBorder and should probably be consolidated.
*/
static class RolloverMarginBorder extends EmptyBorder {
public RolloverMarginBorder() {
super(3,3,3,3); // hardcoded margin for JLF requirements.
}
public Insets getBorderInsets(Component c, Insets insets) {
Insets margin = null;
if (c instanceof AbstractButton) {
margin = ((AbstractButton)c).getMargin();
}
if (margin == null || margin instanceof UIResource) {
// default margin so replace
insets.left = left;
insets.top = top;
insets.right = right;
insets.bottom = bottom;
} else {
// Margin which has been explicitly set by the user.
insets.left = margin.left;
insets.top = margin.top;
insets.right = margin.right;
insets.bottom = margin.bottom;
}
return insets;
}
}
public static class ButtonBorder extends AbstractBorder implements UIResource {
protected Color shadow;
protected Color darkShadow;
protected Color highlight;
protected Color lightHighlight;
public ButtonBorder(Color shadow, Color darkShadow,
Color highlight, Color lightHighlight) {
this.shadow = shadow;
this.darkShadow = darkShadow;
this.highlight = highlight;
this.lightHighlight = lightHighlight;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
boolean isPressed = false;
boolean isDefault = false;
if (c instanceof AbstractButton) {
AbstractButton b = (AbstractButton)c;
ButtonModel model = b.getModel();
isPressed = model.isPressed() && model.isArmed();
if (c instanceof JButton) {
isDefault = ((JButton)c).isDefaultButton();
}
}
BasicGraphicsUtils.drawBezel(g, x, y, width, height,
isPressed, isDefault, shadow,
darkShadow, highlight, lightHighlight);
}
public Insets getBorderInsets(Component c, Insets insets) {
// leave room for default visual
insets.set(2, 3, 3, 3);
return insets;
}
}
public static class ToggleButtonBorder extends ButtonBorder {
public ToggleButtonBorder(Color shadow, Color darkShadow,
Color highlight, Color lightHighlight) {
super(shadow, darkShadow, highlight, lightHighlight);
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
BasicGraphicsUtils.drawBezel(g, x, y, width, height,
false, false,
shadow, darkShadow,
highlight, lightHighlight);
}
public Insets getBorderInsets(Component c, Insets insets) {
insets.set(2, 2, 2, 2);
return insets;
}
}
public static class RadioButtonBorder extends ButtonBorder {
public RadioButtonBorder(Color shadow, Color darkShadow,
Color highlight, Color lightHighlight) {
super(shadow, darkShadow, highlight, lightHighlight);
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if (c instanceof AbstractButton) {
AbstractButton b = (AbstractButton)c;
ButtonModel model = b.getModel();
if (model.isArmed() && model.isPressed() || model.isSelected()) {
BasicGraphicsUtils.drawLoweredBezel(g, x, y, width, height,
shadow, darkShadow,
highlight, lightHighlight);
} else {
BasicGraphicsUtils.drawBezel(g, x, y, width, height,
false, b.isFocusPainted() && b.hasFocus(),
shadow, darkShadow,
highlight, lightHighlight);
}
} else {
BasicGraphicsUtils.drawBezel(g, x, y, width, height, false, false,
shadow, darkShadow, highlight, lightHighlight);
}
}
public Insets getBorderInsets(Component c, Insets insets) {
insets.set(2, 2, 2, 2);
return insets;
}
}
public static class MenuBarBorder extends AbstractBorder implements UIResource {
private Color shadow;
private Color highlight;
public MenuBarBorder(Color shadow, Color highlight) {
this.shadow = shadow;
this.highlight = highlight;
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Color oldColor = g.getColor();
g.translate(x, y);
g.setColor(shadow);
SwingUtilities2.drawHLine(g, 0, width - 1, height - 2);
g.setColor(highlight);
SwingUtilities2.drawHLine(g, 0, width - 1, height - 1);
g.translate(-x, -y);
g.setColor(oldColor);
}
public Insets getBorderInsets(Component c, Insets insets) {
insets.set(0, 0, 2, 0);
return insets;
}
}
public static class MarginBorder extends AbstractBorder implements UIResource {
public Insets getBorderInsets(Component c, Insets insets) {
Insets margin = null;
//
// Ideally we'd have an interface defined for classes which
// support margins (to avoid this hackery), but we've
// decided against it for simplicity
//
if (c instanceof AbstractButton) {
AbstractButton b = (AbstractButton)c;
margin = b.getMargin();
} else if (c instanceof JToolBar) {
JToolBar t = (JToolBar)c;
margin = t.getMargin();
} else if (c instanceof JTextComponent) {
JTextComponent t = (JTextComponent)c;
margin = t.getMargin();
}
insets.top = margin != null? margin.top : 0;
insets.left = margin != null? margin.left : 0;
insets.bottom = margin != null? margin.bottom : 0;
insets.right = margin != null? margin.right : 0;
return insets;
}
}
public static class FieldBorder extends AbstractBorder implements UIResource {
protected Color shadow;
protected Color darkShadow;
protected Color highlight;
protected Color lightHighlight;
public FieldBorder(Color shadow, Color darkShadow,
Color highlight, Color lightHighlight) {
this.shadow = shadow;
this.highlight = highlight;
this.darkShadow = darkShadow;
this.lightHighlight = lightHighlight;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
BasicGraphicsUtils.drawEtchedRect(g, x, y, width, height,
shadow, darkShadow,
highlight, lightHighlight);
}
public Insets getBorderInsets(Component c, Insets insets) {
Insets margin = null;
if (c instanceof JTextComponent) {
margin = ((JTextComponent)c).getMargin();
}
insets.top = margin != null? 2+margin.top : 2;
insets.left = margin != null? 2+margin.left : 2;
insets.bottom = margin != null? 2+margin.bottom : 2;
insets.right = margin != null? 2+margin.right : 2;
return insets;
}
}
/**
* Draws the border around the divider in a splitpane
* (when BasicSplitPaneUI is used). To get the appropriate effect, this
* needs to be used with a SplitPaneBorder.
*/
static class SplitPaneDividerBorder implements Border, UIResource {
Color highlight;
Color shadow;
SplitPaneDividerBorder(Color highlight, Color shadow) {
this.highlight = highlight;
this.shadow = shadow;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
if (!(c instanceof BasicSplitPaneDivider)) {
return;
}
Component child;
Rectangle cBounds;
JSplitPane splitPane = ((BasicSplitPaneDivider)c).
getBasicSplitPaneUI().getSplitPane();
Dimension size = c.getSize();
child = splitPane.getLeftComponent();
// This is needed for the space between the divider and end of
// splitpane.
g.setColor(c.getBackground());
g.drawRect(x, y, width - 1, height - 1);
if(splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
if(child != null) {
g.setColor(highlight);
g.drawLine(0, 0, 0, size.height);
}
child = splitPane.getRightComponent();
if(child != null) {
g.setColor(shadow);
g.drawLine(size.width - 1, 0, size.width - 1, size.height);
}
} else {
if(child != null) {
g.setColor(highlight);
g.drawLine(0, 0, size.width, 0);
}
child = splitPane.getRightComponent();
if(child != null) {
g.setColor(shadow);
g.drawLine(0, size.height - 1, size.width,
size.height - 1);
}
}
}
public Insets getBorderInsets(Component c) {
Insets insets = new Insets(0,0,0,0);
if (c instanceof BasicSplitPaneDivider) {
BasicSplitPaneUI bspui = ((BasicSplitPaneDivider)c).
getBasicSplitPaneUI();
if (bspui != null) {
JSplitPane splitPane = bspui.getSplitPane();
if (splitPane != null) {
if (splitPane.getOrientation() ==
JSplitPane.HORIZONTAL_SPLIT) {
insets.top = insets.bottom = 0;
insets.left = insets.right = 1;
return insets;
}
// VERTICAL_SPLIT
insets.top = insets.bottom = 1;
insets.left = insets.right = 0;
return insets;
}
}
}
insets.top = insets.bottom = insets.left = insets.right = 1;
return insets;
}
public boolean isBorderOpaque() { return true; }
}
/**
* Draws the border around the splitpane. To work correctly you should
* also install a border on the divider (property SplitPaneDivider.border).
*/
public static class SplitPaneBorder implements Border, UIResource {
protected Color highlight;
protected Color shadow;
public SplitPaneBorder(Color highlight, Color shadow) {
this.highlight = highlight;
this.shadow = shadow;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
if (!(c instanceof JSplitPane)) {
return;
}
// The only tricky part with this border is that the divider is
// not positioned at the top (for horizontal) or left (for vert),
// so this border draws to where the divider is:
// -----------------
// |xxxxxxx xxxxxxx|
// |x --- x|
// |x | | x|
// |x |D| x|
// |x | | x|
// |x --- x|
// |xxxxxxx xxxxxxx|
// -----------------
// The above shows (rather excessively) what this looks like for
// a horizontal orientation. This border then draws the x's, with
// the SplitPaneDividerBorder drawing its own border.
Component child;
Rectangle cBounds;
JSplitPane splitPane = (JSplitPane)c;
child = splitPane.getLeftComponent();
// This is needed for the space between the divider and end of
// splitpane.
g.setColor(c.getBackground());
g.drawRect(x, y, width - 1, height - 1);
if(splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
if(child != null) {
cBounds = child.getBounds();
g.setColor(shadow);
g.drawLine(0, 0, cBounds.width + 1, 0);
g.drawLine(0, 1, 0, cBounds.height + 1);
g.setColor(highlight);
g.drawLine(0, cBounds.height + 1, cBounds.width + 1,
cBounds.height + 1);
}
child = splitPane.getRightComponent();
if(child != null) {
cBounds = child.getBounds();
int maxX = cBounds.x + cBounds.width;
int maxY = cBounds.y + cBounds.height;
g.setColor(shadow);
g.drawLine(cBounds.x - 1, 0, maxX, 0);
g.setColor(highlight);
g.drawLine(cBounds.x - 1, maxY, maxX, maxY);
g.drawLine(maxX, 0, maxX, maxY + 1);
}
} else {
if(child != null) {
cBounds = child.getBounds();
g.setColor(shadow);
g.drawLine(0, 0, cBounds.width + 1, 0);
g.drawLine(0, 1, 0, cBounds.height);
g.setColor(highlight);
g.drawLine(1 + cBounds.width, 0, 1 + cBounds.width,
cBounds.height + 1);
g.drawLine(0, cBounds.height + 1, 0, cBounds.height + 1);
}
child = splitPane.getRightComponent();
if(child != null) {
cBounds = child.getBounds();
int maxX = cBounds.x + cBounds.width;
int maxY = cBounds.y + cBounds.height;
g.setColor(shadow);
g.drawLine(0, cBounds.y - 1, 0, maxY);
g.drawLine(maxX, cBounds.y - 1, maxX, cBounds.y - 1);
g.setColor(highlight);
g.drawLine(0, maxY, cBounds.width + 1, maxY);
g.drawLine(maxX, cBounds.y, maxX, maxY);
}
}
}
public Insets getBorderInsets(Component c) {
return new Insets(1, 1, 1, 1);
}
public boolean isBorderOpaque() { return true; }
}
}

View File

@@ -0,0 +1,327 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.swing.DefaultLookup;
import sun.swing.SwingUtilities2;
import sun.swing.UIAction;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentInputMapUIResource;
/**
* Button Listener
*
* @author Jeff Dinkins
* @author Arnaud Weber (keyboard UI support)
*/
public class BasicButtonListener implements MouseListener, MouseMotionListener,
FocusListener, ChangeListener, PropertyChangeListener
{
private long lastPressedTimestamp = -1;
private boolean shouldDiscardRelease = false;
/**
* Populates Buttons actions.
*/
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.PRESS));
map.put(new Actions(Actions.RELEASE));
}
public BasicButtonListener(AbstractButton b) {
}
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if(prop == AbstractButton.MNEMONIC_CHANGED_PROPERTY) {
updateMnemonicBinding((AbstractButton)e.getSource());
}
else if(prop == AbstractButton.CONTENT_AREA_FILLED_CHANGED_PROPERTY) {
checkOpacity((AbstractButton) e.getSource() );
}
else if(prop == AbstractButton.TEXT_CHANGED_PROPERTY ||
"font" == prop || "foreground" == prop) {
AbstractButton b = (AbstractButton) e.getSource();
BasicHTML.updateRenderer(b, b.getText());
}
}
protected void checkOpacity(AbstractButton b) {
b.setOpaque( b.isContentAreaFilled() );
}
/**
* Register default key actions: pressing space to "click" a
* button and registring the keyboard mnemonic (if any).
*/
public void installKeyboardActions(JComponent c) {
AbstractButton b = (AbstractButton)c;
// Update the mnemonic binding.
updateMnemonicBinding(b);
LazyActionMap.installLazyActionMap(c, BasicButtonListener.class,
"Button.actionMap");
InputMap km = getInputMap(JComponent.WHEN_FOCUSED, c);
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, km);
}
/**
* Unregister's default key actions
*/
public void uninstallKeyboardActions(JComponent c) {
SwingUtilities.replaceUIInputMap(c, JComponent.
WHEN_IN_FOCUSED_WINDOW, null);
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, null);
SwingUtilities.replaceUIActionMap(c, null);
}
/**
* Returns the InputMap for condition <code>condition</code>. Called as
* part of <code>installKeyboardActions</code>.
*/
InputMap getInputMap(int condition, JComponent c) {
if (condition == JComponent.WHEN_FOCUSED) {
BasicButtonUI ui = (BasicButtonUI)BasicLookAndFeel.getUIOfType(
((AbstractButton)c).getUI(), BasicButtonUI.class);
if (ui != null) {
return (InputMap)DefaultLookup.get(
c, ui, ui.getPropertyPrefix() + "focusInputMap");
}
}
return null;
}
/**
* Resets the binding for the mnemonic in the WHEN_IN_FOCUSED_WINDOW
* UI InputMap.
*/
void updateMnemonicBinding(AbstractButton b) {
int m = b.getMnemonic();
if(m != 0) {
InputMap map = SwingUtilities.getUIInputMap(
b, JComponent.WHEN_IN_FOCUSED_WINDOW);
if (map == null) {
map = new ComponentInputMapUIResource(b);
SwingUtilities.replaceUIInputMap(b,
JComponent.WHEN_IN_FOCUSED_WINDOW, map);
}
map.clear();
map.put(KeyStroke.getKeyStroke(m, BasicLookAndFeel.getFocusAcceleratorKeyMask(), false),
"pressed");
map.put(KeyStroke.getKeyStroke(m, SwingUtilities2.setAltGraphMask
(BasicLookAndFeel.getFocusAcceleratorKeyMask()),
false),
"pressed");
map.put(KeyStroke.getKeyStroke(m, BasicLookAndFeel.getFocusAcceleratorKeyMask(), true),
"released");
map.put(KeyStroke.getKeyStroke(m,
SwingUtilities2.setAltGraphMask
(BasicLookAndFeel.getFocusAcceleratorKeyMask()), true),
"released");
map.put(KeyStroke.getKeyStroke(m, 0, true), "released");
}
else {
InputMap map = SwingUtilities.getUIInputMap(b, JComponent.
WHEN_IN_FOCUSED_WINDOW);
if (map != null) {
map.clear();
}
}
}
public void stateChanged(ChangeEvent e) {
AbstractButton b = (AbstractButton) e.getSource();
b.repaint();
}
public void focusGained(FocusEvent e) {
AbstractButton b = (AbstractButton) e.getSource();
if (b instanceof JButton && ((JButton)b).isDefaultCapable()) {
JRootPane root = b.getRootPane();
if (root != null) {
BasicButtonUI ui = (BasicButtonUI)BasicLookAndFeel.getUIOfType(
b.getUI(), BasicButtonUI.class);
if (ui != null && DefaultLookup.getBoolean(b, ui,
ui.getPropertyPrefix() +
"defaultButtonFollowsFocus", true)) {
root.putClientProperty("temporaryDefaultButton", b);
root.setDefaultButton((JButton)b);
root.putClientProperty("temporaryDefaultButton", null);
}
}
}
b.repaint();
}
public void focusLost(FocusEvent e) {
AbstractButton b = (AbstractButton) e.getSource();
JRootPane root = b.getRootPane();
if (root != null) {
JButton initialDefault = (JButton)root.getClientProperty("initialDefaultButton");
if (b != initialDefault) {
BasicButtonUI ui = (BasicButtonUI)BasicLookAndFeel.getUIOfType(
b.getUI(), BasicButtonUI.class);
if (ui != null && DefaultLookup.getBoolean(b, ui,
ui.getPropertyPrefix() +
"defaultButtonFollowsFocus", true)) {
root.setDefaultButton(initialDefault);
}
}
}
ButtonModel model = b.getModel();
model.setPressed(false);
model.setArmed(false);
b.repaint();
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e) ) {
AbstractButton b = (AbstractButton) e.getSource();
if(b.contains(e.getX(), e.getY())) {
long multiClickThreshhold = b.getMultiClickThreshhold();
long lastTime = lastPressedTimestamp;
long currentTime = lastPressedTimestamp = e.getWhen();
if (lastTime != -1 && currentTime - lastTime < multiClickThreshhold) {
shouldDiscardRelease = true;
return;
}
ButtonModel model = b.getModel();
if (!model.isEnabled()) {
// Disabled buttons ignore all input...
return;
}
if (!model.isArmed()) {
// button not armed, should be
model.setArmed(true);
}
model.setPressed(true);
if(!b.hasFocus() && b.isRequestFocusEnabled()) {
b.requestFocus();
}
}
}
}
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
// Support for multiClickThreshhold
if (shouldDiscardRelease) {
shouldDiscardRelease = false;
return;
}
AbstractButton b = (AbstractButton) e.getSource();
ButtonModel model = b.getModel();
model.setPressed(false);
model.setArmed(false);
}
}
public void mouseEntered(MouseEvent e) {
AbstractButton b = (AbstractButton) e.getSource();
ButtonModel model = b.getModel();
if (b.isRolloverEnabled() && !SwingUtilities.isLeftMouseButton(e)) {
model.setRollover(true);
}
if (model.isPressed())
model.setArmed(true);
}
public void mouseExited(MouseEvent e) {
AbstractButton b = (AbstractButton) e.getSource();
ButtonModel model = b.getModel();
if(b.isRolloverEnabled()) {
model.setRollover(false);
}
model.setArmed(false);
}
/**
* Actions for Buttons. Two types of action are supported:
* pressed: Moves the button to a pressed state
* released: Disarms the button.
*/
private static class Actions extends UIAction {
private static final String PRESS = "pressed";
private static final String RELEASE = "released";
Actions(String name) {
super(name);
}
public void actionPerformed(ActionEvent e) {
AbstractButton b = (AbstractButton)e.getSource();
String key = getName();
if (key == PRESS) {
ButtonModel model = b.getModel();
model.setArmed(true);
model.setPressed(true);
if(!b.hasFocus()) {
b.requestFocus();
}
}
else if (key == RELEASE) {
ButtonModel model = b.getModel();
model.setPressed(false);
model.setArmed(false);
}
}
public boolean isEnabled(Object sender) {
if(sender != null && (sender instanceof AbstractButton) &&
!((AbstractButton)sender).getModel().isEnabled()) {
return false;
} else {
return true;
}
}
}
}

View File

@@ -0,0 +1,471 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.swing.SwingUtilities2;
import sun.awt.AppContext;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.View;
/**
* BasicButton implementation
*
* @author Jeff Dinkins
*/
public class BasicButtonUI extends ButtonUI{
// Visual constants
// NOTE: This is not used or set any where. Were we allowed to remove
// fields, this would be removed.
protected int defaultTextIconGap;
// Amount to offset text, the value of this comes from
// defaultTextShiftOffset once setTextShiftOffset has been invoked.
private int shiftOffset = 0;
// Value that is set in shiftOffset once setTextShiftOffset has been
// invoked. The value of this comes from the defaults table.
protected int defaultTextShiftOffset;
private final static String propertyPrefix = "Button" + ".";
private static final Object BASIC_BUTTON_UI_KEY = new Object();
// ********************************
// Create PLAF
// ********************************
public static ComponentUI createUI(JComponent c) {
AppContext appContext = AppContext.getAppContext();
BasicButtonUI buttonUI =
(BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY);
if (buttonUI == null) {
buttonUI = new BasicButtonUI();
appContext.put(BASIC_BUTTON_UI_KEY, buttonUI);
}
return buttonUI;
}
protected String getPropertyPrefix() {
return propertyPrefix;
}
// ********************************
// Install PLAF
// ********************************
public void installUI(JComponent c) {
installDefaults((AbstractButton) c);
installListeners((AbstractButton) c);
installKeyboardActions((AbstractButton) c);
BasicHTML.updateRenderer(c, ((AbstractButton) c).getText());
}
protected void installDefaults(AbstractButton b) {
// load shared instance defaults
String pp = getPropertyPrefix();
defaultTextShiftOffset = UIManager.getInt(pp + "textShiftOffset");
// set the following defaults on the button
if (b.isContentAreaFilled()) {
LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
} else {
LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
}
if(b.getMargin() == null || (b.getMargin() instanceof UIResource)) {
b.setMargin(UIManager.getInsets(pp + "margin"));
}
LookAndFeel.installColorsAndFont(b, pp + "background",
pp + "foreground", pp + "font");
LookAndFeel.installBorder(b, pp + "border");
Object rollover = UIManager.get(pp + "rollover");
if (rollover != null) {
LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
}
LookAndFeel.installProperty(b, "iconTextGap", Integer.valueOf(4));
}
protected void installListeners(AbstractButton b) {
BasicButtonListener listener = createButtonListener(b);
if(listener != null) {
b.addMouseListener(listener);
b.addMouseMotionListener(listener);
b.addFocusListener(listener);
b.addPropertyChangeListener(listener);
b.addChangeListener(listener);
}
}
protected void installKeyboardActions(AbstractButton b){
BasicButtonListener listener = getButtonListener(b);
if(listener != null) {
listener.installKeyboardActions(b);
}
}
// ********************************
// Uninstall PLAF
// ********************************
public void uninstallUI(JComponent c) {
uninstallKeyboardActions((AbstractButton) c);
uninstallListeners((AbstractButton) c);
uninstallDefaults((AbstractButton) c);
BasicHTML.updateRenderer(c, "");
}
protected void uninstallKeyboardActions(AbstractButton b) {
BasicButtonListener listener = getButtonListener(b);
if(listener != null) {
listener.uninstallKeyboardActions(b);
}
}
protected void uninstallListeners(AbstractButton b) {
BasicButtonListener listener = getButtonListener(b);
if(listener != null) {
b.removeMouseListener(listener);
b.removeMouseMotionListener(listener);
b.removeFocusListener(listener);
b.removeChangeListener(listener);
b.removePropertyChangeListener(listener);
}
}
protected void uninstallDefaults(AbstractButton b) {
LookAndFeel.uninstallBorder(b);
}
// ********************************
// Create Listeners
// ********************************
protected BasicButtonListener createButtonListener(AbstractButton b) {
return new BasicButtonListener(b);
}
public int getDefaultTextIconGap(AbstractButton b) {
return defaultTextIconGap;
}
/* These rectangles/insets are allocated once for all
* ButtonUI.paint() calls. Re-using rectangles rather than
* allocating them in each paint call substantially reduced the time
* it took paint to run. Obviously, this method can't be re-entered.
*/
private static Rectangle viewRect = new Rectangle();
private static Rectangle textRect = new Rectangle();
private static Rectangle iconRect = new Rectangle();
// ********************************
// Paint Methods
// ********************************
public void paint(Graphics g, JComponent c)
{
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
String text = layout(b, SwingUtilities2.getFontMetrics(b, g),
b.getWidth(), b.getHeight());
clearTextShiftOffset();
// perform UI specific press action, e.g. Windows L&F shifts text
if (model.isArmed() && model.isPressed()) {
paintButtonPressed(g,b);
}
// Paint the Icon
if(b.getIcon() != null) {
paintIcon(g,c,iconRect);
}
if (text != null && !text.equals("")){
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, textRect);
} else {
paintText(g, b, textRect, text);
}
}
if (b.isFocusPainted() && b.hasFocus()) {
// paint UI specific focus
paintFocus(g,b,viewRect,textRect,iconRect);
}
}
protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect){
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Icon icon = b.getIcon();
Icon tmpIcon = null;
if(icon == null) {
return;
}
Icon selectedIcon = null;
/* the fallback icon should be based on the selected state */
if (model.isSelected()) {
selectedIcon = b.getSelectedIcon();
if (selectedIcon != null) {
icon = selectedIcon;
}
}
if(!model.isEnabled()) {
if(model.isSelected()) {
tmpIcon = b.getDisabledSelectedIcon();
if (tmpIcon == null) {
tmpIcon = selectedIcon;
}
}
if (tmpIcon == null) {
tmpIcon = b.getDisabledIcon();
}
} else if(model.isPressed() && model.isArmed()) {
tmpIcon = b.getPressedIcon();
if(tmpIcon != null) {
// revert back to 0 offset
clearTextShiftOffset();
}
} else if(b.isRolloverEnabled() && model.isRollover()) {
if(model.isSelected()) {
tmpIcon = b.getRolloverSelectedIcon();
if (tmpIcon == null) {
tmpIcon = selectedIcon;
}
}
if (tmpIcon == null) {
tmpIcon = b.getRolloverIcon();
}
}
if(tmpIcon != null) {
icon = tmpIcon;
}
if(model.isPressed() && model.isArmed()) {
icon.paintIcon(c, g, iconRect.x + getTextShiftOffset(),
iconRect.y + getTextShiftOffset());
} else {
icon.paintIcon(c, g, iconRect.x, iconRect.y);
}
}
/**
* As of Java 2 platform v 1.4 this method should not be used or overriden.
* Use the paintText method which takes the AbstractButton argument.
*/
protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
int mnemonicIndex = b.getDisplayedMnemonicIndex();
/* Draw the Text */
if(model.isEnabled()) {
/*** paint the text normally */
g.setColor(b.getForeground());
SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
textRect.x + getTextShiftOffset(),
textRect.y + fm.getAscent() + getTextShiftOffset());
}
else {
/*** paint the text disabled ***/
g.setColor(b.getBackground().brighter());
SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
textRect.x, textRect.y + fm.getAscent());
g.setColor(b.getBackground().darker());
SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
textRect.x - 1, textRect.y + fm.getAscent() - 1);
}
}
/**
* Method which renders the text of the current button.
* <p>
* @param g Graphics context
* @param b Current button to render
* @param textRect Bounding rectangle to render the text.
* @param text String to render
* @since 1.4
*/
protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
paintText(g, (JComponent)b, textRect, text);
}
// Method signature defined here overriden in subclasses.
// Perhaps this class should be abstract?
protected void paintFocus(Graphics g, AbstractButton b,
Rectangle viewRect, Rectangle textRect, Rectangle iconRect){
}
protected void paintButtonPressed(Graphics g, AbstractButton b){
}
protected void clearTextShiftOffset(){
this.shiftOffset = 0;
}
protected void setTextShiftOffset(){
this.shiftOffset = defaultTextShiftOffset;
}
protected int getTextShiftOffset() {
return shiftOffset;
}
// ********************************
// Layout Methods
// ********************************
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 getPreferredSize(JComponent c) {
AbstractButton b = (AbstractButton)c;
return BasicGraphicsUtils.getPreferredButtonSize(b, b.getIconTextGap());
}
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;
}
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
AbstractButton b = (AbstractButton)c;
String text = b.getText();
if (text == null || "".equals(text)) {
return -1;
}
FontMetrics fm = b.getFontMetrics(b.getFont());
layout(b, fm, width, height);
return BasicHTML.getBaseline(b, textRect.y, fm.getAscent(),
textRect.width, textRect.height);
}
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public Component.BaselineResizeBehavior getBaselineResizeBehavior(
JComponent c) {
super.getBaselineResizeBehavior(c);
if (c.getClientProperty(BasicHTML.propertyKey) != null) {
return Component.BaselineResizeBehavior.OTHER;
}
switch(((AbstractButton)c).getVerticalAlignment()) {
case AbstractButton.TOP:
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
case AbstractButton.BOTTOM:
return Component.BaselineResizeBehavior.CONSTANT_DESCENT;
case AbstractButton.CENTER:
return Component.BaselineResizeBehavior.CENTER_OFFSET;
}
return Component.BaselineResizeBehavior.OTHER;
}
private String layout(AbstractButton b, FontMetrics fm,
int width, int height) {
Insets i = b.getInsets();
viewRect.x = i.left;
viewRect.y = i.top;
viewRect.width = width - (i.right + viewRect.x);
viewRect.height = height - (i.bottom + viewRect.y);
textRect.x = textRect.y = textRect.width = textRect.height = 0;
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
// layout the text and icon
return SwingUtilities.layoutCompoundLabel(
b, fm, b.getText(), b.getIcon(),
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect,
b.getText() == null ? 0 : b.getIconTextGap());
}
/**
* Returns the ButtonListener for the passed in Button, or null if one
* could not be found.
*/
private BasicButtonListener getButtonListener(AbstractButton b) {
MouseMotionListener[] listeners = b.getMouseMotionListeners();
if (listeners != null) {
for (MouseMotionListener listener : listeners) {
if (listener instanceof BasicButtonListener) {
return (BasicButtonListener) listener;
}
}
}
return null;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 1997, 2001, 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.basic;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.border.*;
import java.io.Serializable;
/**
* BasicCheckboxMenuItem implementation
*
* @author Georges Saab
* @author David Karlton
* @author Arnaud Weber
*/
public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI {
public static ComponentUI createUI(JComponent c) {
return new BasicCheckBoxMenuItemUI();
}
protected String getPropertyPrefix() {
return "CheckBoxMenuItem";
}
public void processMouseEvent(JMenuItem item,MouseEvent e,MenuElement path[],MenuSelectionManager manager) {
Point p = e.getPoint();
if(p.x >= 0 && p.x < item.getWidth() &&
p.y >= 0 && p.y < item.getHeight()) {
if(e.getID() == MouseEvent.MOUSE_RELEASED) {
manager.clearSelectedPath();
item.doClick(0);
} else
manager.setSelectedPath(path);
} else if(item.getModel().isArmed()) {
MenuElement newPath[] = new MenuElement[path.length-1];
int i,c;
for(i=0,c=path.length-1;i<c;i++)
newPath[i] = path[i];
manager.setSelectedPath(newPath);
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.awt.AppContext;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.*;
import java.io.Serializable;
/**
* CheckboxUI implementation for BasicCheckboxUI
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Jeff Dinkins
*/
public class BasicCheckBoxUI extends BasicRadioButtonUI {
private static final Object BASIC_CHECK_BOX_UI_KEY = new Object();
private final static String propertyPrefix = "CheckBox" + ".";
// ********************************
// Create PLAF
// ********************************
public static ComponentUI createUI(JComponent b) {
AppContext appContext = AppContext.getAppContext();
BasicCheckBoxUI checkboxUI =
(BasicCheckBoxUI) appContext.get(BASIC_CHECK_BOX_UI_KEY);
if (checkboxUI == null) {
checkboxUI = new BasicCheckBoxUI();
appContext.put(BASIC_CHECK_BOX_UI_KEY, checkboxUI);
}
return checkboxUI;
}
public String getPropertyPrefix() {
return propertyPrefix;
}
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.*;
import javax.swing.colorchooser.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import sun.swing.DefaultLookup;
/**
* Provides the basic look and feel for a JColorChooser.
* <p>
* @author Tom Santos
* @author Steve Wilson
*/
public class BasicColorChooserUI extends ColorChooserUI
{
/**
* JColorChooser this BasicColorChooserUI is installed on.
*
* @since 1.5
*/
protected JColorChooser chooser;
JTabbedPane tabbedPane;
JPanel singlePanel;
JPanel previewPanelHolder;
JComponent previewPanel;
boolean isMultiPanel = false;
private static TransferHandler defaultTransferHandler = new ColorTransferHandler();
protected AbstractColorChooserPanel[] defaultChoosers;
protected ChangeListener previewListener;
protected PropertyChangeListener propertyChangeListener;
private Handler handler;
public static ComponentUI createUI(JComponent c) {
return new BasicColorChooserUI();
}
protected AbstractColorChooserPanel[] createDefaultChoosers() {
AbstractColorChooserPanel[] panels = ColorChooserComponentFactory.getDefaultChooserPanels();
return panels;
}
protected void uninstallDefaultChoosers() {
AbstractColorChooserPanel[] choosers = chooser.getChooserPanels();
for( int i = 0 ; i < choosers.length; i++) {
chooser.removeChooserPanel( choosers[i] );
}
}
public void installUI( JComponent c ) {
chooser = (JColorChooser)c;
super.installUI( c );
installDefaults();
installListeners();
tabbedPane = new JTabbedPane();
tabbedPane.setName("ColorChooser.tabPane");
tabbedPane.setInheritsPopupMenu(true);
tabbedPane.getAccessibleContext().setAccessibleDescription(tabbedPane.getName());
singlePanel = new JPanel(new CenterLayout());
singlePanel.setName("ColorChooser.panel");
singlePanel.setInheritsPopupMenu(true);
chooser.setLayout( new BorderLayout() );
defaultChoosers = createDefaultChoosers();
chooser.setChooserPanels(defaultChoosers);
previewPanelHolder = new JPanel(new CenterLayout());
previewPanelHolder.setName("ColorChooser.previewPanelHolder");
if (DefaultLookup.getBoolean(chooser, this,
"ColorChooser.showPreviewPanelText", true)) {
String previewString = UIManager.getString(
"ColorChooser.previewText", chooser.getLocale());
previewPanelHolder.setBorder(new TitledBorder(previewString));
}
previewPanelHolder.setInheritsPopupMenu(true);
installPreviewPanel();
chooser.applyComponentOrientation(c.getComponentOrientation());
}
public void uninstallUI( JComponent c ) {
chooser.remove(tabbedPane);
chooser.remove(singlePanel);
chooser.remove(previewPanelHolder);
uninstallDefaultChoosers();
uninstallListeners();
uninstallPreviewPanel();
uninstallDefaults();
previewPanelHolder = null;
previewPanel = null;
defaultChoosers = null;
chooser = null;
tabbedPane = null;
handler = null;
}
protected void installPreviewPanel() {
JComponent previewPanel = this.chooser.getPreviewPanel();
if (previewPanel == null) {
previewPanel = ColorChooserComponentFactory.getPreviewPanel();
}
else if (JPanel.class.equals(previewPanel.getClass()) && (0 == previewPanel.getComponentCount())) {
previewPanel = null;
}
this.previewPanel = previewPanel;
if (previewPanel != null) {
chooser.add(previewPanelHolder, BorderLayout.SOUTH);
previewPanel.setForeground(chooser.getColor());
previewPanelHolder.add(previewPanel);
previewPanel.addMouseListener(getHandler());
previewPanel.setInheritsPopupMenu(true);
}
}
/**
* Removes installed preview panel from the UI delegate.
*
* @since 1.7
*/
protected void uninstallPreviewPanel() {
if (this.previewPanel != null) {
this.previewPanel.removeMouseListener(getHandler());
this.previewPanelHolder.remove(this.previewPanel);
}
this.chooser.remove(this.previewPanelHolder);
}
protected void installDefaults() {
LookAndFeel.installColorsAndFont(chooser, "ColorChooser.background",
"ColorChooser.foreground",
"ColorChooser.font");
LookAndFeel.installProperty(chooser, "opaque", Boolean.TRUE);
TransferHandler th = chooser.getTransferHandler();
if (th == null || th instanceof UIResource) {
chooser.setTransferHandler(defaultTransferHandler);
}
}
protected void uninstallDefaults() {
if (chooser.getTransferHandler() instanceof UIResource) {
chooser.setTransferHandler(null);
}
}
protected void installListeners() {
propertyChangeListener = createPropertyChangeListener();
chooser.addPropertyChangeListener( propertyChangeListener );
previewListener = getHandler();
chooser.getSelectionModel().addChangeListener(previewListener);
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler();
}
return handler;
}
protected PropertyChangeListener createPropertyChangeListener() {
return getHandler();
}
protected void uninstallListeners() {
chooser.removePropertyChangeListener( propertyChangeListener );
chooser.getSelectionModel().removeChangeListener(previewListener);
previewListener = null;
}
private void selectionChanged(ColorSelectionModel model) {
JComponent previewPanel = this.chooser.getPreviewPanel();
if (previewPanel != null) {
previewPanel.setForeground(model.getSelectedColor());
previewPanel.repaint();
}
AbstractColorChooserPanel[] panels = this.chooser.getChooserPanels();
if (panels != null) {
for (AbstractColorChooserPanel panel : panels) {
if (panel != null) {
panel.updateChooser();
}
}
}
}
private class Handler implements ChangeListener, MouseListener,
PropertyChangeListener {
//
// ChangeListener
//
public void stateChanged(ChangeEvent evt) {
selectionChanged((ColorSelectionModel) evt.getSource());
}
//
// MouseListener
public void mousePressed(MouseEvent evt) {
if (chooser.getDragEnabled()) {
TransferHandler th = chooser.getTransferHandler();
th.exportAsDrag(chooser, evt, TransferHandler.COPY);
}
}
public void mouseReleased(MouseEvent evt) {}
public void mouseClicked(MouseEvent evt) {}
public void mouseEntered(MouseEvent evt) {}
public void mouseExited(MouseEvent evt) {}
//
// PropertyChangeListener
//
public void propertyChange(PropertyChangeEvent evt) {
String prop = evt.getPropertyName();
if (prop == JColorChooser.CHOOSER_PANELS_PROPERTY) {
AbstractColorChooserPanel[] oldPanels =
(AbstractColorChooserPanel[])evt.getOldValue();
AbstractColorChooserPanel[] newPanels =
(AbstractColorChooserPanel[])evt.getNewValue();
for (int i = 0; i < oldPanels.length; i++) { // remove old panels
Container wrapper = oldPanels[i].getParent();
if (wrapper != null) {
Container parent = wrapper.getParent();
if (parent != null)
parent.remove(wrapper); // remove from hierarchy
oldPanels[i].uninstallChooserPanel(chooser); // uninstall
}
}
int numNewPanels = newPanels.length;
if (numNewPanels == 0) { // removed all panels and added none
chooser.remove(tabbedPane);
return;
}
else if (numNewPanels == 1) { // one panel case
chooser.remove(tabbedPane);
JPanel centerWrapper = new JPanel( new CenterLayout() );
centerWrapper.setInheritsPopupMenu(true);
centerWrapper.add(newPanels[0]);
singlePanel.add(centerWrapper, BorderLayout.CENTER);
chooser.add(singlePanel);
}
else { // multi-panel case
if ( oldPanels.length < 2 ) {// moving from single to multiple
chooser.remove(singlePanel);
chooser.add(tabbedPane, BorderLayout.CENTER);
}
for (int i = 0; i < newPanels.length; i++) {
JPanel centerWrapper = new JPanel( new CenterLayout() );
centerWrapper.setInheritsPopupMenu(true);
String name = newPanels[i].getDisplayName();
int mnemonic = newPanels[i].getMnemonic();
centerWrapper.add(newPanels[i]);
tabbedPane.addTab(name, centerWrapper);
if (mnemonic > 0) {
tabbedPane.setMnemonicAt(i, mnemonic);
int index = newPanels[i].getDisplayedMnemonicIndex();
if (index >= 0) {
tabbedPane.setDisplayedMnemonicIndexAt(i, index);
}
}
}
}
chooser.applyComponentOrientation(chooser.getComponentOrientation());
for (int i = 0; i < newPanels.length; i++) {
newPanels[i].installChooserPanel(chooser);
}
}
else if (prop == JColorChooser.PREVIEW_PANEL_PROPERTY) {
uninstallPreviewPanel();
installPreviewPanel();
}
else if (prop == JColorChooser.SELECTION_MODEL_PROPERTY) {
ColorSelectionModel oldModel = (ColorSelectionModel) evt.getOldValue();
oldModel.removeChangeListener(previewListener);
ColorSelectionModel newModel = (ColorSelectionModel) evt.getNewValue();
newModel.addChangeListener(previewListener);
selectionChanged(newModel);
}
else if (prop == "componentOrientation") {
ComponentOrientation o =
(ComponentOrientation)evt.getNewValue();
JColorChooser cc = (JColorChooser)evt.getSource();
if (o != (ComponentOrientation)evt.getOldValue()) {
cc.applyComponentOrientation(o);
cc.updateUI();
}
}
}
}
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of {@code BasicColorChooserUI}.
*/
public class PropertyHandler implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
getHandler().propertyChange(e);
}
}
static class ColorTransferHandler extends TransferHandler implements UIResource {
ColorTransferHandler() {
super("color");
}
}
}

View File

@@ -0,0 +1,172 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.ComboBoxEditor;
import javax.swing.JTextField;
import javax.swing.border.Border;
import java.awt.Component;
import java.awt.event.*;
import java.lang.reflect.Method;
import sun.reflect.misc.MethodUtil;
/**
* The default editor for editable combo boxes. The editor is implemented as a JTextField.
*
* @author Arnaud Weber
* @author Mark Davidson
*/
public class BasicComboBoxEditor implements ComboBoxEditor,FocusListener {
protected JTextField editor;
private Object oldValue;
public BasicComboBoxEditor() {
editor = createEditorComponent();
}
public Component getEditorComponent() {
return editor;
}
/**
* Creates the internal editor component. Override this to provide
* a custom implementation.
*
* @return a new editor component
* @since 1.6
*/
protected JTextField createEditorComponent() {
JTextField editor = new BorderlessTextField("",9);
editor.setBorder(null);
return editor;
}
/**
* Sets the item that should be edited.
*
* @param anObject the displayed value of the editor
*/
public void setItem(Object anObject) {
String text;
if ( anObject != null ) {
text = anObject.toString();
if (text == null) {
text = "";
}
oldValue = anObject;
} else {
text = "";
}
// workaround for 4530952
if (! text.equals(editor.getText())) {
editor.setText(text);
}
}
public Object getItem() {
Object newValue = editor.getText();
if (oldValue != null && !(oldValue instanceof String)) {
// The original value is not a string. Should return the value in it's
// original type.
if (newValue.equals(oldValue.toString())) {
return oldValue;
} else {
// Must take the value from the editor and get the value and cast it to the new type.
Class<?> cls = oldValue.getClass();
try {
Method method = MethodUtil.getMethod(cls, "valueOf", new Class[]{String.class});
newValue = MethodUtil.invoke(method, oldValue, new Object[] { editor.getText()});
} catch (Exception ex) {
// Fail silently and return the newValue (a String object)
}
}
}
return newValue;
}
public void selectAll() {
editor.selectAll();
editor.requestFocus();
}
// This used to do something but now it doesn't. It couldn't be
// removed because it would be an API change to do so.
public void focusGained(FocusEvent e) {}
// This used to do something but now it doesn't. It couldn't be
// removed because it would be an API change to do so.
public void focusLost(FocusEvent e) {}
public void addActionListener(ActionListener l) {
editor.addActionListener(l);
}
public void removeActionListener(ActionListener l) {
editor.removeActionListener(l);
}
static class BorderlessTextField extends JTextField {
public BorderlessTextField(String value,int n) {
super(value,n);
}
// workaround for 4530952
public void setText(String s) {
if (getText().equals(s)) {
return;
}
super.setText(s);
}
public void setBorder(Border b) {
if (!(b instanceof UIResource)) {
super.setBorder(b);
}
}
}
/**
* A subclass of BasicComboBoxEditor that implements UIResource.
* BasicComboBoxEditor doesn't implement UIResource
* directly so that applications can safely override the
* cellRenderer property with BasicListCellRenderer subclasses.
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*/
public static class UIResource extends BasicComboBoxEditor
implements javax.swing.plaf.UIResource {
}
}

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.*;
import java.io.Serializable;
/**
* ComboBox renderer
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Arnaud Weber
*/
public class BasicComboBoxRenderer extends JLabel
implements ListCellRenderer, Serializable {
/**
* An empty <code>Border</code>. This field might not be used. To change the
* <code>Border</code> used by this renderer directly set it using
* the <code>setBorder</code> method.
*/
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
private final static Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
public BasicComboBoxRenderer() {
super();
setOpaque(true);
setBorder(getNoFocusBorder());
}
private static Border getNoFocusBorder() {
if (System.getSecurityManager() != null) {
return SAFE_NO_FOCUS_BORDER;
} else {
return noFocusBorder;
}
}
public Dimension getPreferredSize() {
Dimension size;
if ((this.getText() == null) || (this.getText().equals( "" ))) {
setText( " " );
size = super.getPreferredSize();
setText( "" );
}
else {
size = super.getPreferredSize();
}
return size;
}
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
/**if (isSelected) {
setBackground(UIManager.getColor("ComboBox.selectionBackground"));
setForeground(UIManager.getColor("ComboBox.selectionForeground"));
} else {
setBackground(UIManager.getColor("ComboBox.background"));
setForeground(UIManager.getColor("ComboBox.foreground"));
}**/
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setFont(list.getFont());
if (value instanceof Icon) {
setIcon((Icon)value);
}
else {
setText((value == null) ? "" : value.toString());
}
return this;
}
/**
* A subclass of BasicComboBoxRenderer that implements UIResource.
* BasicComboBoxRenderer doesn't implement UIResource
* directly so that applications can safely override the
* cellRenderer property with BasicListCellRenderer subclasses.
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*/
public static class UIResource extends BasicComboBoxRenderer implements javax.swing.plaf.UIResource {
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,296 @@
/*
* Copyright (c) 1997, 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.basic;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.beans.*;
/**
* Basic L&amp;F for a minimized window on a desktop.
*
* @author David Kloba
* @author Steve Wilson
* @author Rich Schiavi
*/
public class BasicDesktopIconUI extends DesktopIconUI {
protected JInternalFrame.JDesktopIcon desktopIcon;
protected JInternalFrame frame;
/**
* The title pane component used in the desktop icon.
*
* @since 1.5
*/
protected JComponent iconPane;
MouseInputListener mouseInputListener;
public static ComponentUI createUI(JComponent c) {
return new BasicDesktopIconUI();
}
public BasicDesktopIconUI() {
}
public void installUI(JComponent c) {
desktopIcon = (JInternalFrame.JDesktopIcon)c;
frame = desktopIcon.getInternalFrame();
installDefaults();
installComponents();
// Update icon layout if frame is already iconified
JInternalFrame f = desktopIcon.getInternalFrame();
if (f.isIcon() && f.getParent() == null) {
JDesktopPane desktop = desktopIcon.getDesktopPane();
if (desktop != null) {
DesktopManager desktopManager = desktop.getDesktopManager();
if (desktopManager instanceof DefaultDesktopManager) {
desktopManager.iconifyFrame(f);
}
}
}
installListeners();
JLayeredPane.putLayer(desktopIcon, JLayeredPane.getLayer(frame));
}
public void uninstallUI(JComponent c) {
uninstallDefaults();
uninstallComponents();
// Force future UI to relayout icon
JInternalFrame f = desktopIcon.getInternalFrame();
if (f.isIcon()) {
JDesktopPane desktop = desktopIcon.getDesktopPane();
if (desktop != null) {
DesktopManager desktopManager = desktop.getDesktopManager();
if (desktopManager instanceof DefaultDesktopManager) {
// This will cause DefaultDesktopManager to layout the icon
f.putClientProperty("wasIconOnce", null);
// Move aside to allow fresh layout of all icons
desktopIcon.setLocation(Integer.MIN_VALUE, 0);
}
}
}
uninstallListeners();
frame = null;
desktopIcon = null;
}
protected void installComponents() {
iconPane = new BasicInternalFrameTitlePane(frame);
desktopIcon.setLayout(new BorderLayout());
desktopIcon.add(iconPane, BorderLayout.CENTER);
}
protected void uninstallComponents() {
desktopIcon.remove(iconPane);
desktopIcon.setLayout(null);
iconPane = null;
}
protected void installListeners() {
mouseInputListener = createMouseInputListener();
desktopIcon.addMouseMotionListener(mouseInputListener);
desktopIcon.addMouseListener(mouseInputListener);
}
protected void uninstallListeners() {
desktopIcon.removeMouseMotionListener(mouseInputListener);
desktopIcon.removeMouseListener(mouseInputListener);
mouseInputListener = null;
}
protected void installDefaults() {
LookAndFeel.installBorder(desktopIcon, "DesktopIcon.border");
LookAndFeel.installProperty(desktopIcon, "opaque", Boolean.TRUE);
}
protected void uninstallDefaults() {
LookAndFeel.uninstallBorder(desktopIcon);
}
protected MouseInputListener createMouseInputListener() {
return new MouseInputHandler();
}
public Dimension getPreferredSize(JComponent c) {
return desktopIcon.getLayout().preferredLayoutSize(desktopIcon);
}
public Dimension getMinimumSize(JComponent c) {
Dimension dim = new Dimension(iconPane.getMinimumSize());
Border border = frame.getBorder();
if (border != null) {
dim.height += border.getBorderInsets(frame).bottom +
border.getBorderInsets(frame).top;
}
return dim;
}
/**
* Desktop icons can not be resized. Therefore, we should always
* return the minimum size of the desktop icon.
*
* @see #getMinimumSize
*/
public Dimension getMaximumSize(JComponent c){
return iconPane.getMaximumSize();
}
public Insets getInsets(JComponent c) {
JInternalFrame iframe = desktopIcon.getInternalFrame();
Border border = iframe.getBorder();
if(border != null)
return border.getBorderInsets(iframe);
return new Insets(0,0,0,0);
}
public void deiconize() {
try { frame.setIcon(false); } catch (PropertyVetoException e2) { }
}
/**
* Listens for mouse movements and acts on them.
*
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of {@code BasicDesktopIconUI}.
*/
public class MouseInputHandler extends MouseInputAdapter
{
// _x & _y are the mousePressed location in absolute coordinate system
int _x, _y;
// __x & __y are the mousePressed location in source view's coordinate system
int __x, __y;
Rectangle startingBounds;
public void mouseReleased(MouseEvent e) {
_x = 0;
_y = 0;
__x = 0;
__y = 0;
startingBounds = null;
JDesktopPane d;
if((d = desktopIcon.getDesktopPane()) != null) {
DesktopManager dm = d.getDesktopManager();
dm.endDraggingFrame(desktopIcon);
}
}
public void mousePressed(MouseEvent e) {
Point p = SwingUtilities.convertPoint((Component)e.getSource(),
e.getX(), e.getY(), null);
__x = e.getX();
__y = e.getY();
_x = p.x;
_y = p.y;
startingBounds = desktopIcon.getBounds();
JDesktopPane d;
if((d = desktopIcon.getDesktopPane()) != null) {
DesktopManager dm = d.getDesktopManager();
dm.beginDraggingFrame(desktopIcon);
}
try { frame.setSelected(true); } catch (PropertyVetoException e1) { }
if(desktopIcon.getParent() instanceof JLayeredPane) {
((JLayeredPane)desktopIcon.getParent()).moveToFront(desktopIcon);
}
if(e.getClickCount() > 1) {
if(frame.isIconifiable() && frame.isIcon()) {
deiconize();
}
}
}
public void mouseMoved(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {
Point p;
int newX, newY, newW, newH;
int deltaX;
int deltaY;
Dimension min;
Dimension max;
p = SwingUtilities.convertPoint((Component)e.getSource(),
e.getX(), e.getY(), null);
Insets i = desktopIcon.getInsets();
int pWidth, pHeight;
pWidth = ((JComponent)desktopIcon.getParent()).getWidth();
pHeight = ((JComponent)desktopIcon.getParent()).getHeight();
if (startingBounds == null) {
// (STEVE) Yucky work around for bug ID 4106552
return;
}
newX = startingBounds.x - (_x - p.x);
newY = startingBounds.y - (_y - p.y);
// Make sure we stay in-bounds
if(newX + i.left <= -__x)
newX = -__x - i.left;
if(newY + i.top <= -__y)
newY = -__y - i.top;
if(newX + __x + i.right > pWidth)
newX = pWidth - __x - i.right;
if(newY + __y + i.bottom > pHeight)
newY = pHeight - __y - i.bottom;
JDesktopPane d;
if((d = desktopIcon.getDesktopPane()) != null) {
DesktopManager dm = d.getDesktopManager();
dm.dragFrame(desktopIcon, newX, newY);
} else {
moveAndRepaint(desktopIcon, newX, newY,
desktopIcon.getWidth(), desktopIcon.getHeight());
}
return;
}
public void moveAndRepaint(JComponent f, int newX, int newY,
int newWidth, int newHeight) {
Rectangle r = f.getBounds();
f.setBounds(newX, newY, newWidth, newHeight);
SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r);
f.getParent().repaint(r.x, r.y, r.width, r.height);
}
}; /// End MotionListener
}

View File

@@ -0,0 +1,715 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.*;
import javax.swing.plaf.*;
import java.beans.*;
import java.awt.event.*;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Graphics;
import java.awt.KeyboardFocusManager;
import java.awt.*;
import sun.swing.DefaultLookup;
import sun.swing.UIAction;
/**
* Basic L&amp;F for a desktop.
*
* @author Steve Wilson
*/
public class BasicDesktopPaneUI extends DesktopPaneUI {
// Old actions forward to an instance of this.
private static final Actions SHARED_ACTION = new Actions();
private Handler handler;
private PropertyChangeListener pcl;
protected JDesktopPane desktop;
protected DesktopManager desktopManager;
/**
* As of Java 2 platform v1.3 this previously undocumented field is no
* longer used.
* Key bindings are now defined by the LookAndFeel, please refer to
* the key bindings specification for further details.
*
* @deprecated As of 1.3.
*/
@Deprecated
protected KeyStroke minimizeKey;
/**
* As of Java 2 platform v1.3 this previously undocumented field is no
* longer used.
* Key bindings are now defined by the LookAndFeel, please refer to
* the key bindings specification for further details.
*
* @deprecated As of 1.3.
*/
@Deprecated
protected KeyStroke maximizeKey;
/**
* As of Java 2 platform v1.3 this previously undocumented field is no
* longer used.
* Key bindings are now defined by the LookAndFeel, please refer to
* the key bindings specification for further details.
*
* @deprecated As of 1.3.
*/
@Deprecated
protected KeyStroke closeKey;
/**
* As of Java 2 platform v1.3 this previously undocumented field is no
* longer used.
* Key bindings are now defined by the LookAndFeel, please refer to
* the key bindings specification for further details.
*
* @deprecated As of 1.3.
*/
@Deprecated
protected KeyStroke navigateKey;
/**
* As of Java 2 platform v1.3 this previously undocumented field is no
* longer used.
* Key bindings are now defined by the LookAndFeel, please refer to
* the key bindings specification for further details.
*
* @deprecated As of 1.3.
*/
@Deprecated
protected KeyStroke navigateKey2;
public static ComponentUI createUI(JComponent c) {
return new BasicDesktopPaneUI();
}
public BasicDesktopPaneUI() {
}
public void installUI(JComponent c) {
desktop = (JDesktopPane)c;
installDefaults();
installDesktopManager();
installListeners();
installKeyboardActions();
}
public void uninstallUI(JComponent c) {
uninstallKeyboardActions();
uninstallListeners();
uninstallDesktopManager();
uninstallDefaults();
desktop = null;
handler = null;
}
protected void installDefaults() {
if (desktop.getBackground() == null ||
desktop.getBackground() instanceof UIResource) {
desktop.setBackground(UIManager.getColor("Desktop.background"));
}
LookAndFeel.installProperty(desktop, "opaque", Boolean.TRUE);
}
protected void uninstallDefaults() { }
/**
* Installs the <code>PropertyChangeListener</code> returned from
* <code>createPropertyChangeListener</code> on the
* <code>JDesktopPane</code>.
*
* @since 1.5
* @see #createPropertyChangeListener
*/
protected void installListeners() {
pcl = createPropertyChangeListener();
desktop.addPropertyChangeListener(pcl);
}
/**
* Uninstalls the <code>PropertyChangeListener</code> returned from
* <code>createPropertyChangeListener</code> from the
* <code>JDesktopPane</code>.
*
* @since 1.5
* @see #createPropertyChangeListener
*/
protected void uninstallListeners() {
desktop.removePropertyChangeListener(pcl);
pcl = null;
}
protected void installDesktopManager() {
desktopManager = desktop.getDesktopManager();
if(desktopManager == null) {
desktopManager = new BasicDesktopManager();
desktop.setDesktopManager(desktopManager);
}
}
protected void uninstallDesktopManager() {
if(desktop.getDesktopManager() instanceof UIResource) {
desktop.setDesktopManager(null);
}
desktopManager = null;
}
protected void installKeyboardActions(){
InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
if (inputMap != null) {
SwingUtilities.replaceUIInputMap(desktop,
JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
}
inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
if (inputMap != null) {
SwingUtilities.replaceUIInputMap(desktop,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
inputMap);
}
LazyActionMap.installLazyActionMap(desktop, BasicDesktopPaneUI.class,
"DesktopPane.actionMap");
registerKeyboardActions();
}
protected void registerKeyboardActions(){
}
protected void unregisterKeyboardActions(){
}
InputMap getInputMap(int condition) {
if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
return createInputMap(condition);
}
else if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
return (InputMap)DefaultLookup.get(desktop, this,
"Desktop.ancestorInputMap");
}
return null;
}
InputMap createInputMap(int condition) {
if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
Object[] bindings = (Object[])DefaultLookup.get(desktop,
this, "Desktop.windowBindings");
if (bindings != null) {
return LookAndFeel.makeComponentInputMap(desktop, bindings);
}
}
return null;
}
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.RESTORE));
map.put(new Actions(Actions.CLOSE));
map.put(new Actions(Actions.MOVE));
map.put(new Actions(Actions.RESIZE));
map.put(new Actions(Actions.LEFT));
map.put(new Actions(Actions.SHRINK_LEFT));
map.put(new Actions(Actions.RIGHT));
map.put(new Actions(Actions.SHRINK_RIGHT));
map.put(new Actions(Actions.UP));
map.put(new Actions(Actions.SHRINK_UP));
map.put(new Actions(Actions.DOWN));
map.put(new Actions(Actions.SHRINK_DOWN));
map.put(new Actions(Actions.ESCAPE));
map.put(new Actions(Actions.MINIMIZE));
map.put(new Actions(Actions.MAXIMIZE));
map.put(new Actions(Actions.NEXT_FRAME));
map.put(new Actions(Actions.PREVIOUS_FRAME));
map.put(new Actions(Actions.NAVIGATE_NEXT));
map.put(new Actions(Actions.NAVIGATE_PREVIOUS));
}
protected void uninstallKeyboardActions(){
unregisterKeyboardActions();
SwingUtilities.replaceUIInputMap(desktop, JComponent.
WHEN_IN_FOCUSED_WINDOW, null);
SwingUtilities.replaceUIInputMap(desktop, JComponent.
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
SwingUtilities.replaceUIActionMap(desktop, null);
}
public void paint(Graphics g, JComponent c) {}
@Override
public Dimension getPreferredSize(JComponent c) {
return null;
}
@Override
public Dimension getMinimumSize(JComponent c) {
return new Dimension(0, 0);
}
@Override
public Dimension getMaximumSize(JComponent c) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Returns the <code>PropertyChangeListener</code> to install on
* the <code>JDesktopPane</code>.
*
* @since 1.5
* @return The PropertyChangeListener that will be added to track
* changes in the desktop pane.
*/
protected PropertyChangeListener createPropertyChangeListener() {
return getHandler();
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler();
}
return handler;
}
private class Handler implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if ("desktopManager" == propertyName) {
installDesktopManager();
}
}
}
/**
* The default DesktopManager installed by the UI.
*/
private class BasicDesktopManager extends DefaultDesktopManager
implements UIResource {
}
private static class Actions extends UIAction {
private static String CLOSE = "close";
private static String ESCAPE = "escape";
private static String MAXIMIZE = "maximize";
private static String MINIMIZE = "minimize";
private static String MOVE = "move";
private static String RESIZE = "resize";
private static String RESTORE = "restore";
private static String LEFT = "left";
private static String RIGHT = "right";
private static String UP = "up";
private static String DOWN = "down";
private static String SHRINK_LEFT = "shrinkLeft";
private static String SHRINK_RIGHT = "shrinkRight";
private static String SHRINK_UP = "shrinkUp";
private static String SHRINK_DOWN = "shrinkDown";
private static String NEXT_FRAME = "selectNextFrame";
private static String PREVIOUS_FRAME = "selectPreviousFrame";
private static String NAVIGATE_NEXT = "navigateNext";
private static String NAVIGATE_PREVIOUS = "navigatePrevious";
private final int MOVE_RESIZE_INCREMENT = 10;
private static boolean moving = false;
private static boolean resizing = false;
private static JInternalFrame sourceFrame = null;
private static Component focusOwner = null;
Actions() {
super(null);
}
Actions(String name) {
super(name);
}
public void actionPerformed(ActionEvent e) {
JDesktopPane dp = (JDesktopPane)e.getSource();
String key = getName();
if (CLOSE == key || MAXIMIZE == key || MINIMIZE == key ||
RESTORE == key) {
setState(dp, key);
}
else if (ESCAPE == key) {
if (sourceFrame == dp.getSelectedFrame() &&
focusOwner != null) {
focusOwner.requestFocus();
}
moving = false;
resizing = false;
sourceFrame = null;
focusOwner = null;
}
else if (MOVE == key || RESIZE == key) {
sourceFrame = dp.getSelectedFrame();
if (sourceFrame == null) {
return;
}
moving = (key == MOVE) ? true : false;
resizing = (key == RESIZE) ? true : false;
focusOwner = KeyboardFocusManager.
getCurrentKeyboardFocusManager().getFocusOwner();
if (!SwingUtilities.isDescendingFrom(focusOwner, sourceFrame)) {
focusOwner = null;
}
sourceFrame.requestFocus();
}
else if (LEFT == key ||
RIGHT == key ||
UP == key ||
DOWN == key ||
SHRINK_RIGHT == key ||
SHRINK_LEFT == key ||
SHRINK_UP == key ||
SHRINK_DOWN == key) {
JInternalFrame c = dp.getSelectedFrame();
if (sourceFrame == null || c != sourceFrame ||
KeyboardFocusManager.
getCurrentKeyboardFocusManager().getFocusOwner() !=
sourceFrame) {
return;
}
Insets minOnScreenInsets =
UIManager.getInsets("Desktop.minOnScreenInsets");
Dimension size = c.getSize();
Dimension minSize = c.getMinimumSize();
int dpWidth = dp.getWidth();
int dpHeight = dp.getHeight();
int delta;
Point loc = c.getLocation();
if (LEFT == key) {
if (moving) {
c.setLocation(
loc.x + size.width - MOVE_RESIZE_INCREMENT <
minOnScreenInsets.right ?
-size.width + minOnScreenInsets.right :
loc.x - MOVE_RESIZE_INCREMENT,
loc.y);
} else if (resizing) {
c.setLocation(loc.x - MOVE_RESIZE_INCREMENT, loc.y);
c.setSize(size.width + MOVE_RESIZE_INCREMENT,
size.height);
}
} else if (RIGHT == key) {
if (moving) {
c.setLocation(
loc.x + MOVE_RESIZE_INCREMENT >
dpWidth - minOnScreenInsets.left ?
dpWidth - minOnScreenInsets.left :
loc.x + MOVE_RESIZE_INCREMENT,
loc.y);
} else if (resizing) {
c.setSize(size.width + MOVE_RESIZE_INCREMENT,
size.height);
}
} else if (UP == key) {
if (moving) {
c.setLocation(loc.x,
loc.y + size.height - MOVE_RESIZE_INCREMENT <
minOnScreenInsets.bottom ?
-size.height +
minOnScreenInsets.bottom :
loc.y - MOVE_RESIZE_INCREMENT);
} else if (resizing) {
c.setLocation(loc.x, loc.y - MOVE_RESIZE_INCREMENT);
c.setSize(size.width,
size.height + MOVE_RESIZE_INCREMENT);
}
} else if (DOWN == key) {
if (moving) {
c.setLocation(loc.x,
loc.y + MOVE_RESIZE_INCREMENT >
dpHeight - minOnScreenInsets.top ?
dpHeight - minOnScreenInsets.top :
loc.y + MOVE_RESIZE_INCREMENT);
} else if (resizing) {
c.setSize(size.width,
size.height + MOVE_RESIZE_INCREMENT);
}
} else if (SHRINK_LEFT == key && resizing) {
// Make sure we don't resize less than minimum size.
if (minSize.width < (size.width - MOVE_RESIZE_INCREMENT)) {
delta = MOVE_RESIZE_INCREMENT;
} else {
delta = size.width - minSize.width;
}
// Ensure that we keep the internal frame on the desktop.
if (loc.x + size.width - delta < minOnScreenInsets.left) {
delta = loc.x + size.width - minOnScreenInsets.left;
}
c.setSize(size.width - delta, size.height);
} else if (SHRINK_RIGHT == key && resizing) {
// Make sure we don't resize less than minimum size.
if (minSize.width < (size.width - MOVE_RESIZE_INCREMENT)) {
delta = MOVE_RESIZE_INCREMENT;
} else {
delta = size.width - minSize.width;
}
// Ensure that we keep the internal frame on the desktop.
if (loc.x + delta > dpWidth - minOnScreenInsets.right) {
delta = (dpWidth - minOnScreenInsets.right) - loc.x;
}
c.setLocation(loc.x + delta, loc.y);
c.setSize(size.width - delta, size.height);
} else if (SHRINK_UP == key && resizing) {
// Make sure we don't resize less than minimum size.
if (minSize.height <
(size.height - MOVE_RESIZE_INCREMENT)) {
delta = MOVE_RESIZE_INCREMENT;
} else {
delta = size.height - minSize.height;
}
// Ensure that we keep the internal frame on the desktop.
if (loc.y + size.height - delta <
minOnScreenInsets.bottom) {
delta = loc.y + size.height - minOnScreenInsets.bottom;
}
c.setSize(size.width, size.height - delta);
} else if (SHRINK_DOWN == key && resizing) {
// Make sure we don't resize less than minimum size.
if (minSize.height <
(size.height - MOVE_RESIZE_INCREMENT)) {
delta = MOVE_RESIZE_INCREMENT;
} else {
delta = size.height - minSize.height;
}
// Ensure that we keep the internal frame on the desktop.
if (loc.y + delta > dpHeight - minOnScreenInsets.top) {
delta = (dpHeight - minOnScreenInsets.top) - loc.y;
}
c.setLocation(loc.x, loc.y + delta);
c.setSize(size.width, size.height - delta);
}
}
else if (NEXT_FRAME == key || PREVIOUS_FRAME == key) {
dp.selectFrame((key == NEXT_FRAME) ? true : false);
}
else if (NAVIGATE_NEXT == key ||
NAVIGATE_PREVIOUS == key) {
boolean moveForward = true;
if (NAVIGATE_PREVIOUS == key) {
moveForward = false;
}
Container cycleRoot = dp.getFocusCycleRootAncestor();
if (cycleRoot != null) {
FocusTraversalPolicy policy =
cycleRoot.getFocusTraversalPolicy();
if (policy != null && policy instanceof
SortingFocusTraversalPolicy) {
SortingFocusTraversalPolicy sPolicy =
(SortingFocusTraversalPolicy)policy;
boolean idc = sPolicy.getImplicitDownCycleTraversal();
try {
sPolicy.setImplicitDownCycleTraversal(false);
if (moveForward) {
KeyboardFocusManager.
getCurrentKeyboardFocusManager().
focusNextComponent(dp);
} else {
KeyboardFocusManager.
getCurrentKeyboardFocusManager().
focusPreviousComponent(dp);
}
} finally {
sPolicy.setImplicitDownCycleTraversal(idc);
}
}
}
}
}
private void setState(JDesktopPane dp, String state) {
if (state == CLOSE) {
JInternalFrame f = dp.getSelectedFrame();
if (f == null) {
return;
}
f.doDefaultCloseAction();
} else if (state == MAXIMIZE) {
// maximize the selected frame
JInternalFrame f = dp.getSelectedFrame();
if (f == null) {
return;
}
if (!f.isMaximum()) {
if (f.isIcon()) {
try {
f.setIcon(false);
f.setMaximum(true);
} catch (PropertyVetoException pve) {}
} else {
try {
f.setMaximum(true);
} catch (PropertyVetoException pve) {
}
}
}
} else if (state == MINIMIZE) {
// minimize the selected frame
JInternalFrame f = dp.getSelectedFrame();
if (f == null) {
return;
}
if (!f.isIcon()) {
try {
f.setIcon(true);
} catch (PropertyVetoException pve) {
}
}
} else if (state == RESTORE) {
// restore the selected minimized or maximized frame
JInternalFrame f = dp.getSelectedFrame();
if (f == null) {
return;
}
try {
if (f.isIcon()) {
f.setIcon(false);
} else if (f.isMaximum()) {
f.setMaximum(false);
}
f.setSelected(true);
} catch (PropertyVetoException pve) {
}
}
}
public boolean isEnabled(Object sender) {
if (sender instanceof JDesktopPane) {
JDesktopPane dp = (JDesktopPane)sender;
String action = getName();
if (action == Actions.NEXT_FRAME ||
action == Actions.PREVIOUS_FRAME) {
return true;
}
JInternalFrame iFrame = dp.getSelectedFrame();
if (iFrame == null) {
return false;
} else if (action == Actions.CLOSE) {
return iFrame.isClosable();
} else if (action == Actions.MINIMIZE) {
return iFrame.isIconifiable();
} else if (action == Actions.MAXIMIZE) {
return iFrame.isMaximizable();
}
return true;
}
return false;
}
}
/**
* Handles restoring a minimized or maximized internal frame.
* @since 1.3
*/
protected class OpenAction extends AbstractAction {
public void actionPerformed(ActionEvent evt) {
JDesktopPane dp = (JDesktopPane)evt.getSource();
SHARED_ACTION.setState(dp, Actions.RESTORE);
}
public boolean isEnabled() {
return true;
}
}
/**
* Handles closing an internal frame.
*/
protected class CloseAction extends AbstractAction {
public void actionPerformed(ActionEvent evt) {
JDesktopPane dp = (JDesktopPane)evt.getSource();
SHARED_ACTION.setState(dp, Actions.CLOSE);
}
public boolean isEnabled() {
JInternalFrame iFrame = desktop.getSelectedFrame();
if (iFrame != null) {
return iFrame.isClosable();
}
return false;
}
}
/**
* Handles minimizing an internal frame.
*/
protected class MinimizeAction extends AbstractAction {
public void actionPerformed(ActionEvent evt) {
JDesktopPane dp = (JDesktopPane)evt.getSource();
SHARED_ACTION.setState(dp, Actions.MINIMIZE);
}
public boolean isEnabled() {
JInternalFrame iFrame = desktop.getSelectedFrame();
if (iFrame != null) {
return iFrame.isIconifiable();
}
return false;
}
}
/**
* Handles maximizing an internal frame.
*/
protected class MaximizeAction extends AbstractAction {
public void actionPerformed(ActionEvent evt) {
JDesktopPane dp = (JDesktopPane)evt.getSource();
SHARED_ACTION.setState(dp, Actions.MAXIMIZE);
}
public boolean isEnabled() {
JInternalFrame iFrame = desktop.getSelectedFrame();
if (iFrame != null) {
return iFrame.isMaximizable();
}
return false;
}
}
/**
* Handles navigating to the next internal frame.
*/
protected class NavigateAction extends AbstractAction {
public void actionPerformed(ActionEvent evt) {
JDesktopPane dp = (JDesktopPane)evt.getSource();
dp.selectFrame(true);
}
public boolean isEnabled() {
return true;
}
}
}

View File

@@ -0,0 +1,497 @@
/*
* Copyright (c) 1998, 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.basic;
import java.io.File;
import java.util.*;
import java.util.concurrent.Callable;
import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.event.*;
import java.beans.*;
import sun.awt.shell.ShellFolder;
/**
* Basic implementation of a file list.
*
* @author Jeff Dinkins
*/
public class BasicDirectoryModel extends AbstractListModel<Object> implements PropertyChangeListener {
private JFileChooser filechooser = null;
// PENDING(jeff) pick the size more sensibly
private Vector<File> fileCache = new Vector<File>(50);
private LoadFilesThread loadThread = null;
private Vector<File> files = null;
private Vector<File> directories = null;
private int fetchID = 0;
private PropertyChangeSupport changeSupport;
private boolean busy = false;
public BasicDirectoryModel(JFileChooser filechooser) {
this.filechooser = filechooser;
validateFileCache();
}
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if(prop == JFileChooser.DIRECTORY_CHANGED_PROPERTY ||
prop == JFileChooser.FILE_VIEW_CHANGED_PROPERTY ||
prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY ||
prop == JFileChooser.FILE_HIDING_CHANGED_PROPERTY ||
prop == JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY) {
validateFileCache();
} else if ("UI".equals(prop)) {
Object old = e.getOldValue();
if (old instanceof BasicFileChooserUI) {
BasicFileChooserUI ui = (BasicFileChooserUI) old;
BasicDirectoryModel model = ui.getModel();
if (model != null) {
model.invalidateFileCache();
}
}
} else if ("JFileChooserDialogIsClosingProperty".equals(prop)) {
invalidateFileCache();
}
}
/**
* This method is used to interrupt file loading thread.
*/
public void invalidateFileCache() {
if (loadThread != null) {
loadThread.interrupt();
loadThread.cancelRunnables();
loadThread = null;
}
}
public Vector<File> getDirectories() {
synchronized(fileCache) {
if (directories != null) {
return directories;
}
Vector fls = getFiles();
return directories;
}
}
public Vector<File> getFiles() {
synchronized(fileCache) {
if (files != null) {
return files;
}
files = new Vector<File>();
directories = new Vector<File>();
directories.addElement(filechooser.getFileSystemView().createFileObject(
filechooser.getCurrentDirectory(), "..")
);
for (int i = 0; i < getSize(); i++) {
File f = fileCache.get(i);
if (filechooser.isTraversable(f)) {
directories.add(f);
} else {
files.add(f);
}
}
return files;
}
}
public void validateFileCache() {
File currentDirectory = filechooser.getCurrentDirectory();
if (currentDirectory == null) {
return;
}
if (loadThread != null) {
loadThread.interrupt();
loadThread.cancelRunnables();
}
setBusy(true, ++fetchID);
loadThread = new LoadFilesThread(currentDirectory, fetchID);
loadThread.start();
}
/**
* Renames a file in the underlying file system.
*
* @param oldFile a <code>File</code> object representing
* the existing file
* @param newFile a <code>File</code> object representing
* the desired new file name
* @return <code>true</code> if rename succeeded,
* otherwise <code>false</code>
* @since 1.4
*/
public boolean renameFile(File oldFile, File newFile) {
synchronized(fileCache) {
if (oldFile.renameTo(newFile)) {
validateFileCache();
return true;
}
return false;
}
}
public void fireContentsChanged() {
// System.out.println("BasicDirectoryModel: firecontentschanged");
fireContentsChanged(this, 0, getSize()-1);
}
public int getSize() {
return fileCache.size();
}
public boolean contains(Object o) {
return fileCache.contains(o);
}
public int indexOf(Object o) {
return fileCache.indexOf(o);
}
public Object getElementAt(int index) {
return fileCache.get(index);
}
/**
* Obsolete - not used.
*/
public void intervalAdded(ListDataEvent e) {
}
/**
* Obsolete - not used.
*/
public void intervalRemoved(ListDataEvent e) {
}
protected void sort(Vector<? extends File> v){
ShellFolder.sort(v);
}
// Obsolete - not used
protected boolean lt(File a, File b) {
// First ignore case when comparing
int diff = a.getName().toLowerCase().compareTo(b.getName().toLowerCase());
if (diff != 0) {
return diff < 0;
} else {
// May differ in case (e.g. "mail" vs. "Mail")
return a.getName().compareTo(b.getName()) < 0;
}
}
class LoadFilesThread extends Thread {
File currentDirectory = null;
int fid;
Vector<DoChangeContents> runnables = new Vector<DoChangeContents>(10);
public LoadFilesThread(File currentDirectory, int fid) {
super("Basic L&F File Loading Thread");
this.currentDirectory = currentDirectory;
this.fid = fid;
}
public void run() {
run0();
setBusy(false, fid);
}
public void run0() {
FileSystemView fileSystem = filechooser.getFileSystemView();
if (isInterrupted()) {
return;
}
File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled());
if (isInterrupted()) {
return;
}
final Vector<File> newFileCache = new Vector<File>();
Vector<File> newFiles = new Vector<File>();
// run through the file list, add directories and selectable files to fileCache
// Note that this block must be OUTSIDE of Invoker thread because of
// deadlock possibility with custom synchronized FileSystemView
for (File file : list) {
if (filechooser.accept(file)) {
boolean isTraversable = filechooser.isTraversable(file);
if (isTraversable) {
newFileCache.addElement(file);
} else if (filechooser.isFileSelectionEnabled()) {
newFiles.addElement(file);
}
if (isInterrupted()) {
return;
}
}
}
// First sort alphabetically by filename
sort(newFileCache);
sort(newFiles);
newFileCache.addAll(newFiles);
// To avoid loads of synchronizations with Invoker and improve performance we
// execute the whole block on the COM thread
DoChangeContents doChangeContents = ShellFolder.invoke(new Callable<DoChangeContents>() {
public DoChangeContents call() {
int newSize = newFileCache.size();
int oldSize = fileCache.size();
if (newSize > oldSize) {
//see if interval is added
int start = oldSize;
int end = newSize;
for (int i = 0; i < oldSize; i++) {
if (!newFileCache.get(i).equals(fileCache.get(i))) {
start = i;
for (int j = i; j < newSize; j++) {
if (newFileCache.get(j).equals(fileCache.get(i))) {
end = j;
break;
}
}
break;
}
}
if (start >= 0 && end > start
&& newFileCache.subList(end, newSize).equals(fileCache.subList(start, oldSize))) {
if (isInterrupted()) {
return null;
}
return new DoChangeContents(newFileCache.subList(start, end), start, null, 0, fid);
}
} else if (newSize < oldSize) {
//see if interval is removed
int start = -1;
int end = -1;
for (int i = 0; i < newSize; i++) {
if (!newFileCache.get(i).equals(fileCache.get(i))) {
start = i;
end = i + oldSize - newSize;
break;
}
}
if (start >= 0 && end > start
&& fileCache.subList(end, oldSize).equals(newFileCache.subList(start, newSize))) {
if (isInterrupted()) {
return null;
}
return new DoChangeContents(null, 0, new Vector(fileCache.subList(start, end)), start, fid);
}
}
if (!fileCache.equals(newFileCache)) {
if (isInterrupted()) {
cancelRunnables(runnables);
}
return new DoChangeContents(newFileCache, 0, fileCache, 0, fid);
}
return null;
}
});
if (doChangeContents != null) {
runnables.addElement(doChangeContents);
SwingUtilities.invokeLater(doChangeContents);
}
}
public void cancelRunnables(Vector<DoChangeContents> runnables) {
for (DoChangeContents runnable : runnables) {
runnable.cancel();
}
}
public void cancelRunnables() {
cancelRunnables(runnables);
}
}
/**
* Adds a PropertyChangeListener to the listener list. The listener is
* registered for all bound properties of this class.
* <p>
* If <code>listener</code> is <code>null</code>,
* no exception is thrown and no action is performed.
*
* @param listener the property change listener to be added
*
* @see #removePropertyChangeListener
* @see #getPropertyChangeListeners
*
* @since 1.6
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
if (changeSupport == null) {
changeSupport = new PropertyChangeSupport(this);
}
changeSupport.addPropertyChangeListener(listener);
}
/**
* Removes a PropertyChangeListener from the listener list.
* <p>
* If listener is null, no exception is thrown and no action is performed.
*
* @param listener the PropertyChangeListener to be removed
*
* @see #addPropertyChangeListener
* @see #getPropertyChangeListeners
*
* @since 1.6
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
if (changeSupport != null) {
changeSupport.removePropertyChangeListener(listener);
}
}
/**
* Returns an array of all the property change listeners
* registered on this component.
*
* @return all of this component's <code>PropertyChangeListener</code>s
* or an empty array if no property change
* listeners are currently registered
*
* @see #addPropertyChangeListener
* @see #removePropertyChangeListener
* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
*
* @since 1.6
*/
public PropertyChangeListener[] getPropertyChangeListeners() {
if (changeSupport == null) {
return new PropertyChangeListener[0];
}
return changeSupport.getPropertyChangeListeners();
}
/**
* Support for reporting bound property changes for boolean properties.
* This method can be called when a bound property has changed and it will
* send the appropriate PropertyChangeEvent to any registered
* PropertyChangeListeners.
*
* @param propertyName the property whose value has changed
* @param oldValue the property's previous value
* @param newValue the property's new value
*
* @since 1.6
*/
protected void firePropertyChange(String propertyName,
Object oldValue, Object newValue) {
if (changeSupport != null) {
changeSupport.firePropertyChange(propertyName,
oldValue, newValue);
}
}
/**
* Set the busy state for the model. The model is considered
* busy when it is running a separate (interruptable)
* thread in order to load the contents of a directory.
*/
private synchronized void setBusy(final boolean busy, int fid) {
if (fid == fetchID) {
boolean oldValue = this.busy;
this.busy = busy;
if (changeSupport != null && busy != oldValue) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
firePropertyChange("busy", !busy, busy);
}
});
}
}
}
class DoChangeContents implements Runnable {
private List<File> addFiles;
private List<File> remFiles;
private boolean doFire = true;
private int fid;
private int addStart = 0;
private int remStart = 0;
public DoChangeContents(List<File> addFiles, int addStart, List<File> remFiles, int remStart, int fid) {
this.addFiles = addFiles;
this.addStart = addStart;
this.remFiles = remFiles;
this.remStart = remStart;
this.fid = fid;
}
synchronized void cancel() {
doFire = false;
}
public synchronized void run() {
if (fetchID == fid && doFire) {
int remSize = (remFiles == null) ? 0 : remFiles.size();
int addSize = (addFiles == null) ? 0 : addFiles.size();
synchronized(fileCache) {
if (remSize > 0) {
fileCache.removeAll(remFiles);
}
if (addSize > 0) {
fileCache.addAll(addStart, addFiles);
}
files = null;
directories = null;
}
if (remSize > 0 && addSize == 0) {
fireIntervalRemoved(BasicDirectoryModel.this, remStart, remStart + remSize - 1);
} else if (addSize > 0 && remSize == 0 && addStart + addSize <= fileCache.size()) {
fireIntervalAdded(BasicDirectoryModel.this, addStart, addStart + addSize - 1);
} else {
fireContentsChanged();
}
}
}
}
}

View File

@@ -0,0 +1,413 @@
/*
* Copyright (c) 1997, 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.basic;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.net.URL;
import java.net.MalformedURLException;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.plaf.*;
import javax.swing.border.*;
/**
* Provides the look and feel for a JEditorPane.
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Timothy Prinzing
*/
public class BasicEditorPaneUI extends BasicTextUI {
/**
* Creates a UI for the JTextPane.
*
* @param c the JTextPane component
* @return the UI
*/
public static ComponentUI createUI(JComponent c) {
return new BasicEditorPaneUI();
}
/**
* Creates a new BasicEditorPaneUI.
*/
public BasicEditorPaneUI() {
super();
}
/**
* 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 ("EditorPane")
*/
protected String getPropertyPrefix() {
return "EditorPane";
}
/**
*{@inheritDoc}
*
* @since 1.5
*/
public void installUI(JComponent c) {
super.installUI(c);
updateDisplayProperties(c.getFont(),
c.getForeground());
}
/**
*{@inheritDoc}
*
* @since 1.5
*/
public void uninstallUI(JComponent c) {
cleanDisplayProperties();
super.uninstallUI(c);
}
/**
* Fetches the EditorKit for the UI. This is whatever is
* currently set in the associated JEditorPane.
*
* @return the editor capabilities
* @see TextUI#getEditorKit
*/
public EditorKit getEditorKit(JTextComponent tc) {
JEditorPane pane = (JEditorPane) getComponent();
return pane.getEditorKit();
}
/**
* Fetch an action map to use. The map for a JEditorPane
* is not shared because it changes with the EditorKit.
*/
ActionMap getActionMap() {
ActionMap am = new ActionMapUIResource();
am.put("requestFocus", new FocusAction());
EditorKit editorKit = getEditorKit(getComponent());
if (editorKit != null) {
Action[] actions = editorKit.getActions();
if (actions != null) {
addActions(am, actions);
}
}
am.put(TransferHandler.getCutAction().getValue(Action.NAME),
TransferHandler.getCutAction());
am.put(TransferHandler.getCopyAction().getValue(Action.NAME),
TransferHandler.getCopyAction());
am.put(TransferHandler.getPasteAction().getValue(Action.NAME),
TransferHandler.getPasteAction());
return am;
}
/**
* 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
*/
protected void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
String name = evt.getPropertyName();
if ("editorKit".equals(name)) {
ActionMap map = SwingUtilities.getUIActionMap(getComponent());
if (map != null) {
Object oldValue = evt.getOldValue();
if (oldValue instanceof EditorKit) {
Action[] actions = ((EditorKit)oldValue).getActions();
if (actions != null) {
removeActions(map, actions);
}
}
Object newValue = evt.getNewValue();
if (newValue instanceof EditorKit) {
Action[] actions = ((EditorKit)newValue).getActions();
if (actions != null) {
addActions(map, actions);
}
}
}
updateFocusTraversalKeys();
} else if ("editable".equals(name)) {
updateFocusTraversalKeys();
} else if ("foreground".equals(name)
|| "font".equals(name)
|| "document".equals(name)
|| JEditorPane.W3C_LENGTH_UNITS.equals(name)
|| JEditorPane.HONOR_DISPLAY_PROPERTIES.equals(name)
) {
JComponent c = getComponent();
updateDisplayProperties(c.getFont(), c.getForeground());
if ( JEditorPane.W3C_LENGTH_UNITS.equals(name)
|| JEditorPane.HONOR_DISPLAY_PROPERTIES.equals(name) ) {
modelChanged();
}
if ("foreground".equals(name)) {
Object honorDisplayPropertiesObject = c.
getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
boolean honorDisplayProperties = false;
if (honorDisplayPropertiesObject instanceof Boolean) {
honorDisplayProperties =
((Boolean)honorDisplayPropertiesObject).booleanValue();
}
if (honorDisplayProperties) {
modelChanged();
}
}
}
}
void removeActions(ActionMap map, Action[] actions) {
int n = actions.length;
for (int i = 0; i < n; i++) {
Action a = actions[i];
map.remove(a.getValue(Action.NAME));
}
}
void addActions(ActionMap map, Action[] actions) {
int n = actions.length;
for (int i = 0; i < n; i++) {
Action a = actions[i];
map.put(a.getValue(Action.NAME), a);
}
}
void updateDisplayProperties(Font font, Color fg) {
JComponent c = getComponent();
Object honorDisplayPropertiesObject = c.
getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
boolean honorDisplayProperties = false;
Object w3cLengthUnitsObject = c.getClientProperty(JEditorPane.
W3C_LENGTH_UNITS);
boolean w3cLengthUnits = false;
if (honorDisplayPropertiesObject instanceof Boolean) {
honorDisplayProperties =
((Boolean)honorDisplayPropertiesObject).booleanValue();
}
if (w3cLengthUnitsObject instanceof Boolean) {
w3cLengthUnits = ((Boolean)w3cLengthUnitsObject).booleanValue();
}
if (this instanceof BasicTextPaneUI
|| honorDisplayProperties) {
//using equals because can not use UIResource for Boolean
Document doc = getComponent().getDocument();
if (doc instanceof StyledDocument) {
if (doc instanceof HTMLDocument
&& honorDisplayProperties) {
updateCSS(font, fg);
} else {
updateStyle(font, fg);
}
}
} else {
cleanDisplayProperties();
}
if ( w3cLengthUnits ) {
Document doc = getComponent().getDocument();
if (doc instanceof HTMLDocument) {
StyleSheet documentStyleSheet =
((HTMLDocument)doc).getStyleSheet();
documentStyleSheet.addRule("W3C_LENGTH_UNITS_ENABLE");
}
} else {
Document doc = getComponent().getDocument();
if (doc instanceof HTMLDocument) {
StyleSheet documentStyleSheet =
((HTMLDocument)doc).getStyleSheet();
documentStyleSheet.addRule("W3C_LENGTH_UNITS_DISABLE");
}
}
}
/**
* Attribute key to reference the default font.
* used in javax.swing.text.StyleContext.getFont
* to resolve the default font.
*/
private static final String FONT_ATTRIBUTE_KEY = "FONT_ATTRIBUTE_KEY";
void cleanDisplayProperties() {
Document document = getComponent().getDocument();
if (document instanceof HTMLDocument) {
StyleSheet documentStyleSheet =
((HTMLDocument)document).getStyleSheet();
StyleSheet[] styleSheets = documentStyleSheet.getStyleSheets();
if (styleSheets != null) {
for (StyleSheet s : styleSheets) {
if (s instanceof StyleSheetUIResource) {
documentStyleSheet.removeStyleSheet(s);
documentStyleSheet.addRule("BASE_SIZE_DISABLE");
break;
}
}
}
Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE);
if (style.getAttribute(FONT_ATTRIBUTE_KEY) != null) {
style.removeAttribute(FONT_ATTRIBUTE_KEY);
}
}
}
static class StyleSheetUIResource extends StyleSheet implements UIResource {
}
private void updateCSS(Font font, Color fg) {
JTextComponent component = getComponent();
Document document = component.getDocument();
if (document instanceof HTMLDocument) {
StyleSheet styleSheet = new StyleSheetUIResource();
StyleSheet documentStyleSheet =
((HTMLDocument)document).getStyleSheet();
StyleSheet[] styleSheets = documentStyleSheet.getStyleSheets();
if (styleSheets != null) {
for (StyleSheet s : styleSheets) {
if (s instanceof StyleSheetUIResource) {
documentStyleSheet.removeStyleSheet(s);
}
}
}
String cssRule = sun.swing.
SwingUtilities2.displayPropertiesToCSS(font,
fg);
styleSheet.addRule(cssRule);
documentStyleSheet.addStyleSheet(styleSheet);
documentStyleSheet.addRule("BASE_SIZE " +
component.getFont().getSize());
Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE);
if (! font.equals(style.getAttribute(FONT_ATTRIBUTE_KEY))) {
style.addAttribute(FONT_ATTRIBUTE_KEY, font);
}
}
}
private void updateStyle(Font font, Color fg) {
updateFont(font);
updateForeground(fg);
}
/**
* 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) {
if (style.getAttribute(StyleConstants.Foreground) != null) {
style.removeAttribute(StyleConstants.Foreground);
}
} else {
if (! color.equals(StyleConstants.getForeground(style))) {
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;
}
String fontFamily = (String) style.getAttribute(StyleConstants.FontFamily);
Integer fontSize = (Integer) style.getAttribute(StyleConstants.FontSize);
Boolean isBold = (Boolean) style.getAttribute(StyleConstants.Bold);
Boolean isItalic = (Boolean) style.getAttribute(StyleConstants.Italic);
Font fontAttribute = (Font) style.getAttribute(FONT_ATTRIBUTE_KEY);
if (font == null) {
if (fontFamily != null) {
style.removeAttribute(StyleConstants.FontFamily);
}
if (fontSize != null) {
style.removeAttribute(StyleConstants.FontSize);
}
if (isBold != null) {
style.removeAttribute(StyleConstants.Bold);
}
if (isItalic != null) {
style.removeAttribute(StyleConstants.Italic);
}
if (fontAttribute != null) {
style.removeAttribute(FONT_ATTRIBUTE_KEY);
}
} else {
if (! font.getName().equals(fontFamily)) {
StyleConstants.setFontFamily(style, font.getName());
}
if (fontSize == null
|| fontSize.intValue() != font.getSize()) {
StyleConstants.setFontSize(style, font.getSize());
}
if (isBold == null
|| isBold.booleanValue() != font.isBold()) {
StyleConstants.setBold(style, font.isBold());
}
if (isItalic == null
|| isItalic.booleanValue() != font.isItalic()) {
StyleConstants.setItalic(style, font.isItalic());
}
if (! font.equals(fontAttribute)) {
style.addAttribute(FONT_ATTRIBUTE_KEY, font);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2000, 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.basic;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
/**
* Provides the look and feel implementation for
* <code>JFormattedTextField</code>.
*
* @since 1.4
*/
public class BasicFormattedTextFieldUI extends BasicTextFieldUI {
/**
* Creates a UI for a JFormattedTextField.
*
* @param c the formatted text field
* @return the UI
*/
public static ComponentUI createUI(JComponent c) {
return new BasicFormattedTextFieldUI();
}
/**
* 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"
*/
protected String getPropertyPrefix() {
return "FormattedTextField";
}
}

View File

@@ -0,0 +1,314 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.*;
import java.awt.Component;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import sun.swing.SwingUtilities2;
/*
* @author Hans Muller
*/
public class BasicGraphicsUtils
{
private static final Insets GROOVE_INSETS = new Insets(2, 2, 2, 2);
private static final Insets ETCHED_INSETS = new Insets(2, 2, 2, 2);
public static void drawEtchedRect(Graphics g, int x, int y, int w, int h,
Color shadow, Color darkShadow,
Color highlight, Color lightHighlight)
{
Color oldColor = g.getColor(); // Make no net change to g
g.translate(x, y);
g.setColor(shadow);
g.drawLine(0, 0, w-1, 0); // outer border, top
g.drawLine(0, 1, 0, h-2); // outer border, left
g.setColor(darkShadow);
g.drawLine(1, 1, w-3, 1); // inner border, top
g.drawLine(1, 2, 1, h-3); // inner border, left
g.setColor(lightHighlight);
g.drawLine(w-1, 0, w-1, h-1); // outer border, bottom
g.drawLine(0, h-1, w-1, h-1); // outer border, right
g.setColor(highlight);
g.drawLine(w-2, 1, w-2, h-3); // inner border, right
g.drawLine(1, h-2, w-2, h-2); // inner border, bottom
g.translate(-x, -y);
g.setColor(oldColor);
}
/**
* Returns the amount of space taken up by a border drawn by
* <code>drawEtchedRect()</code>
*
* @return the inset of an etched rect
*/
public static Insets getEtchedInsets() {
return ETCHED_INSETS;
}
public static void drawGroove(Graphics g, int x, int y, int w, int h,
Color shadow, Color highlight)
{
Color oldColor = g.getColor(); // Make no net change to g
g.translate(x, y);
g.setColor(shadow);
g.drawRect(0, 0, w-2, h-2);
g.setColor(highlight);
g.drawLine(1, h-3, 1, 1);
g.drawLine(1, 1, w-3, 1);
g.drawLine(0, h-1, w-1, h-1);
g.drawLine(w-1, h-1, w-1, 0);
g.translate(-x, -y);
g.setColor(oldColor);
}
/**
* Returns the amount of space taken up by a border drawn by
* <code>drawGroove()</code>
*
* @return the inset of a groove border
*/
public static Insets getGrooveInsets() {
return GROOVE_INSETS;
}
public static void drawBezel(Graphics g, int x, int y, int w, int h,
boolean isPressed, boolean isDefault,
Color shadow, Color darkShadow,
Color highlight, Color lightHighlight)
{
Color oldColor = g.getColor(); // Make no net change to g
g.translate(x, y);
if (isPressed && isDefault) {
g.setColor(darkShadow);
g.drawRect(0, 0, w - 1, h - 1);
g.setColor(shadow);
g.drawRect(1, 1, w - 3, h - 3);
} else if (isPressed) {
drawLoweredBezel(g, x, y, w, h,
shadow, darkShadow, highlight, lightHighlight);
} else if (isDefault) {
g.setColor(darkShadow);
g.drawRect(0, 0, w-1, h-1);
g.setColor(lightHighlight);
g.drawLine(1, 1, 1, h-3);
g.drawLine(2, 1, w-3, 1);
g.setColor(highlight);
g.drawLine(2, 2, 2, h-4);
g.drawLine(3, 2, w-4, 2);
g.setColor(shadow);
g.drawLine(2, h-3, w-3, h-3);
g.drawLine(w-3, 2, w-3, h-4);
g.setColor(darkShadow);
g.drawLine(1, h-2, w-2, h-2);
g.drawLine(w-2, h-2, w-2, 1);
} else {
g.setColor(lightHighlight);
g.drawLine(0, 0, 0, h-1);
g.drawLine(1, 0, w-2, 0);
g.setColor(highlight);
g.drawLine(1, 1, 1, h-3);
g.drawLine(2, 1, w-3, 1);
g.setColor(shadow);
g.drawLine(1, h-2, w-2, h-2);
g.drawLine(w-2, 1, w-2, h-3);
g.setColor(darkShadow);
g.drawLine(0, h-1, w-1, h-1);
g.drawLine(w-1, h-1, w-1, 0);
}
g.translate(-x, -y);
g.setColor(oldColor);
}
public static void drawLoweredBezel(Graphics g, int x, int y, int w, int h,
Color shadow, Color darkShadow,
Color highlight, Color lightHighlight) {
g.setColor(darkShadow);
g.drawLine(0, 0, 0, h-1);
g.drawLine(1, 0, w-2, 0);
g.setColor(shadow);
g.drawLine(1, 1, 1, h-2);
g.drawLine(1, 1, w-3, 1);
g.setColor(lightHighlight);
g.drawLine(0, h-1, w-1, h-1);
g.drawLine(w-1, h-1, w-1, 0);
g.setColor(highlight);
g.drawLine(1, h-2, w-2, h-2);
g.drawLine(w-2, h-2, w-2, 1);
}
/** Draw a string with the graphics <code>g</code> at location (x,y)
* just like <code>g.drawString</code> would.
* The first occurrence of <code>underlineChar</code>
* in text will be underlined. The matching algorithm is
* not case sensitive.
*/
public static void drawString(Graphics g,String text,int underlinedChar,int x,int y) {
int index=-1;
if (underlinedChar != '\0') {
char uc = Character.toUpperCase((char)underlinedChar);
char lc = Character.toLowerCase((char)underlinedChar);
int uci = text.indexOf(uc);
int lci = text.indexOf(lc);
if(uci == -1) {
index = lci;
}
else if(lci == -1) {
index = uci;
}
else {
index = (lci < uci) ? lci : uci;
}
}
drawStringUnderlineCharAt(g, text, index, x, y);
}
/**
* Draw a string with the graphics <code>g</code> at location
* (<code>x</code>, <code>y</code>)
* just like <code>g.drawString</code> would.
* The character at index <code>underlinedIndex</code>
* in text will be underlined. If <code>index</code> is beyond the
* bounds of <code>text</code> (including &lt; 0), nothing will be
* underlined.
*
* @param g Graphics to draw with
* @param text String to draw
* @param underlinedIndex Index of character in text to underline
* @param x x coordinate to draw at
* @param y y coordinate to draw at
* @since 1.4
*/
public static void drawStringUnderlineCharAt(Graphics g, String text,
int underlinedIndex, int x,int y) {
SwingUtilities2.drawStringUnderlineCharAt(null, g, text,
underlinedIndex, x, y);
}
public static void drawDashedRect(Graphics g,int x,int y,int width,int height) {
int vx,vy;
// draw upper and lower horizontal dashes
for (vx = x; vx < (x + width); vx+=2) {
g.fillRect(vx, y, 1, 1);
g.fillRect(vx, y + height-1, 1, 1);
}
// draw left and right vertical dashes
for (vy = y; vy < (y + height); vy+=2) {
g.fillRect(x, vy, 1, 1);
g.fillRect(x+width-1, vy, 1, 1);
}
}
public static Dimension getPreferredButtonSize(AbstractButton b, int textIconGap)
{
if(b.getComponentCount() > 0) {
return null;
}
Icon icon = b.getIcon();
String text = b.getText();
Font font = b.getFont();
FontMetrics fm = b.getFontMetrics(font);
Rectangle iconR = new Rectangle();
Rectangle textR = new Rectangle();
Rectangle viewR = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
SwingUtilities.layoutCompoundLabel(
b, fm, text, icon,
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewR, iconR, textR, (text == null ? 0 : textIconGap)
);
/* The preferred size of the button is the size of
* the text and icon rectangles plus the buttons insets.
*/
Rectangle r = iconR.union(textR);
Insets insets = b.getInsets();
r.width += insets.left + insets.right;
r.height += insets.top + insets.bottom;
return r.getSize();
}
/*
* Convenience function for determining ComponentOrientation. Helps us
* avoid having Munge directives throughout the code.
*/
static boolean isLeftToRight( Component c ) {
return c.getComponentOrientation().isLeftToRight();
}
static boolean isMenuShortcutKeyDown(InputEvent event) {
return (event.getModifiers() &
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0;
}
}

View File

@@ -0,0 +1,694 @@
/*
* Copyright (c) 1998, 2019, 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.basic;
import java.io.*;
import java.awt.*;
import java.net.URL;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import sun.swing.SwingAccessor;
import sun.swing.SwingUtilities2;
/**
* Support for providing html views for the swing components.
* This translates a simple html string to a javax.swing.text.View
* implementation that can render the html and provide the necessary
* layout semantics.
*
* @author Timothy Prinzing
* @since 1.3
*/
public class BasicHTML {
/**
* Create an html renderer for the given component and
* string of html.
*/
public static View createHTMLView(JComponent c, String html) {
BasicEditorKit kit = getFactory();
Document doc = kit.createDefaultDocument(c.getFont(),
c.getForeground());
Object base = c.getClientProperty(documentBaseKey);
if (base instanceof URL) {
((HTMLDocument)doc).setBase((URL)base);
}
Reader r = new StringReader(html);
try {
kit.read(r, doc, 0);
} catch (Throwable e) {
}
ViewFactory f = kit.getViewFactory();
View hview = f.create(doc.getDefaultRootElement());
View v = new Renderer(c, f, hview);
return v;
}
/**
* Returns the baseline for the html renderer.
*
* @param view the View to get the baseline for
* @param w the width to get the baseline for
* @param h the height to get the baseline for
* @throws IllegalArgumentException if width or height is &lt; 0
* @return baseline or a value &lt; 0 indicating there is no reasonable
* baseline
* @see java.awt.FontMetrics
* @see javax.swing.JComponent#getBaseline(int,int)
* @since 1.6
*/
public static int getHTMLBaseline(View view, int w, int h) {
if (w < 0 || h < 0) {
throw new IllegalArgumentException(
"Width and height must be >= 0");
}
if (view instanceof Renderer) {
return getBaseline(view.getView(0), w, h);
}
return -1;
}
/**
* Gets the baseline for the specified component. This digs out
* the View client property, and if non-null the baseline is calculated
* from it. Otherwise the baseline is the value <code>y + ascent</code>.
*/
static int getBaseline(JComponent c, int y, int ascent,
int w, int h) {
View view = (View)c.getClientProperty(BasicHTML.propertyKey);
if (view != null) {
int baseline = getHTMLBaseline(view, w, h);
if (baseline < 0) {
return baseline;
}
return y + baseline;
}
return y + ascent;
}
/**
* Gets the baseline for the specified View.
*/
static int getBaseline(View view, int w, int h) {
if (hasParagraph(view)) {
view.setSize(w, h);
return getBaseline(view, new Rectangle(0, 0, w, h));
}
return -1;
}
private static int getBaseline(View view, Shape bounds) {
if (view.getViewCount() == 0) {
return -1;
}
AttributeSet attributes = view.getElement().getAttributes();
Object name = null;
if (attributes != null) {
name = attributes.getAttribute(StyleConstants.NameAttribute);
}
int index = 0;
if (name == HTML.Tag.HTML && view.getViewCount() > 1) {
// For html on widgets the header is not visible, skip it.
index++;
}
bounds = view.getChildAllocation(index, bounds);
if (bounds == null) {
return -1;
}
View child = view.getView(index);
if (view instanceof javax.swing.text.ParagraphView) {
Rectangle rect;
if (bounds instanceof Rectangle) {
rect = (Rectangle)bounds;
}
else {
rect = bounds.getBounds();
}
return rect.y + (int)(rect.height *
child.getAlignment(View.Y_AXIS));
}
return getBaseline(child, bounds);
}
private static boolean hasParagraph(View view) {
if (view instanceof javax.swing.text.ParagraphView) {
return true;
}
if (view.getViewCount() == 0) {
return false;
}
AttributeSet attributes = view.getElement().getAttributes();
Object name = null;
if (attributes != null) {
name = attributes.getAttribute(StyleConstants.NameAttribute);
}
int index = 0;
if (name == HTML.Tag.HTML && view.getViewCount() > 1) {
// For html on widgets the header is not visible, skip it.
index = 1;
}
return hasParagraph(view.getView(index));
}
/**
* Check the given string to see if it should trigger the
* html rendering logic in a non-text component that supports
* html rendering.
*/
public static boolean isHTMLString(String s) {
if (s != null) {
if ((s.length() >= 6) && (s.charAt(0) == '<') && (s.charAt(5) == '>')) {
String tag = s.substring(1,5);
return tag.equalsIgnoreCase(propertyKey);
}
}
return false;
}
/**
* Stash the HTML render for the given text into the client
* properties of the given JComponent. If the given text is
* <em>NOT HTML</em> the property will be cleared of any
* renderer.
* <p>
* This method is useful for ComponentUI implementations
* that are static (i.e. shared) and get their state
* entirely from the JComponent.
*/
public static void updateRenderer(JComponent c, String text) {
View value = null;
View oldValue = (View)c.getClientProperty(BasicHTML.propertyKey);
Boolean htmlDisabled = (Boolean) c.getClientProperty(htmlDisable);
if (!(Boolean.TRUE.equals(htmlDisabled)) && BasicHTML.isHTMLString(text)) {
value = BasicHTML.createHTMLView(c, text);
}
if (value != oldValue && oldValue != null) {
for (int i = 0; i < oldValue.getViewCount(); i++) {
oldValue.getView(i).setParent(null);
}
}
c.putClientProperty(BasicHTML.propertyKey, value);
String currentAccessibleNameProperty =
(String) c.getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
String previousParsedText = null;
if (currentAccessibleNameProperty != null && oldValue != null) {
try {
previousParsedText =
(oldValue.getDocument().getText(0, oldValue.getDocument().getLength())).trim();
} catch (BadLocationException e) {
}
}
// AccessibleContext.ACCESSIBLE_NAME_PROPERTY should be set from here only if,
// 1. If AccessibleContext.ACCESSIBLE_NAME_PROPERTY was NOT set before
// i.e. currentAccessibleNameProperty is null. and,
// 2. If AccessibleContext.ACCESSIBLE_NAME_PROPERTY was previously set from this method
// using the value.getDocument().getText().
if (currentAccessibleNameProperty == null ||
currentAccessibleNameProperty.equals(previousParsedText)) {
String parsedText = null;
if (value != null) {
try {
parsedText =
(value.getDocument().getText(0, value.getDocument().getLength())).trim();
} catch (BadLocationException e) {
}
}
c.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, parsedText);
}
}
/**
* If this client property of a JComponent is set to Boolean.TRUE
* the component's 'text' property is never treated as HTML.
*/
private static final String htmlDisable = "html.disable";
/**
* Key to use for the html renderer when stored as a
* client property of a JComponent.
*/
public static final String propertyKey = "html";
/**
* Key stored as a client property to indicate the base that relative
* references are resolved against. For example, lets say you keep
* your images in the directory resources relative to the code path,
* you would use the following the set the base:
* <pre>
* jComponent.putClientProperty(documentBaseKey,
* xxx.class.getResource("resources/"));
* </pre>
*/
public static final String documentBaseKey = "html.base";
static BasicEditorKit getFactory() {
if (basicHTMLFactory == null) {
basicHTMLViewFactory = new BasicHTMLViewFactory();
basicHTMLFactory = new BasicEditorKit();
}
return basicHTMLFactory;
}
/**
* The source of the html renderers
*/
private static BasicEditorKit basicHTMLFactory;
/**
* Creates the Views that visually represent the model.
*/
private static ViewFactory basicHTMLViewFactory;
/**
* Overrides to the default stylesheet. Should consider
* just creating a completely fresh stylesheet.
*/
private static final String styleChanges =
"p { margin-top: 0; margin-bottom: 0; margin-left: 0; margin-right: 0 }" +
"body { margin-top: 0; margin-bottom: 0; margin-left: 0; margin-right: 0 }";
/**
* The views produced for the ComponentUI implementations aren't
* going to be edited and don't need full html support. This kit
* alters the HTMLEditorKit to try and trim things down a bit.
* It does the following:
* <ul>
* <li>It doesn't produce Views for things like comments,
* head, title, unknown tags, etc.
* <li>It installs a different set of css settings from the default
* provided by HTMLEditorKit.
* </ul>
*/
static class BasicEditorKit extends HTMLEditorKit {
/** Shared base style for all documents created by us use. */
private static StyleSheet defaultStyles;
/**
* Overriden to return our own slimmed down style sheet.
*/
public StyleSheet getStyleSheet() {
if (defaultStyles == null) {
defaultStyles = new StyleSheet();
StringReader r = new StringReader(styleChanges);
try {
defaultStyles.loadRules(r, null);
} catch (Throwable e) {
// don't want to die in static initialization...
// just display things wrong.
}
r.close();
defaultStyles.addStyleSheet(super.getStyleSheet());
}
return defaultStyles;
}
/**
* Sets the async policy to flush everything in one chunk, and
* to not display unknown tags.
*/
public Document createDefaultDocument(Font defaultFont,
Color foreground) {
StyleSheet styles = getStyleSheet();
StyleSheet ss = new StyleSheet();
ss.addStyleSheet(styles);
BasicDocument doc = new BasicDocument(ss, defaultFont, foreground);
doc.setAsynchronousLoadPriority(Integer.MAX_VALUE);
doc.setPreservesUnknownTags(false);
return doc;
}
/**
* Returns the ViewFactory that is used to make sure the Views don't
* load in the background.
*/
public ViewFactory getViewFactory() {
return basicHTMLViewFactory;
}
}
/**
* BasicHTMLViewFactory extends HTMLFactory to force images to be loaded
* synchronously.
*/
static class BasicHTMLViewFactory extends HTMLEditorKit.HTMLFactory {
public View create(Element elem) {
View view = null;
try {
setAllowHTMLObject();
view = super.create(elem);
} finally {
clearAllowHTMLObject();
}
if (view instanceof ImageView) {
((ImageView)view).setLoadsSynchronously(true);
}
return view;
}
private static Boolean useOV = null;
private static void setAllowHTMLObject() {
if (useOV == null) {
useOV = java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction(
"swing.html.object"));
};
SwingAccessor.setAllowHTMLObject(useOV);
}
private static void clearAllowHTMLObject() {
SwingAccessor.setAllowHTMLObject(null);
}
}
/**
* The subclass of HTMLDocument that is used as the model. getForeground
* is overridden to return the foreground property from the Component this
* was created for.
*/
static class BasicDocument extends HTMLDocument {
/** The host, that is where we are rendering. */
// private JComponent host;
BasicDocument(StyleSheet s, Font defaultFont, Color foreground) {
super(s);
setPreservesUnknownTags(false);
setFontAndColor(defaultFont, foreground);
}
/**
* Sets the default font and default color. These are set by
* adding a rule for the body that specifies the font and color.
* This allows the html to override these should it wish to have
* a custom font or color.
*/
private void setFontAndColor(Font font, Color fg) {
getStyleSheet().addRule(sun.swing.SwingUtilities2.
displayPropertiesToCSS(font,fg));
}
}
/**
* Root text view that acts as an HTML renderer.
*/
static class Renderer extends View {
Renderer(JComponent c, ViewFactory f, View v) {
super(null);
host = c;
factory = f;
view = v;
view.setParent(this);
// initially layout to the preferred size
setSize(view.getPreferredSpan(X_AXIS), view.getPreferredSpan(Y_AXIS));
}
/**
* Fetches the attributes to use when rendering. At the root
* level there are no attributes. If an attribute is resolved
* up the view hierarchy this is the end of the line.
*/
public AttributeSet getAttributes() {
return null;
}
/**
* Determines the preferred span for this view along an axis.
*
* @param axis may be either X_AXIS or Y_AXIS
* @return the span the view would like to be rendered into.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
*/
public float getPreferredSpan(int axis) {
if (axis == X_AXIS) {
// width currently laid out to
return width;
}
return view.getPreferredSpan(axis);
}
/**
* Determines the minimum span for this view along an axis.
*
* @param axis may be either X_AXIS or Y_AXIS
* @return the span the view would like to be rendered into.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
*/
public float getMinimumSpan(int axis) {
return view.getMinimumSpan(axis);
}
/**
* Determines the maximum span for this view along an axis.
*
* @param axis may be either X_AXIS or Y_AXIS
* @return the span the view would like to be rendered into.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
*/
public float getMaximumSpan(int axis) {
return Integer.MAX_VALUE;
}
/**
* Specifies that a preference has changed.
* Child views can call this on the parent to indicate that
* the preference has changed. The root view routes this to
* invalidate on the hosting component.
* <p>
* This can be called on a different thread from the
* event dispatching thread and is basically unsafe to
* propagate into the component. To make this safe,
* the operation is transferred over to the event dispatching
* thread for completion. It is a design goal that all view
* methods be safe to call without concern for concurrency,
* and this behavior helps make that true.
*
* @param child the child view
* @param width true if the width preference has changed
* @param height true if the height preference has changed
*/
public void preferenceChanged(View child, boolean width, boolean height) {
host.revalidate();
host.repaint();
}
/**
* Determines the desired alignment for this view along an axis.
*
* @param axis may be either X_AXIS or Y_AXIS
* @return the desired alignment, where 0.0 indicates the origin
* and 1.0 the full span away from the origin
*/
public float getAlignment(int axis) {
return view.getAlignment(axis);
}
/**
* Renders the view.
*
* @param g the graphics context
* @param allocation the region to render into
*/
public void paint(Graphics g, Shape allocation) {
Rectangle alloc = allocation.getBounds();
view.setSize(alloc.width, alloc.height);
view.paint(g, allocation);
}
/**
* Sets the view parent.
*
* @param parent the parent view
*/
public void setParent(View parent) {
throw new Error("Can't set parent on root view");
}
/**
* Returns the number of views in this view. Since
* this view simply wraps the root of the view hierarchy
* it has exactly one child.
*
* @return the number of views
* @see #getView
*/
public int getViewCount() {
return 1;
}
/**
* Gets the n-th view in this container.
*
* @param n the number of the view to get
* @return the view
*/
public View getView(int n) {
return view;
}
/**
* Provides a mapping from the document model coordinate space
* to the coordinate space of the view mapped to it.
*
* @param pos the position to convert
* @param a the allocated region to render into
* @return the bounding box of the given position
*/
public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
return view.modelToView(pos, a, b);
}
/**
* Provides a mapping from the document model coordinate space
* to the coordinate space of the view mapped to it.
*
* @param p0 the position to convert >= 0
* @param b0 the bias toward the previous character or the
* next character represented by p0, in case the
* position is a boundary of two views.
* @param p1 the position to convert >= 0
* @param b1 the bias toward the previous character or the
* next character represented by p1, in case the
* position is a boundary of two views.
* @param a the allocated region to render into
* @return the bounding box of the given position is returned
* @exception BadLocationException if the given position does
* not represent a valid location in the associated document
* @exception IllegalArgumentException for an invalid bias argument
* @see View#viewToModel
*/
public Shape modelToView(int p0, Position.Bias b0, int p1,
Position.Bias b1, Shape a) throws BadLocationException {
return view.modelToView(p0, b0, p1, b1, a);
}
/**
* Provides a mapping from the view coordinate space to the logical
* coordinate space of the model.
*
* @param x x coordinate of the view location to convert
* @param y y coordinate of the view location to convert
* @param a the allocated region to render into
* @return the location within the model that best represents the
* given point in the view
*/
public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
return view.viewToModel(x, y, a, bias);
}
/**
* Returns the document model underlying the view.
*
* @return the model
*/
public Document getDocument() {
return view.getDocument();
}
/**
* Returns the starting offset into the model for this view.
*
* @return the starting offset
*/
public int getStartOffset() {
return view.getStartOffset();
}
/**
* Returns the ending offset into the model for this view.
*
* @return the ending offset
*/
public int getEndOffset() {
return view.getEndOffset();
}
/**
* Gets the element that this view is mapped to.
*
* @return the view
*/
public Element getElement() {
return view.getElement();
}
/**
* Sets the view size.
*
* @param width the width
* @param height the height
*/
public void setSize(float width, float height) {
this.width = (int) width;
view.setSize(width, height);
}
/**
* Fetches the container hosting the view. This is useful for
* things like scheduling a repaint, finding out the host
* components font, etc. The default implementation
* of this is to forward the query to the parent view.
*
* @return the container
*/
public Container getContainer() {
return host;
}
/**
* Fetches the factory to be used for building the
* various view fragments that make up the view that
* represents the model. This is what determines
* how the model will be represented. This is implemented
* to fetch the factory provided by the associated
* EditorKit.
*
* @return the factory
*/
public ViewFactory getViewFactory() {
return factory;
}
private int width;
private View view;
private ViewFactory factory;
private JComponent host;
}
}

View File

@@ -0,0 +1,222 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.*;
import javax.swing.plaf.UIResource;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Component;
import java.awt.Polygon;
import java.io.Serializable;
/**
* Factory object that can vend Icons appropriate for the basic L &amp; F.
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author David Kloba
* @author Georges Saab
*/
public class BasicIconFactory implements Serializable
{
private static Icon frame_icon;
private static Icon checkBoxIcon;
private static Icon radioButtonIcon;
private static Icon checkBoxMenuItemIcon;
private static Icon radioButtonMenuItemIcon;
private static Icon menuItemCheckIcon;
private static Icon menuItemArrowIcon;
private static Icon menuArrowIcon;
public static Icon getMenuItemCheckIcon() {
if (menuItemCheckIcon == null) {
menuItemCheckIcon = new MenuItemCheckIcon();
}
return menuItemCheckIcon;
}
public static Icon getMenuItemArrowIcon() {
if (menuItemArrowIcon == null) {
menuItemArrowIcon = new MenuItemArrowIcon();
}
return menuItemArrowIcon;
}
public static Icon getMenuArrowIcon() {
if (menuArrowIcon == null) {
menuArrowIcon = new MenuArrowIcon();
}
return menuArrowIcon;
}
public static Icon getCheckBoxIcon() {
if (checkBoxIcon == null) {
checkBoxIcon = new CheckBoxIcon();
}
return checkBoxIcon;
}
public static Icon getRadioButtonIcon() {
if (radioButtonIcon == null) {
radioButtonIcon = new RadioButtonIcon();
}
return radioButtonIcon;
}
public static Icon getCheckBoxMenuItemIcon() {
if (checkBoxMenuItemIcon == null) {
checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
}
return checkBoxMenuItemIcon;
}
public static Icon getRadioButtonMenuItemIcon() {
if (radioButtonMenuItemIcon == null) {
radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
}
return radioButtonMenuItemIcon;
}
public static Icon createEmptyFrameIcon() {
if(frame_icon == null)
frame_icon = new EmptyFrameIcon();
return frame_icon;
}
private static class EmptyFrameIcon implements Icon, Serializable {
int height = 16;
int width = 14;
public void paintIcon(Component c, Graphics g, int x, int y) {
}
public int getIconWidth() { return width; }
public int getIconHeight() { return height; }
};
private static class CheckBoxIcon implements Icon, Serializable
{
final static int csize = 13;
public void paintIcon(Component c, Graphics g, int x, int y) {
}
public int getIconWidth() {
return csize;
}
public int getIconHeight() {
return csize;
}
}
private static class RadioButtonIcon implements Icon, UIResource, Serializable
{
public void paintIcon(Component c, Graphics g, int x, int y) {
}
public int getIconWidth() {
return 13;
}
public int getIconHeight() {
return 13;
}
} // end class RadioButtonIcon
private static class CheckBoxMenuItemIcon implements Icon, UIResource, Serializable
{
public void paintIcon(Component c, Graphics g, int x, int y) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
boolean isSelected = model.isSelected();
if (isSelected) {
g.drawLine(x+7, y+1, x+7, y+3);
g.drawLine(x+6, y+2, x+6, y+4);
g.drawLine(x+5, y+3, x+5, y+5);
g.drawLine(x+4, y+4, x+4, y+6);
g.drawLine(x+3, y+5, x+3, y+7);
g.drawLine(x+2, y+4, x+2, y+6);
g.drawLine(x+1, y+3, x+1, y+5);
}
}
public int getIconWidth() { return 9; }
public int getIconHeight() { return 9; }
} // End class CheckBoxMenuItemIcon
private static class RadioButtonMenuItemIcon implements Icon, UIResource, Serializable
{
public void paintIcon(Component c, Graphics g, int x, int y) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
if (b.isSelected() == true) {
g.fillOval(x+1, y+1, getIconWidth(), getIconHeight());
}
}
public int getIconWidth() { return 6; }
public int getIconHeight() { return 6; }
} // End class RadioButtonMenuItemIcon
private static class MenuItemCheckIcon implements Icon, UIResource, Serializable{
public void paintIcon(Component c, Graphics g, int x, int y) {
}
public int getIconWidth() { return 9; }
public int getIconHeight() { return 9; }
} // End class MenuItemCheckIcon
private static class MenuItemArrowIcon implements Icon, UIResource, Serializable {
public void paintIcon(Component c, Graphics g, int x, int y) {
}
public int getIconWidth() { return 4; }
public int getIconHeight() { return 8; }
} // End class MenuItemArrowIcon
private static class MenuArrowIcon implements Icon, UIResource, Serializable {
public void paintIcon(Component c, Graphics g, int x, int y) {
Polygon p = new Polygon();
p.addPoint(x, y);
p.addPoint(x+getIconWidth(), y+getIconHeight()/2);
p.addPoint(x, y+getIconHeight());
g.fillPolygon(p);
}
public int getIconWidth() { return 4; }
public int getIconHeight() { return 8; }
} // End class MenuArrowIcon
}

View File

@@ -0,0 +1,804 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.swing.SwingUtilities2;
import java.awt.*;
import java.awt.event.*;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.event.InternalFrameEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import sun.swing.DefaultLookup;
import static sun.swing.SwingUtilities2.AA_TEXT_PROPERTY_KEY;
/**
* The class that manages a basic title bar
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author David Kloba
* @author Steve Wilson
*/
public class BasicInternalFrameTitlePane extends JComponent
{
protected JMenuBar menuBar;
protected JButton iconButton;
protected JButton maxButton;
protected JButton closeButton;
protected JMenu windowMenu;
protected JInternalFrame frame;
protected Color selectedTitleColor;
protected Color selectedTextColor;
protected Color notSelectedTitleColor;
protected Color notSelectedTextColor;
protected Icon maxIcon;
protected Icon minIcon;
protected Icon iconIcon;
protected Icon closeIcon;
protected PropertyChangeListener propertyChangeListener;
protected Action closeAction;
protected Action maximizeAction;
protected Action iconifyAction;
protected Action restoreAction;
protected Action moveAction;
protected Action sizeAction;
// These constants are not used in JDK code
protected static final String CLOSE_CMD =
UIManager.getString("InternalFrameTitlePane.closeButtonText");
protected static final String ICONIFY_CMD =
UIManager.getString("InternalFrameTitlePane.minimizeButtonText");
protected static final String RESTORE_CMD =
UIManager.getString("InternalFrameTitlePane.restoreButtonText");
protected static final String MAXIMIZE_CMD =
UIManager.getString("InternalFrameTitlePane.maximizeButtonText");
protected static final String MOVE_CMD =
UIManager.getString("InternalFrameTitlePane.moveButtonText");
protected static final String SIZE_CMD =
UIManager.getString("InternalFrameTitlePane.sizeButtonText");
private String closeButtonToolTip;
private String iconButtonToolTip;
private String restoreButtonToolTip;
private String maxButtonToolTip;
private Handler handler;
public BasicInternalFrameTitlePane(JInternalFrame f) {
frame = f;
installTitlePane();
}
protected void installTitlePane() {
installDefaults();
installListeners();
createActions();
enableActions();
createActionMap();
setLayout(createLayout());
assembleSystemMenu();
createButtons();
addSubComponents();
updateProperties();
}
private void updateProperties() {
final Object aaTextInfo = frame.getClientProperty(AA_TEXT_PROPERTY_KEY);
putClientProperty(AA_TEXT_PROPERTY_KEY, aaTextInfo);
}
protected void addSubComponents() {
add(menuBar);
add(iconButton);
add(maxButton);
add(closeButton);
}
protected void createActions() {
maximizeAction = new MaximizeAction();
iconifyAction = new IconifyAction();
closeAction = new CloseAction();
restoreAction = new RestoreAction();
moveAction = new MoveAction();
sizeAction = new SizeAction();
}
ActionMap createActionMap() {
ActionMap map = new ActionMapUIResource();
map.put("showSystemMenu", new ShowSystemMenuAction(true));
map.put("hideSystemMenu", new ShowSystemMenuAction(false));
return map;
}
protected void installListeners() {
if( propertyChangeListener == null ) {
propertyChangeListener = createPropertyChangeListener();
}
frame.addPropertyChangeListener(propertyChangeListener);
}
protected void uninstallListeners() {
frame.removePropertyChangeListener(propertyChangeListener);
handler = null;
}
protected void installDefaults() {
maxIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
minIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
iconIcon = UIManager.getIcon("InternalFrame.iconifyIcon");
closeIcon = UIManager.getIcon("InternalFrame.closeIcon");
selectedTitleColor = UIManager.getColor("InternalFrame.activeTitleBackground");
selectedTextColor = UIManager.getColor("InternalFrame.activeTitleForeground");
notSelectedTitleColor = UIManager.getColor("InternalFrame.inactiveTitleBackground");
notSelectedTextColor = UIManager.getColor("InternalFrame.inactiveTitleForeground");
setFont(UIManager.getFont("InternalFrame.titleFont"));
closeButtonToolTip =
UIManager.getString("InternalFrame.closeButtonToolTip");
iconButtonToolTip =
UIManager.getString("InternalFrame.iconButtonToolTip");
restoreButtonToolTip =
UIManager.getString("InternalFrame.restoreButtonToolTip");
maxButtonToolTip =
UIManager.getString("InternalFrame.maxButtonToolTip");
}
protected void uninstallDefaults() {
}
protected void createButtons() {
iconButton = new NoFocusButton(
"InternalFrameTitlePane.iconifyButtonAccessibleName",
"InternalFrameTitlePane.iconifyButtonOpacity");
iconButton.addActionListener(iconifyAction);
if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
iconButton.setToolTipText(iconButtonToolTip);
}
maxButton = new NoFocusButton(
"InternalFrameTitlePane.maximizeButtonAccessibleName",
"InternalFrameTitlePane.maximizeButtonOpacity");
maxButton.addActionListener(maximizeAction);
closeButton = new NoFocusButton(
"InternalFrameTitlePane.closeButtonAccessibleName",
"InternalFrameTitlePane.closeButtonOpacity");
closeButton.addActionListener(closeAction);
if (closeButtonToolTip != null && closeButtonToolTip.length() != 0) {
closeButton.setToolTipText(closeButtonToolTip);
}
setButtonIcons();
}
protected void setButtonIcons() {
if(frame.isIcon()) {
if (minIcon != null) {
iconButton.setIcon(minIcon);
}
if (restoreButtonToolTip != null &&
restoreButtonToolTip.length() != 0) {
iconButton.setToolTipText(restoreButtonToolTip);
}
if (maxIcon != null) {
maxButton.setIcon(maxIcon);
}
if (maxButtonToolTip != null && maxButtonToolTip.length() != 0) {
maxButton.setToolTipText(maxButtonToolTip);
}
} else if (frame.isMaximum()) {
if (iconIcon != null) {
iconButton.setIcon(iconIcon);
}
if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
iconButton.setToolTipText(iconButtonToolTip);
}
if (minIcon != null) {
maxButton.setIcon(minIcon);
}
if (restoreButtonToolTip != null &&
restoreButtonToolTip.length() != 0) {
maxButton.setToolTipText(restoreButtonToolTip);
}
} else {
if (iconIcon != null) {
iconButton.setIcon(iconIcon);
}
if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
iconButton.setToolTipText(iconButtonToolTip);
}
if (maxIcon != null) {
maxButton.setIcon(maxIcon);
}
if (maxButtonToolTip != null && maxButtonToolTip.length() != 0) {
maxButton.setToolTipText(maxButtonToolTip);
}
}
if (closeIcon != null) {
closeButton.setIcon(closeIcon);
}
}
protected void assembleSystemMenu() {
menuBar = createSystemMenuBar();
windowMenu = createSystemMenu();
menuBar.add(windowMenu);
addSystemMenuItems(windowMenu);
enableActions();
}
protected void addSystemMenuItems(JMenu systemMenu) {
JMenuItem mi = systemMenu.add(restoreAction);
mi.setMnemonic(getButtonMnemonic("restore"));
mi = systemMenu.add(moveAction);
mi.setMnemonic(getButtonMnemonic("move"));
mi = systemMenu.add(sizeAction);
mi.setMnemonic(getButtonMnemonic("size"));
mi = systemMenu.add(iconifyAction);
mi.setMnemonic(getButtonMnemonic("minimize"));
mi = systemMenu.add(maximizeAction);
mi.setMnemonic(getButtonMnemonic("maximize"));
systemMenu.add(new JSeparator());
mi = systemMenu.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 JMenu createSystemMenu() {
return new JMenu(" ");
}
protected JMenuBar createSystemMenuBar() {
menuBar = new SystemMenuBar();
menuBar.setBorderPainted(false);
return menuBar;
}
protected void showSystemMenu(){
// windowMenu.setPopupMenuVisible(true);
// windowMenu.setVisible(true);
windowMenu.doClick();
}
public void paintComponent(Graphics g) {
paintTitleBackground(g);
if(frame.getTitle() != null) {
boolean isSelected = frame.isSelected();
Font f = g.getFont();
g.setFont(getFont());
if(isSelected)
g.setColor(selectedTextColor);
else
g.setColor(notSelectedTextColor);
// Center text vertically.
FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g);
int baseline = (getHeight() + fm.getAscent() - fm.getLeading() -
fm.getDescent()) / 2;
int titleX;
Rectangle r = new Rectangle(0, 0, 0, 0);
if (frame.isIconifiable()) r = iconButton.getBounds();
else if (frame.isMaximizable()) r = maxButton.getBounds();
else if (frame.isClosable()) r = closeButton.getBounds();
int titleW;
String title = frame.getTitle();
if( BasicGraphicsUtils.isLeftToRight(frame) ) {
if (r.x == 0) r.x = frame.getWidth()-frame.getInsets().right;
titleX = menuBar.getX() + menuBar.getWidth() + 2;
titleW = r.x - titleX - 3;
title = getTitle(frame.getTitle(), fm, titleW);
} else {
titleX = menuBar.getX() - 2
- SwingUtilities2.stringWidth(frame,fm,title);
}
SwingUtilities2.drawString(frame, g, title, titleX, baseline);
g.setFont(f);
}
}
/**
* Invoked from paintComponent.
* Paints the background of the titlepane. All text and icons will
* then be rendered on top of this background.
* @param g the graphics to use to render the background
* @since 1.4
*/
protected void paintTitleBackground(Graphics g) {
boolean isSelected = frame.isSelected();
if(isSelected)
g.setColor(selectedTitleColor);
else
g.setColor(notSelectedTitleColor);
g.fillRect(0, 0, getWidth(), getHeight());
}
protected String getTitle(String text, FontMetrics fm, int availTextWidth) {
return SwingUtilities2.clipStringIfNecessary(
frame, fm, text, availTextWidth);
}
/**
* Post a WINDOW_CLOSING-like event to the frame, so that it can
* be treated like a regular Frame.
*/
protected void postClosingEvent(JInternalFrame frame) {
InternalFrameEvent e = new InternalFrameEvent(
frame, InternalFrameEvent.INTERNAL_FRAME_CLOSING);
// Try posting event, unless there's a SecurityManager.
try {
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
} catch (SecurityException se) {
frame.dispatchEvent(e);
}
}
protected void enableActions() {
restoreAction.setEnabled(frame.isMaximum() || frame.isIcon());
maximizeAction.setEnabled(
(frame.isMaximizable() && !frame.isMaximum() && !frame.isIcon()) ||
(frame.isMaximizable() && frame.isIcon()));
iconifyAction.setEnabled(frame.isIconifiable() && !frame.isIcon());
closeAction.setEnabled(frame.isClosable());
sizeAction.setEnabled(false);
moveAction.setEnabled(false);
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler();
}
return handler;
}
protected PropertyChangeListener createPropertyChangeListener() {
return getHandler();
}
protected LayoutManager createLayout() {
return getHandler();
}
private class Handler implements LayoutManager, PropertyChangeListener {
//
// PropertyChangeListener
//
public void propertyChange(PropertyChangeEvent evt) {
String prop = evt.getPropertyName();
if (prop == JInternalFrame.IS_SELECTED_PROPERTY) {
repaint();
return;
}
if (prop == JInternalFrame.IS_ICON_PROPERTY ||
prop == JInternalFrame.IS_MAXIMUM_PROPERTY) {
setButtonIcons();
enableActions();
return;
}
if ("closable" == prop) {
if (evt.getNewValue() == Boolean.TRUE) {
add(closeButton);
} else {
remove(closeButton);
}
} else if ("maximizable" == prop) {
if (evt.getNewValue() == Boolean.TRUE) {
add(maxButton);
} else {
remove(maxButton);
}
} else if ("iconable" == prop) {
if (evt.getNewValue() == Boolean.TRUE) {
add(iconButton);
} else {
remove(iconButton);
}
}
enableActions();
revalidate();
repaint();
}
//
// 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) {
// Calculate width.
int width = 22;
if (frame.isClosable()) {
width += 19;
}
if (frame.isMaximizable()) {
width += 19;
}
if (frame.isIconifiable()) {
width += 19;
}
FontMetrics fm = frame.getFontMetrics(getFont());
String frameTitle = frame.getTitle();
int title_w = frameTitle != null ? SwingUtilities2.stringWidth(
frame, 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 = SwingUtilities2.stringWidth(
frame, fm, frameTitle.substring(0, 3) + "...");
width += (title_w < subtitle_w) ? title_w : subtitle_w;
} else {
width += title_w;
}
// Calculate height.
Icon icon = frame.getFrameIcon();
int fontHeight = fm.getHeight();
fontHeight += 2;
int iconHeight = 0;
if (icon != null) {
// SystemMenuBar forces the icon to be 16x16 or less.
iconHeight = Math.min(icon.getIconHeight(), 16);
}
iconHeight += 2;
int height = Math.max( fontHeight, iconHeight );
Dimension dim = new Dimension(width, height);
// Take into account the border insets if any.
if (getBorder() != null) {
Insets insets = getBorder().getBorderInsets(c);
dim.height += insets.top + insets.bottom;
dim.width += insets.left + insets.right;
}
return dim;
}
public void layoutContainer(Container c) {
boolean leftToRight = BasicGraphicsUtils.isLeftToRight(frame);
int w = getWidth();
int h = getHeight();
int x;
int buttonHeight = closeButton.getIcon().getIconHeight();
Icon icon = frame.getFrameIcon();
int iconHeight = 0;
if (icon != null) {
iconHeight = icon.getIconHeight();
}
x = (leftToRight) ? 2 : w - 16 - 2;
menuBar.setBounds(x, (h - iconHeight) / 2, 16, 16);
x = (leftToRight) ? w - 16 - 2 : 2;
if (frame.isClosable()) {
closeButton.setBounds(x, (h - buttonHeight) / 2, 16, 14);
x += (leftToRight) ? -(16 + 2) : 16 + 2;
}
if (frame.isMaximizable()) {
maxButton.setBounds(x, (h - buttonHeight) / 2, 16, 14);
x += (leftToRight) ? -(16 + 2) : 16 + 2;
}
if (frame.isIconifiable()) {
iconButton.setBounds(x, (h - buttonHeight) / 2, 16, 14);
}
}
}
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class PropertyChangeHandler implements PropertyChangeListener {
// NOTE: This class exists only for backward compatibility. All
// its functionality has been moved into Handler. If you need to add
// new functionality add it to the Handler, but make sure this
// class calls into the Handler.
public void propertyChange(PropertyChangeEvent evt) {
getHandler().propertyChange(evt);
}
}
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class TitlePaneLayout implements LayoutManager {
// NOTE: This class exists only for backward compatibility. All
// its functionality has been moved into Handler. If you need to add
// new functionality add it to the Handler, but make sure this
// class calls into the Handler.
public void addLayoutComponent(String name, Component c) {
getHandler().addLayoutComponent(name, c);
}
public void removeLayoutComponent(Component c) {
getHandler().removeLayoutComponent(c);
}
public Dimension preferredLayoutSize(Container c) {
return getHandler().preferredLayoutSize(c);
}
public Dimension minimumLayoutSize(Container c) {
return getHandler().minimumLayoutSize(c);
}
public void layoutContainer(Container c) {
getHandler().layoutContainer(c);
}
}
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class CloseAction extends AbstractAction {
public CloseAction() {
super(UIManager.getString(
"InternalFrameTitlePane.closeButtonText"));
}
public void actionPerformed(ActionEvent e) {
if(frame.isClosable()) {
frame.doDefaultCloseAction();
}
}
} // end CloseAction
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class MaximizeAction extends AbstractAction {
public MaximizeAction() {
super(UIManager.getString(
"InternalFrameTitlePane.maximizeButtonText"));
}
public void actionPerformed(ActionEvent evt) {
if (frame.isMaximizable()) {
if (frame.isMaximum() && frame.isIcon()) {
try {
frame.setIcon(false);
} catch (PropertyVetoException e) { }
} else if (!frame.isMaximum()) {
try {
frame.setMaximum(true);
} catch (PropertyVetoException e) { }
} else {
try {
frame.setMaximum(false);
} catch (PropertyVetoException e) { }
}
}
}
}
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class IconifyAction extends AbstractAction {
public IconifyAction() {
super(UIManager.getString(
"InternalFrameTitlePane.minimizeButtonText"));
}
public void actionPerformed(ActionEvent e) {
if(frame.isIconifiable()) {
if(!frame.isIcon()) {
try { frame.setIcon(true); } catch (PropertyVetoException e1) { }
} else{
try { frame.setIcon(false); } catch (PropertyVetoException e1) { }
}
}
}
} // end IconifyAction
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class RestoreAction extends AbstractAction {
public RestoreAction() {
super(UIManager.getString(
"InternalFrameTitlePane.restoreButtonText"));
}
public void actionPerformed(ActionEvent evt) {
if (frame.isMaximizable() && frame.isMaximum() && frame.isIcon()) {
try {
frame.setIcon(false);
} catch (PropertyVetoException e) { }
} else if (frame.isMaximizable() && frame.isMaximum()) {
try {
frame.setMaximum(false);
} catch (PropertyVetoException e) { }
} else if (frame.isIconifiable() && frame.isIcon()) {
try {
frame.setIcon(false);
} catch (PropertyVetoException e) { }
}
}
}
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class MoveAction extends AbstractAction {
public MoveAction() {
super(UIManager.getString(
"InternalFrameTitlePane.moveButtonText"));
}
public void actionPerformed(ActionEvent e) {
// This action is currently undefined
}
} // end MoveAction
/*
* Handles showing and hiding the system menu.
*/
private class ShowSystemMenuAction extends AbstractAction {
private boolean show; // whether to show the menu
public ShowSystemMenuAction(boolean show) {
this.show = show;
}
public void actionPerformed(ActionEvent e) {
if (show) {
windowMenu.doClick();
} else {
windowMenu.setVisible(false);
}
}
}
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class SizeAction extends AbstractAction {
public SizeAction() {
super(UIManager.getString(
"InternalFrameTitlePane.sizeButtonText"));
}
public void actionPerformed(ActionEvent e) {
// This action is currently undefined
}
} // end SizeAction
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <code>Foo</code>.
*/
public class SystemMenuBar extends JMenuBar {
public boolean isFocusTraversable() { return false; }
public void requestFocus() {}
public void paint(Graphics g) {
Icon icon = frame.getFrameIcon();
if (icon == null) {
icon = (Icon)DefaultLookup.get(frame, frame.getUI(),
"InternalFrame.icon");
}
if (icon != null) {
// Resize to 16x16 if necessary.
if (icon instanceof ImageIcon && (icon.getIconWidth() > 16 || icon.getIconHeight() > 16)) {
Image img = ((ImageIcon)icon).getImage();
((ImageIcon)icon).setImage(img.getScaledInstance(16, 16, Image.SCALE_SMOOTH));
}
icon.paintIcon(this, g, 0, 0);
}
}
public boolean isOpaque() {
return true;
}
} // end SystemMenuBar
private class NoFocusButton extends JButton {
private String uiKey;
public NoFocusButton(String uiKey, String opacityKey) {
setFocusPainted(false);
setMargin(new Insets(0,0,0,0));
this.uiKey = uiKey;
Object opacity = UIManager.get(opacityKey);
if (opacity instanceof Boolean) {
setOpaque(((Boolean)opacity).booleanValue());
}
}
public boolean isFocusTraversable() { return false; }
public void requestFocus() {}
public AccessibleContext getAccessibleContext() {
AccessibleContext ac = super.getAccessibleContext();
if (uiKey != null) {
ac.setAccessibleName(UIManager.getString(uiKey));
uiKey = null;
}
return ac;
}
} // end NoFocusButton
} // End Title Pane Class

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,609 @@
/*
* Copyright (c) 1997, 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.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.InputEvent;
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;
/**
* A Windows L&amp;F implementation of LabelUI. This implementation
* is completely static, i.e. there's only one UIView implementation
* that's shared by all JLabel objects.
*
* @author Hans Muller
*/
public class BasicLabelUI extends LabelUI implements PropertyChangeListener
{
/**
* The default <code>BasicLabelUI</code> instance. This field might
* not be used. To change the default instance use a subclass which
* overrides the <code>createUI</code> method, and place that class
* name in defaults table under the key "LabelUI".
*/
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));
}
/**
* Forwards the call to SwingUtilities.layoutCompoundLabel().
* This method is here so that a subclass could do Label specific
* layout and to shorten the method name a little.
*
* @param label an instance of {@code JLabel}
* @param fontMetrics a font metrics
* @param text a text
* @param icon an icon
* @param viewR a bounding rectangle to lay out label
* @param iconR a bounding rectangle to lay out icon
* @param textR a bounding rectangle to lay out text
* @return a possibly clipped version of the compound labels string
* @see SwingUtilities#layoutCompoundLabel
*/
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());
}
/**
* Paint clippedText at textX, textY with the labels foreground color.
*
* @param l an instance of {@code JLabel}
* @param g an instance of {@code Graphics}
* @param s a text
* @param textX an X coordinate
* @param textY an Y coordinate
* @see #paint
* @see #paintDisabledText
*/
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);
}
/**
* Paint clippedText at textX, textY with background.lighter() and then
* shifted down and to the right by one pixel with background.darker().
*
* @param l an instance of {@code JLabel}
* @param g an instance of {@code Graphics}
* @param s a text
* @param textX an X coordinate
* @param textY an Y coordinate
* @see #paint
* @see #paintEnabledText
*/
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);
}
/**
* Paints the label text with the foreground color, if the label is opaque
* then paints the entire background with the background color. The Label
* text is drawn by {@link #paintEnabledText} or {@link #paintDisabledText}.
* The locations of the label parts are computed by {@link #layoutCL}.
*
* @see #paintEnabledText
* @see #paintDisabledText
* @see #layoutCL
*/
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;
}
}
/**
* @return getPreferredSize(c)
*/
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;
}
/**
* @return getPreferredSize(c)
*/
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;
}
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
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);
}
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
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);
}
/**
* Installs default properties.
*
* @param c an instance of {@code JLabel}
*/
protected void installDefaults(JLabel c){
LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground", "Label.font");
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
}
/**
* Registers listeners.
*
* @param c an instance of {@code JLabel}
*/
protected void installListeners(JLabel c){
c.addPropertyChangeListener(this);
}
/**
* Registers components.
*
* @param c an instance of {@code JLabel}
*/
protected void installComponents(JLabel c){
BasicHTML.updateRenderer(c, c.getText());
c.setInheritsPopupMenu(true);
}
/**
* Registers keyboard actions.
*
* @param l an instance of {@code JLabel}
*/
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");
inputMap.put(KeyStroke.getKeyStroke(dka,
SwingUtilities2.setAltGraphMask (
BasicLookAndFeel.getFocusAcceleratorKeyMask()),
false), "press");
}
else {
InputMap inputMap = SwingUtilities.getUIInputMap
(l, JComponent.WHEN_IN_FOCUSED_WINDOW);
if (inputMap != null) {
inputMap.clear();
}
}
}
/**
* Uninstalls default properties.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallDefaults(JLabel c){
}
/**
* Unregisters listeners.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallListeners(JLabel c){
c.removePropertyChangeListener(this);
}
/**
* Unregisters components.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallComponents(JLabel c){
BasicHTML.updateRenderer(c, "");
}
/**
* Unregisters keyboard actions.
*
* @param c an instance of {@code JLabel}
*/
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);
}
/**
* Returns an instance of {@code BasicLabelUI}.
*
* @param c a component
* @return an instance of {@code BasicLabelUI}
*/
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
// into the JLabel is html source.
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
// prevent unwanted keyTyped events from getting to other components.
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, SwingUtilities2.setAltGraphMask (
BasicLookAndFeel.getFocusAcceleratorKeyMask()));
// Need this when the sticky keys are enabled
putOnRelease(inputMap, dka, 0);
// Need this if ALT is released before the accelerator
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) {
// inputMap should never be null.
int dka = label.getDisplayedMnemonic();
removeOnRelease(inputMap, dka, BasicLookAndFeel
.getFocusAcceleratorKeyMask());
removeOnRelease(inputMap, dka,
SwingUtilities2.setAltGraphMask (
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,
SwingUtilities2.setAltGraphMask (
BasicLookAndFeel.getFocusAcceleratorKeyMask()));
// Need this when the sticky keys are enabled
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,
SwingUtilities2.setAltGraphMask (
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));
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,238 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.swing.DefaultLookup;
import sun.swing.UIAction;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.border.*;
import javax.swing.plaf.*;
/**
* A default L&amp;F implementation of MenuBarUI. This implementation
* is a "combined" view/controller.
*
* @author Georges Saab
* @author David Karlton
* @author Arnaud Weber
*/
public class BasicMenuBarUI extends MenuBarUI {
protected JMenuBar menuBar = null;
protected ContainerListener containerListener;
protected ChangeListener changeListener;
private Handler handler;
public static ComponentUI createUI(JComponent x) {
return new BasicMenuBarUI();
}
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.TAKE_FOCUS));
}
public void installUI(JComponent c) {
menuBar = (JMenuBar) c;
installDefaults();
installListeners();
installKeyboardActions();
}
protected void installDefaults() {
if (menuBar.getLayout() == null ||
menuBar.getLayout() instanceof UIResource) {
menuBar.setLayout(new DefaultMenuLayout(menuBar,BoxLayout.LINE_AXIS));
}
LookAndFeel.installProperty(menuBar, "opaque", Boolean.TRUE);
LookAndFeel.installBorder(menuBar,"MenuBar.border");
LookAndFeel.installColorsAndFont(menuBar,
"MenuBar.background",
"MenuBar.foreground",
"MenuBar.font");
}
protected void installListeners() {
containerListener = createContainerListener();
changeListener = createChangeListener();
for (int i = 0; i < menuBar.getMenuCount(); i++) {
JMenu menu = menuBar.getMenu(i);
if (menu!=null)
menu.getModel().addChangeListener(changeListener);
}
menuBar.addContainerListener(containerListener);
}
protected void installKeyboardActions() {
InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
SwingUtilities.replaceUIInputMap(menuBar,
JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
LazyActionMap.installLazyActionMap(menuBar, BasicMenuBarUI.class,
"MenuBar.actionMap");
}
InputMap getInputMap(int condition) {
if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
Object[] bindings = (Object[])DefaultLookup.get
(menuBar, this, "MenuBar.windowBindings");
if (bindings != null) {
return LookAndFeel.makeComponentInputMap(menuBar, bindings);
}
}
return null;
}
public void uninstallUI(JComponent c) {
uninstallDefaults();
uninstallListeners();
uninstallKeyboardActions();
menuBar = null;
}
protected void uninstallDefaults() {
if (menuBar!=null) {
LookAndFeel.uninstallBorder(menuBar);
}
}
protected void uninstallListeners() {
menuBar.removeContainerListener(containerListener);
for (int i = 0; i < menuBar.getMenuCount(); i++) {
JMenu menu = menuBar.getMenu(i);
if (menu !=null)
menu.getModel().removeChangeListener(changeListener);
}
containerListener = null;
changeListener = null;
handler = null;
}
protected void uninstallKeyboardActions() {
SwingUtilities.replaceUIInputMap(menuBar, JComponent.
WHEN_IN_FOCUSED_WINDOW, null);
SwingUtilities.replaceUIActionMap(menuBar, null);
}
protected ContainerListener createContainerListener() {
return getHandler();
}
protected ChangeListener createChangeListener() {
return getHandler();
}
private Handler getHandler() {
if (handler == null) {
handler = new Handler();
}
return handler;
}
public Dimension getMinimumSize(JComponent c) {
return null;
}
public Dimension getMaximumSize(JComponent c) {
return null;
}
private class Handler implements ChangeListener, ContainerListener {
//
// ChangeListener
//
public void stateChanged(ChangeEvent e) {
int i,c;
for(i=0,c = menuBar.getMenuCount() ; i < c ; i++) {
JMenu menu = menuBar.getMenu(i);
if(menu !=null && menu.isSelected()) {
menuBar.getSelectionModel().setSelectedIndex(i);
break;
}
}
}
//
// ContainerListener
//
public void componentAdded(ContainerEvent e) {
Component c = e.getChild();
if (c instanceof JMenu)
((JMenu)c).getModel().addChangeListener(changeListener);
}
public void componentRemoved(ContainerEvent e) {
Component c = e.getChild();
if (c instanceof JMenu)
((JMenu)c).getModel().removeChangeListener(changeListener);
}
}
private static class Actions extends UIAction {
private static final String TAKE_FOCUS = "takeFocus";
Actions(String key) {
super(key);
}
public void actionPerformed(ActionEvent e) {
// TAKE_FOCUS
JMenuBar menuBar = (JMenuBar)e.getSource();
MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
MenuElement me[];
MenuElement subElements[];
JMenu menu = menuBar.getMenu(0);
if (menu!=null) {
me = new MenuElement[3];
me[0] = (MenuElement) menuBar;
me[1] = (MenuElement) menu;
me[2] = (MenuElement) menu.getPopupMenu();
defaultManager.setSelectedPath(me);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,632 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.swing.DefaultLookup;
import sun.swing.UIAction;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.border.*;
import java.util.Arrays;
import java.util.ArrayList;
/**
* A default L&amp;F implementation of MenuUI. This implementation
* is a "combined" view/controller.
*
* @author Georges Saab
* @author David Karlton
* @author Arnaud Weber
*/
public class BasicMenuUI extends BasicMenuItemUI
{
protected ChangeListener changeListener;
protected MenuListener menuListener;
private int lastMnemonic = 0;
/** Uses as the parent of the windowInputMap when selected. */
private InputMap selectedWindowInputMap;
/* diagnostic aids -- should be false for production builds. */
private static final boolean TRACE = false; // trace creates and disposes
private static final boolean VERBOSE = false; // show reuse hits/misses
private static final boolean DEBUG = false; // show bad params, misc.
private static boolean crossMenuMnemonic = true;
public static ComponentUI createUI(JComponent x) {
return new BasicMenuUI();
}
static void loadActionMap(LazyActionMap map) {
BasicMenuItemUI.loadActionMap(map);
map.put(new Actions(Actions.SELECT, null, true));
}
protected void installDefaults() {
super.installDefaults();
updateDefaultBackgroundColor();
((JMenu)menuItem).setDelay(200);
crossMenuMnemonic = UIManager.getBoolean("Menu.crossMenuMnemonic");
}
protected String getPropertyPrefix() {
return "Menu";
}
protected void installListeners() {
super.installListeners();
if (changeListener == null)
changeListener = createChangeListener(menuItem);
if (changeListener != null)
menuItem.addChangeListener(changeListener);
if (menuListener == null)
menuListener = createMenuListener(menuItem);
if (menuListener != null)
((JMenu)menuItem).addMenuListener(menuListener);
}
protected void installKeyboardActions() {
super.installKeyboardActions();
updateMnemonicBinding();
}
void installLazyActionMap() {
LazyActionMap.installLazyActionMap(menuItem, BasicMenuUI.class,
getPropertyPrefix() + ".actionMap");
}
void updateMnemonicBinding() {
int mnemonic = menuItem.getModel().getMnemonic();
int[] shortcutKeys = (int[])DefaultLookup.get(menuItem, this,
"Menu.shortcutKeys");
if (shortcutKeys == null) {
shortcutKeys = new int[] {KeyEvent.ALT_MASK,
KeyEvent.ALT_MASK | KeyEvent.ALT_GRAPH_MASK};
}
if (mnemonic == lastMnemonic) {
return;
}
InputMap windowInputMap = SwingUtilities.getUIInputMap(
menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW);
if (lastMnemonic != 0 && windowInputMap != null) {
for (int shortcutKey : shortcutKeys) {
windowInputMap.remove(KeyStroke.getKeyStroke
(lastMnemonic, shortcutKey, false));
}
}
if (mnemonic != 0) {
if (windowInputMap == null) {
windowInputMap = createInputMap(JComponent.
WHEN_IN_FOCUSED_WINDOW);
SwingUtilities.replaceUIInputMap(menuItem, JComponent.
WHEN_IN_FOCUSED_WINDOW, windowInputMap);
}
for (int shortcutKey : shortcutKeys) {
windowInputMap.put(KeyStroke.getKeyStroke(mnemonic,
shortcutKey, false), "selectMenu");
}
}
lastMnemonic = mnemonic;
}
protected void uninstallKeyboardActions() {
super.uninstallKeyboardActions();
lastMnemonic = 0;
}
protected MouseInputListener createMouseInputListener(JComponent c) {
return getHandler();
}
protected MenuListener createMenuListener(JComponent c) {
return null;
}
protected ChangeListener createChangeListener(JComponent c) {
return null;
}
protected PropertyChangeListener createPropertyChangeListener(JComponent c) {
return getHandler();
}
BasicMenuItemUI.Handler getHandler() {
if (handler == null) {
handler = new Handler();
}
return handler;
}
protected void uninstallDefaults() {
menuItem.setArmed(false);
menuItem.setSelected(false);
menuItem.resetKeyboardActions();
super.uninstallDefaults();
}
protected void uninstallListeners() {
super.uninstallListeners();
if (changeListener != null)
menuItem.removeChangeListener(changeListener);
if (menuListener != null)
((JMenu)menuItem).removeMenuListener(menuListener);
changeListener = null;
menuListener = null;
handler = null;
}
protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) {
return getHandler();
}
protected MenuKeyListener createMenuKeyListener(JComponent c) {
return (MenuKeyListener)getHandler();
}
public Dimension getMaximumSize(JComponent c) {
if (((JMenu)menuItem).isTopLevelMenu() == true) {
Dimension d = c.getPreferredSize();
return new Dimension(d.width, Short.MAX_VALUE);
}
return null;
}
protected void setupPostTimer(JMenu menu) {
Timer timer = new Timer(menu.getDelay(), new Actions(
Actions.SELECT, menu,false));
timer.setRepeats(false);
timer.start();
}
private static void appendPath(MenuElement[] path, MenuElement elem) {
MenuElement newPath[] = new MenuElement[path.length+1];
System.arraycopy(path, 0, newPath, 0, path.length);
newPath[path.length] = elem;
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
}
private static class Actions extends UIAction {
private static final String SELECT = "selectMenu";
// NOTE: This will be null if the action is registered in the
// ActionMap. For the timer use it will be non-null.
private JMenu menu;
private boolean force=false;
Actions(String key, JMenu menu, boolean shouldForce) {
super(key);
this.menu = menu;
this.force = shouldForce;
}
private JMenu getMenu(ActionEvent e) {
if (e.getSource() instanceof JMenu) {
return (JMenu)e.getSource();
}
return menu;
}
public void actionPerformed(ActionEvent e) {
JMenu menu = getMenu(e);
if (!crossMenuMnemonic) {
JPopupMenu pm = BasicPopupMenuUI.getLastPopup();
if (pm != null && pm != menu.getParent()) {
return;
}
}
final MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
if(force) {
Container cnt = menu.getParent();
if(cnt != null && cnt instanceof JMenuBar) {
MenuElement me[];
MenuElement subElements[];
subElements = menu.getPopupMenu().getSubElements();
if(subElements.length > 0) {
me = new MenuElement[4];
me[0] = (MenuElement) cnt;
me[1] = menu;
me[2] = menu.getPopupMenu();
me[3] = subElements[0];
} else {
me = new MenuElement[3];
me[0] = (MenuElement)cnt;
me[1] = menu;
me[2] = menu.getPopupMenu();
}
defaultManager.setSelectedPath(me);
}
} else {
MenuElement path[] = defaultManager.getSelectedPath();
if(path.length > 0 && path[path.length-1] == menu) {
appendPath(path, menu.getPopupMenu());
}
}
}
public boolean isEnabled(Object c) {
if (c instanceof JMenu) {
return ((JMenu)c).isEnabled();
}
return true;
}
}
/*
* Set the background color depending on whether this is a toplevel menu
* in a menubar or a submenu of another menu.
*/
private void updateDefaultBackgroundColor() {
if (!UIManager.getBoolean("Menu.useMenuBarBackgroundForTopLevel")) {
return;
}
JMenu menu = (JMenu)menuItem;
if (menu.getBackground() instanceof UIResource) {
if (menu.isTopLevelMenu()) {
menu.setBackground(UIManager.getColor("MenuBar.background"));
} else {
menu.setBackground(UIManager.getColor(getPropertyPrefix() + ".background"));
}
}
}
/**
* Instantiated and used by a menu item to handle the current menu selection
* from mouse events. A MouseInputHandler processes and forwards all mouse events
* to a shared instance of the MenuSelectionManager.
* <p>
* This class is protected so that it can be subclassed by other look and
* feels to implement their own mouse handling behavior. All overridden
* methods should call the parent methods so that the menu selection
* is correct.
*
* @see javax.swing.MenuSelectionManager
* @since 1.4
*/
protected class MouseInputHandler implements MouseInputListener {
// NOTE: This class exists only for backward compatibility. All
// its functionality has been moved into Handler. If you need to add
// new functionality add it to the Handler, but make sure this
// class calls into the Handler.
public void mouseClicked(MouseEvent e) {
getHandler().mouseClicked(e);
}
/**
* Invoked when the mouse has been clicked on the menu. This
* method clears or sets the selection path of the
* MenuSelectionManager.
*
* @param e the mouse event
*/
public void mousePressed(MouseEvent e) {
getHandler().mousePressed(e);
}
/**
* Invoked when the mouse has been released on the menu. Delegates the
* mouse event to the MenuSelectionManager.
*
* @param e the mouse event
*/
public void mouseReleased(MouseEvent e) {
getHandler().mouseReleased(e);
}
/**
* Invoked when the cursor enters the menu. This method sets the selected
* path for the MenuSelectionManager and handles the case
* in which a menu item is used to pop up an additional menu, as in a
* hierarchical menu system.
*
* @param e the mouse event; not used
*/
public void mouseEntered(MouseEvent e) {
getHandler().mouseEntered(e);
}
public void mouseExited(MouseEvent e) {
getHandler().mouseExited(e);
}
/**
* Invoked when a mouse button is pressed on the menu and then dragged.
* Delegates the mouse event to the MenuSelectionManager.
*
* @param e the mouse event
* @see java.awt.event.MouseMotionListener#mouseDragged
*/
public void mouseDragged(MouseEvent e) {
getHandler().mouseDragged(e);
}
public void mouseMoved(MouseEvent e) {
getHandler().mouseMoved(e);
}
}
/**
* As of Java 2 platform 1.4, this previously undocumented class
* is now obsolete. KeyBindings are now managed by the popup menu.
*/
public class ChangeHandler implements ChangeListener {
public JMenu menu;
public BasicMenuUI ui;
public boolean isSelected = false;
public Component wasFocused;
public ChangeHandler(JMenu m, BasicMenuUI ui) {
menu = m;
this.ui = ui;
}
public void stateChanged(ChangeEvent e) { }
}
private class Handler extends BasicMenuItemUI.Handler implements MenuKeyListener {
//
// PropertyChangeListener
//
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName() == AbstractButton.
MNEMONIC_CHANGED_PROPERTY) {
updateMnemonicBinding();
}
else {
if (e.getPropertyName().equals("ancestor")) {
updateDefaultBackgroundColor();
}
super.propertyChange(e);
}
}
//
// MouseInputListener
//
public void mouseClicked(MouseEvent e) {
}
/**
* Invoked when the mouse has been clicked on the menu. This
* method clears or sets the selection path of the
* MenuSelectionManager.
*
* @param e the mouse event
*/
public void mousePressed(MouseEvent e) {
JMenu menu = (JMenu)menuItem;
if (!menu.isEnabled())
return;
MenuSelectionManager manager =
MenuSelectionManager.defaultManager();
if(menu.isTopLevelMenu()) {
if(menu.isSelected() && menu.getPopupMenu().isShowing()) {
manager.clearSelectedPath();
} else {
Container cnt = menu.getParent();
if(cnt != null && cnt instanceof JMenuBar) {
MenuElement me[] = new MenuElement[2];
me[0]=(MenuElement)cnt;
me[1]=menu;
manager.setSelectedPath(me);
}
}
}
MenuElement selectedPath[] = manager.getSelectedPath();
if (selectedPath.length > 0 &&
selectedPath[selectedPath.length-1] != menu.getPopupMenu()) {
if(menu.isTopLevelMenu() ||
menu.getDelay() == 0) {
appendPath(selectedPath, menu.getPopupMenu());
} else {
setupPostTimer(menu);
}
}
}
/**
* Invoked when the mouse has been released on the menu. Delegates the
* mouse event to the MenuSelectionManager.
*
* @param e the mouse event
*/
public void mouseReleased(MouseEvent e) {
JMenu menu = (JMenu)menuItem;
if (!menu.isEnabled())
return;
MenuSelectionManager manager =
MenuSelectionManager.defaultManager();
manager.processMouseEvent(e);
if (!e.isConsumed())
manager.clearSelectedPath();
}
/**
* Invoked when the cursor enters the menu. This method sets the selected
* path for the MenuSelectionManager and handles the case
* in which a menu item is used to pop up an additional menu, as in a
* hierarchical menu system.
*
* @param e the mouse event; not used
*/
public void mouseEntered(MouseEvent e) {
JMenu menu = (JMenu)menuItem;
// only disable the menu highlighting if it's disabled and the property isn't
// true. This allows disabled rollovers to work in WinL&F
if (!menu.isEnabled() && !UIManager.getBoolean("MenuItem.disabledAreNavigable")) {
return;
}
MenuSelectionManager manager =
MenuSelectionManager.defaultManager();
MenuElement selectedPath[] = manager.getSelectedPath();
if (!menu.isTopLevelMenu()) {
if(!(selectedPath.length > 0 &&
selectedPath[selectedPath.length-1] ==
menu.getPopupMenu())) {
if(menu.getDelay() == 0) {
appendPath(getPath(), menu.getPopupMenu());
} else {
manager.setSelectedPath(getPath());
setupPostTimer(menu);
}
}
} else {
if(selectedPath.length > 0 &&
selectedPath[0] == menu.getParent()) {
MenuElement newPath[] = new MenuElement[3];
// A top level menu's parent is by definition
// a JMenuBar
newPath[0] = (MenuElement)menu.getParent();
newPath[1] = menu;
if (BasicPopupMenuUI.getLastPopup() != null) {
newPath[2] = menu.getPopupMenu();
}
manager.setSelectedPath(newPath);
}
}
}
public void mouseExited(MouseEvent e) {
}
/**
* Invoked when a mouse button is pressed on the menu and then dragged.
* Delegates the mouse event to the MenuSelectionManager.
*
* @param e the mouse event
* @see java.awt.event.MouseMotionListener#mouseDragged
*/
public void mouseDragged(MouseEvent e) {
JMenu menu = (JMenu)menuItem;
if (!menu.isEnabled())
return;
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
public void mouseMoved(MouseEvent e) {
}
//
// MenuDragHandler
//
public void menuDragMouseEntered(MenuDragMouseEvent e) {}
public void menuDragMouseDragged(MenuDragMouseEvent e) {
if (menuItem.isEnabled() == false)
return;
MenuSelectionManager manager = e.getMenuSelectionManager();
MenuElement path[] = e.getPath();
Point p = e.getPoint();
if(p.x >= 0 && p.x < menuItem.getWidth() &&
p.y >= 0 && p.y < menuItem.getHeight()) {
JMenu menu = (JMenu)menuItem;
MenuElement selectedPath[] = manager.getSelectedPath();
if(!(selectedPath.length > 0 &&
selectedPath[selectedPath.length-1] ==
menu.getPopupMenu())) {
if(menu.isTopLevelMenu() ||
menu.getDelay() == 0 ||
e.getID() == MouseEvent.MOUSE_DRAGGED) {
appendPath(path, menu.getPopupMenu());
} else {
manager.setSelectedPath(path);
setupPostTimer(menu);
}
}
} else if(e.getID() == MouseEvent.MOUSE_RELEASED) {
Component comp = manager.componentForPoint(e.getComponent(), e.getPoint());
if (comp == null)
manager.clearSelectedPath();
}
}
public void menuDragMouseExited(MenuDragMouseEvent e) {}
public void menuDragMouseReleased(MenuDragMouseEvent e) {}
//
// MenuKeyListener
//
/**
* Open the Menu
*/
public void menuKeyTyped(MenuKeyEvent e) {
if (!crossMenuMnemonic && BasicPopupMenuUI.getLastPopup() != null) {
// when crossMenuMnemonic is not set, we don't open a toplevel
// menu if another toplevel menu is already open
return;
}
if (BasicPopupMenuUI.getPopups().size() != 0) {
//Fix 6939261: to return in case not on the main menu
//and has a pop-up.
//after return code will be handled in BasicPopupMenuUI.java
return;
}
char key = Character.toLowerCase((char)menuItem.getMnemonic());
MenuElement path[] = e.getPath();
if (key == Character.toLowerCase(e.getKeyChar())) {
JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu();
ArrayList newList = new ArrayList(Arrays.asList(path));
newList.add(popupMenu);
MenuElement subs[] = popupMenu.getSubElements();
MenuElement sub =
BasicPopupMenuUI.findEnabledChild(subs, -1, true);
if(sub != null) {
newList.add(sub);
}
MenuSelectionManager manager = e.getMenuSelectionManager();
MenuElement newPath[] = new MenuElement[0];;
newPath = (MenuElement[]) newList.toArray(newPath);
manager.setSelectedPath(newPath);
e.consume();
}
}
public void menuKeyPressed(MenuKeyEvent e) {}
public void menuKeyReleased(MenuKeyEvent e) {}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 1998, 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.basic;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.awt.*;
import java.awt.event.*;
/**
* BasicPanel implementation
*
* @author Steve Wilson
*/
public class BasicPanelUI extends PanelUI {
// Shared UI object
private static PanelUI panelUI;
public static ComponentUI createUI(JComponent c) {
if(panelUI == null) {
panelUI = new BasicPanelUI();
}
return panelUI;
}
public void installUI(JComponent c) {
JPanel p = (JPanel)c;
super.installUI(p);
installDefaults(p);
}
public void uninstallUI(JComponent c) {
JPanel p = (JPanel)c;
uninstallDefaults(p);
super.uninstallUI(c);
}
protected void installDefaults(JPanel p) {
LookAndFeel.installColorsAndFont(p,
"Panel.background",
"Panel.foreground",
"Panel.font");
LookAndFeel.installBorder(p,"Panel.border");
LookAndFeel.installProperty(p, "opaque", Boolean.TRUE);
}
protected void uninstallDefaults(JPanel p) {
LookAndFeel.uninstallBorder(p);
}
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
Border border = c.getBorder();
if (border instanceof AbstractBorder) {
return ((AbstractBorder)border).getBaseline(c, width, height);
}
return -1;
}
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public Component.BaselineResizeBehavior getBaselineResizeBehavior(
JComponent c) {
super.getBaselineResizeBehavior(c);
Border border = c.getBorder();
if (border instanceof AbstractBorder) {
return ((AbstractBorder)border).getBaselineResizeBehavior(c);
}
return Component.BaselineResizeBehavior.OTHER;
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 1997, 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.basic;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
/**
* Provides the Windows look and feel for a password field.
* The only difference from the standard text field is that
* the view of the text is simply a string of the echo
* character as specified in JPasswordField, rather than the
* real text contained in the field.
*
* @author Timothy Prinzing
*/
public class BasicPasswordFieldUI extends BasicTextFieldUI {
/**
* Creates a UI for a JPasswordField.
*
* @param c the JPasswordField
* @return the UI
*/
public static ComponentUI createUI(JComponent c) {
return new BasicPasswordFieldUI();
}
/**
* 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")
*/
protected String getPropertyPrefix() {
return "PasswordField";
}
/**
* Installs the necessary properties on the JPasswordField.
* @since 1.6
*/
protected void installDefaults() {
super.installDefaults();
String prefix = getPropertyPrefix();
Character echoChar = (Character)UIManager.getDefaults().get(prefix + ".echoChar");
if(echoChar != null) {
LookAndFeel.installProperty(getComponent(), "echoChar", echoChar);
}
}
/**
* Creates a view (PasswordView) for an element.
*
* @param elem the element
* @return the view
*/
public View create(Element elem) {
return new PasswordView(elem);
}
/**
* Create the action map for Password Field. This map provides
* same actions for double mouse click and
* and for triple mouse click (see bug 4231444).
*/
ActionMap createActionMap() {
ActionMap map = super.createActionMap();
if (map.get(DefaultEditorKit.selectWordAction) != null) {
Action a = map.get(DefaultEditorKit.selectLineAction);
if (a != null) {
map.remove(DefaultEditorKit.selectWordAction);
map.put(DefaultEditorKit.selectWordAction, a);
}
}
return map;
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 1998, 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.basic;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.plaf.ComponentUI;
/**
* A Basic L&amp;F implementation of PopupMenuSeparatorUI. This implementation
* is a "combined" view/controller.
*
* @author Jeff Shapiro
*/
public class BasicPopupMenuSeparatorUI extends BasicSeparatorUI
{
public static ComponentUI createUI( JComponent c )
{
return new BasicPopupMenuSeparatorUI();
}
public void paint( Graphics g, JComponent c )
{
Dimension s = c.getSize();
g.setColor( c.getForeground() );
g.drawLine( 0, 0, s.width, 0 );
g.setColor( c.getBackground() );
g.drawLine( 0, 1, s.width, 1 );
}
public Dimension getPreferredSize( JComponent c )
{
return new Dimension( 0, 2 );
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 1997, 2001, 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.basic;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.*;
import javax.swing.border.*;
/**
* BasicRadioButtonMenuItem implementation
*
* @author Georges Saab
* @author David Karlton
*/
public class BasicRadioButtonMenuItemUI extends BasicMenuItemUI
{
public static ComponentUI createUI(JComponent b) {
return new BasicRadioButtonMenuItemUI();
}
protected String getPropertyPrefix() {
return "RadioButtonMenuItem";
}
public void processMouseEvent(JMenuItem item,MouseEvent e,MenuElement path[],MenuSelectionManager manager) {
Point p = e.getPoint();
if(p.x >= 0 && p.x < item.getWidth() &&
p.y >= 0 && p.y < item.getHeight()) {
if(e.getID() == MouseEvent.MOUSE_RELEASED) {
manager.clearSelectedPath();
item.doClick(0);
item.setArmed(false);
} else
manager.setSelectedPath(path);
} else if(item.getModel().isArmed()) {
MenuElement newPath[] = new MenuElement[path.length-1];
int i,c;
for(i=0,c=path.length-1;i<c;i++)
newPath[i] = path[i];
manager.setSelectedPath(newPath);
}
}
}

View File

@@ -0,0 +1,613 @@
/*
* Copyright (c) 1997, 2019, 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.basic;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.text.View;
import sun.swing.SwingUtilities2;
import sun.awt.AppContext;
import java.util.Enumeration;
import java.util.HashSet;
/**
* RadioButtonUI implementation for BasicRadioButtonUI
*
* @author Jeff Dinkins
*/
public class BasicRadioButtonUI extends BasicToggleButtonUI
{
private static final Object BASIC_RADIO_BUTTON_UI_KEY = new Object();
/**
* The icon.
*/
protected Icon icon;
private boolean defaults_initialized = false;
private final static String propertyPrefix = "RadioButton" + ".";
private KeyListener keyListener = null;
// ********************************
// Create PLAF
// ********************************
/**
* Returns an instance of {@code BasicRadioButtonUI}.
*
* @param b a component
* @return an instance of {@code BasicRadioButtonUI}
*/
public static ComponentUI createUI(JComponent b) {
AppContext appContext = AppContext.getAppContext();
BasicRadioButtonUI radioButtonUI =
(BasicRadioButtonUI) appContext.get(BASIC_RADIO_BUTTON_UI_KEY);
if (radioButtonUI == null) {
radioButtonUI = new BasicRadioButtonUI();
appContext.put(BASIC_RADIO_BUTTON_UI_KEY, radioButtonUI);
}
return radioButtonUI;
}
@Override
protected String getPropertyPrefix() {
return propertyPrefix;
}
// ********************************
// Install PLAF
// ********************************
@Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
if(!defaults_initialized) {
icon = UIManager.getIcon(getPropertyPrefix() + "icon");
defaults_initialized = true;
}
}
// ********************************
// Uninstall PLAF
// ********************************
@Override
protected void uninstallDefaults(AbstractButton b) {
super.uninstallDefaults(b);
defaults_initialized = false;
}
/**
* Returns the default icon.
*
* @return the default icon
*/
public Icon getDefaultIcon() {
return icon;
}
// ********************************
// Install Listeners
// ********************************
@Override
protected void installListeners(AbstractButton button) {
super.installListeners(button);
// Only for JRadioButton
if (!(button instanceof JRadioButton))
return;
keyListener = createKeyListener();
button.addKeyListener(keyListener);
// Need to get traversal key event
button.setFocusTraversalKeysEnabled(false);
// Map actions to the arrow keys
button.getActionMap().put("Previous", new SelectPreviousBtn());
button.getActionMap().put("Next", new SelectNextBtn());
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
put(KeyStroke.getKeyStroke("UP"), "Previous");
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
put(KeyStroke.getKeyStroke("DOWN"), "Next");
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
put(KeyStroke.getKeyStroke("LEFT"), "Previous");
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
put(KeyStroke.getKeyStroke("RIGHT"), "Next");
}
// ********************************
// UnInstall Listeners
// ********************************
@Override
protected void uninstallListeners(AbstractButton button) {
super.uninstallListeners(button);
// Only for JRadioButton
if (!(button instanceof JRadioButton))
return;
// Unmap actions from the arrow keys
button.getActionMap().remove("Previous");
button.getActionMap().remove("Next");
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.remove(KeyStroke.getKeyStroke("UP"));
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.remove(KeyStroke.getKeyStroke("DOWN"));
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.remove(KeyStroke.getKeyStroke("LEFT"));
button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.remove(KeyStroke.getKeyStroke("RIGHT"));
if (keyListener != null) {
button.removeKeyListener(keyListener);
keyListener = null;
}
}
/* These Dimensions/Rectangles are allocated once for all
* RadioButtonUI.paint() calls. Re-using rectangles
* rather than allocating them in each paint call substantially
* reduced the time it took paint to run. Obviously, this
* method can't be re-entered.
*/
private static Dimension size = new Dimension();
private static Rectangle viewRect = new Rectangle();
private static Rectangle iconRect = new Rectangle();
private static Rectangle textRect = new Rectangle();
/**
* paint the radio button
*/
@Override
public synchronized void paint(Graphics g, JComponent c) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Font f = c.getFont();
g.setFont(f);
FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f);
Insets i = c.getInsets();
size = b.getSize(size);
viewRect.x = i.left;
viewRect.y = i.top;
viewRect.width = size.width - (i.right + viewRect.x);
viewRect.height = size.height - (i.bottom + viewRect.y);
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
textRect.x = textRect.y = textRect.width = textRect.height = 0;
Icon altIcon = b.getIcon();
Icon selectedIcon = null;
Icon disabledIcon = null;
String text = SwingUtilities.layoutCompoundLabel(
c, fm, b.getText(), altIcon != null ? altIcon : getDefaultIcon(),
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect,
b.getText() == null ? 0 : b.getIconTextGap());
// fill background
if(c.isOpaque()) {
g.setColor(b.getBackground());
g.fillRect(0,0, size.width, size.height);
}
// Paint the radio button
if(altIcon != null) {
if(!model.isEnabled()) {
if(model.isSelected()) {
altIcon = b.getDisabledSelectedIcon();
} else {
altIcon = b.getDisabledIcon();
}
} else if(model.isPressed() && model.isArmed()) {
altIcon = b.getPressedIcon();
if(altIcon == null) {
// Use selected icon
altIcon = b.getSelectedIcon();
}
} else if(model.isSelected()) {
if(b.isRolloverEnabled() && model.isRollover()) {
altIcon = b.getRolloverSelectedIcon();
if (altIcon == null) {
altIcon = b.getSelectedIcon();
}
} else {
altIcon = b.getSelectedIcon();
}
} else if(b.isRolloverEnabled() && model.isRollover()) {
altIcon = b.getRolloverIcon();
}
if(altIcon == null) {
altIcon = b.getIcon();
}
altIcon.paintIcon(c, g, iconRect.x, iconRect.y);
} else {
getDefaultIcon().paintIcon(c, g, iconRect.x, iconRect.y);
}
// Draw the Text
if(text != null) {
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, textRect);
} else {
paintText(g, b, textRect, text);
}
if(b.hasFocus() && b.isFocusPainted() &&
textRect.width > 0 && textRect.height > 0 ) {
paintFocus(g, textRect, size);
}
}
}
/**
* Paints focused radio button.
*
* @param g an instance of {@code Graphics}
* @param textRect bounds
* @param size the size of radio button
*/
protected void paintFocus(Graphics g, Rectangle textRect, Dimension size) {
}
/* These Insets/Rectangles are allocated once for all
* RadioButtonUI.getPreferredSize() calls. Re-using rectangles
* rather than allocating them in each call substantially
* reduced the time it took getPreferredSize() to run. Obviously,
* this method can't be re-entered.
*/
private static Rectangle prefViewRect = new Rectangle();
private static Rectangle prefIconRect = new Rectangle();
private static Rectangle prefTextRect = new Rectangle();
private static Insets prefInsets = new Insets(0, 0, 0, 0);
/**
* The preferred size of the radio button
*/
@Override
public Dimension getPreferredSize(JComponent c) {
if(c.getComponentCount() > 0) {
return null;
}
AbstractButton b = (AbstractButton) c;
String text = b.getText();
Icon buttonIcon = b.getIcon();
if(buttonIcon == null) {
buttonIcon = getDefaultIcon();
}
Font font = b.getFont();
FontMetrics fm = b.getFontMetrics(font);
prefViewRect.x = prefViewRect.y = 0;
prefViewRect.width = Short.MAX_VALUE;
prefViewRect.height = Short.MAX_VALUE;
prefIconRect.x = prefIconRect.y = prefIconRect.width = prefIconRect.height = 0;
prefTextRect.x = prefTextRect.y = prefTextRect.width = prefTextRect.height = 0;
SwingUtilities.layoutCompoundLabel(
c, fm, text, buttonIcon,
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
prefViewRect, prefIconRect, prefTextRect,
text == null ? 0 : b.getIconTextGap());
// find the union of the icon and text rects (from Rectangle.java)
int x1 = Math.min(prefIconRect.x, prefTextRect.x);
int x2 = Math.max(prefIconRect.x + prefIconRect.width,
prefTextRect.x + prefTextRect.width);
int y1 = Math.min(prefIconRect.y, prefTextRect.y);
int y2 = Math.max(prefIconRect.y + prefIconRect.height,
prefTextRect.y + prefTextRect.height);
int width = x2 - x1;
int height = y2 - y1;
prefInsets = b.getInsets(prefInsets);
width += prefInsets.left + prefInsets.right;
height += prefInsets.top + prefInsets.bottom;
return new Dimension(width, height);
}
/////////////////////////// Private functions ////////////////////////
/**
* Creates the key listener to handle tab navigation in JRadioButton Group.
*/
private KeyListener createKeyListener() {
if (keyListener == null) {
keyListener = new KeyHandler();
}
return keyListener;
}
private boolean isValidRadioButtonObj(Object obj) {
return ((obj instanceof JRadioButton) &&
((JRadioButton) obj).isVisible() &&
((JRadioButton) obj).isEnabled());
}
/**
* Select radio button based on "Previous" or "Next" operation
*
* @param event, the event object.
* @param next, indicate if it's next one
*/
private void selectRadioButton(ActionEvent event, boolean next) {
// Get the source of the event.
Object eventSrc = event.getSource();
// Check whether the source is JRadioButton, it so, whether it is visible
if (!isValidRadioButtonObj(eventSrc))
return;
ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc);
btnGroupInfo.selectNewButton(next);
}
/////////////////////////// Inner Classes ////////////////////////
@SuppressWarnings("serial")
private class SelectPreviousBtn extends AbstractAction {
public SelectPreviousBtn() {
super("Previous");
}
public void actionPerformed(ActionEvent e) {
BasicRadioButtonUI.this.selectRadioButton(e, false);
}
}
@SuppressWarnings("serial")
private class SelectNextBtn extends AbstractAction{
public SelectNextBtn() {
super("Next");
}
public void actionPerformed(ActionEvent e) {
BasicRadioButtonUI.this.selectRadioButton(e, true);
}
}
/**
* ButtonGroupInfo, used to get related info in button group
* for given radio button
*/
private class ButtonGroupInfo {
JRadioButton activeBtn = null;
JRadioButton firstBtn = null;
JRadioButton lastBtn = null;
JRadioButton previousBtn = null;
JRadioButton nextBtn = null;
HashSet<JRadioButton> btnsInGroup = null;
boolean srcFound = false;
public ButtonGroupInfo(JRadioButton btn) {
activeBtn = btn;
btnsInGroup = new HashSet<JRadioButton>();
}
// Check if given object is in the button group
boolean containsInGroup(Object obj){
return btnsInGroup.contains(obj);
}
// Check if the next object to gain focus belongs
// to the button group or not
Component getFocusTransferBaseComponent(boolean next){
Component focusBaseComp = activeBtn;
Container container = focusBaseComp.getFocusCycleRootAncestor();
if (container != null) {
FocusTraversalPolicy policy = container.getFocusTraversalPolicy();
Component comp = next ? policy.getComponentAfter(container, activeBtn)
: policy.getComponentBefore(container, activeBtn);
// If next component in the button group, use last/first button as base focus
// otherwise, use the activeBtn as the base focus
if (containsInGroup(comp)) {
focusBaseComp = next ? lastBtn : firstBtn;
}
}
return focusBaseComp;
}
boolean getButtonGroupInfo() {
if (activeBtn == null)
return false;
btnsInGroup.clear();
// Get the button model from the source.
ButtonModel model = activeBtn.getModel();
if (!(model instanceof DefaultButtonModel))
return false;
// If the button model is DefaultButtonModel, and use it, otherwise return.
DefaultButtonModel bm = (DefaultButtonModel) model;
// get the ButtonGroup of the button from the button model
ButtonGroup group = bm.getGroup();
if (group == null)
return false;
// Get all the buttons in the group
Enumeration<AbstractButton> e = group.getElements();
if (e == null)
return false;
while (e.hasMoreElements()) {
AbstractButton curElement = e.nextElement();
if (!isValidRadioButtonObj(curElement))
continue;
btnsInGroup.add((JRadioButton) curElement);
// If firstBtn is not set yet, curElement is that first button
if (null == firstBtn)
firstBtn = (JRadioButton) curElement;
if (activeBtn == curElement)
srcFound = true;
else if (!srcFound) {
// The source has not been yet found and the current element
// is the last previousBtn
previousBtn = (JRadioButton) curElement;
} else if (nextBtn == null) {
// The source has been found and the current element
// is the next valid button of the list
nextBtn = (JRadioButton) curElement;
}
// Set new last "valid" JRadioButton of the list
lastBtn = (JRadioButton) curElement;
}
return true;
}
/**
* Find the new radio button that focus needs to be
* moved to in the group, select the button
*
* @param next, indicate if it's arrow up/left or down/right
*/
void selectNewButton(boolean next) {
if (!getButtonGroupInfo())
return;
if (srcFound) {
JRadioButton newSelectedBtn = null;
if (next) {
// Select Next button. Cycle to the first button if the source
// button is the last of the group.
newSelectedBtn = (null == nextBtn) ? firstBtn : nextBtn;
} else {
// Select previous button. Cycle to the last button if the source
// button is the first button of the group.
newSelectedBtn = (null == previousBtn) ? lastBtn : previousBtn;
}
if (newSelectedBtn != null &&
(newSelectedBtn != activeBtn)) {
ButtonModel btnModel = newSelectedBtn.getModel();
btnModel.setPressed(true);
btnModel.setArmed(true);
newSelectedBtn.requestFocusInWindow();
newSelectedBtn.setSelected(true);
btnModel.setPressed(false);
btnModel.setArmed(false);
}
}
}
/**
* Find the button group the passed in JRadioButton belongs to, and
* move focus to next component of the last button in the group
* or previous component of first button
*
* @param next, indicate if jump to next component or previous
*/
void jumpToNextComponent(boolean next) {
if (!getButtonGroupInfo()){
// In case the button does not belong to any group, it needs
// to be treated as a component
if (activeBtn != null){
lastBtn = activeBtn;
firstBtn = activeBtn;
}
else
return;
}
// Update the component we will use as base to transfer
// focus from
JComponent compTransferFocusFrom = activeBtn;
// If next component in the parent window is not in
// the button group, current active button will be
// base, otherwise, the base will be first or last
// button in the button group
Component focusBase = getFocusTransferBaseComponent(next);
if (focusBase != null){
if (next) {
KeyboardFocusManager.
getCurrentKeyboardFocusManager().focusNextComponent(focusBase);
} else {
KeyboardFocusManager.
getCurrentKeyboardFocusManager().focusPreviousComponent(focusBase);
}
}
}
}
/**
* Radiobutton KeyListener
*/
private class KeyHandler implements KeyListener {
// This listener checks if the key event is a KeyEvent.VK_TAB
// or shift + KeyEvent.VK_TAB event on a radio button, consume the event
// if so and move the focus to next/previous component
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_TAB) {
// Get the source of the event.
Object eventSrc = e.getSource();
// Check whether the source is a visible and enabled JRadioButton
if (isValidRadioButtonObj(eventSrc)) {
e.consume();
ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc);
btnGroupInfo.jumpToNextComponent(!e.isShiftDown());
}
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
}

View File

@@ -0,0 +1,248 @@
/*
* Copyright (c) 1999, 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.basic;
import java.awt.event.ActionEvent;
import java.awt.KeyboardFocusManager;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.plaf.*;
import sun.swing.DefaultLookup;
import sun.swing.UIAction;
/**
* Basic implementation of RootPaneUI, there is one shared between all
* JRootPane instances.
*
* @author Scott Violet
* @since 1.3
*/
public class BasicRootPaneUI extends RootPaneUI implements
PropertyChangeListener {
private static RootPaneUI rootPaneUI = new BasicRootPaneUI();
public static ComponentUI createUI(JComponent c) {
return rootPaneUI;
}
public void installUI(JComponent c) {
installDefaults((JRootPane)c);
installComponents((JRootPane)c);
installListeners((JRootPane)c);
installKeyboardActions((JRootPane)c);
}
public void uninstallUI(JComponent c) {
uninstallDefaults((JRootPane)c);
uninstallComponents((JRootPane)c);
uninstallListeners((JRootPane)c);
uninstallKeyboardActions((JRootPane)c);
}
protected void installDefaults(JRootPane c){
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
}
protected void installComponents(JRootPane root) {
}
protected void installListeners(JRootPane root) {
root.addPropertyChangeListener(this);
}
protected void installKeyboardActions(JRootPane root) {
InputMap km = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, root);
SwingUtilities.replaceUIInputMap(root,
JComponent.WHEN_IN_FOCUSED_WINDOW, km);
km = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
root);
SwingUtilities.replaceUIInputMap(root,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, km);
LazyActionMap.installLazyActionMap(root, BasicRootPaneUI.class,
"RootPane.actionMap");
updateDefaultButtonBindings(root);
}
protected void uninstallDefaults(JRootPane root) {
}
protected void uninstallComponents(JRootPane root) {
}
protected void uninstallListeners(JRootPane root) {
root.removePropertyChangeListener(this);
}
protected void uninstallKeyboardActions(JRootPane root) {
SwingUtilities.replaceUIInputMap(root, JComponent.
WHEN_IN_FOCUSED_WINDOW, null);
SwingUtilities.replaceUIActionMap(root, null);
}
InputMap getInputMap(int condition, JComponent c) {
if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
return (InputMap)DefaultLookup.get(c, this,
"RootPane.ancestorInputMap");
}
if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
return createInputMap(condition, c);
}
return null;
}
ComponentInputMap createInputMap(int condition, JComponent c) {
return new RootPaneInputMap(c);
}
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.PRESS));
map.put(new Actions(Actions.RELEASE));
map.put(new Actions(Actions.POST_POPUP));
}
/**
* Invoked when the default button property has changed. This reloads
* the bindings from the defaults table with name
* <code>RootPane.defaultButtonWindowKeyBindings</code>.
*/
void updateDefaultButtonBindings(JRootPane root) {
InputMap km = SwingUtilities.getUIInputMap(root, JComponent.
WHEN_IN_FOCUSED_WINDOW);
while (km != null && !(km instanceof RootPaneInputMap)) {
km = km.getParent();
}
if (km != null) {
km.clear();
if (root.getDefaultButton() != null) {
Object[] bindings = (Object[])DefaultLookup.get(root, this,
"RootPane.defaultButtonWindowKeyBindings");
if (bindings != null) {
LookAndFeel.loadKeyBindings(km, bindings);
}
}
}
}
/**
* 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.
*/
public void propertyChange(PropertyChangeEvent e) {
if(e.getPropertyName().equals("defaultButton")) {
JRootPane rootpane = (JRootPane)e.getSource();
updateDefaultButtonBindings(rootpane);
if (rootpane.getClientProperty("temporaryDefaultButton") == null) {
rootpane.putClientProperty("initialDefaultButton", e.getNewValue());
}
}
}
static class Actions extends UIAction {
public static final String PRESS = "press";
public static final String RELEASE = "release";
public static final String POST_POPUP = "postPopup";
Actions(String name) {
super(name);
}
public void actionPerformed(ActionEvent evt) {
JRootPane root = (JRootPane)evt.getSource();
JButton owner = root.getDefaultButton();
String key = getName();
if (key == POST_POPUP) { // Action to post popup
Component c = KeyboardFocusManager
.getCurrentKeyboardFocusManager()
.getFocusOwner();
if(c instanceof JComponent) {
JComponent src = (JComponent) c;
JPopupMenu jpm = src.getComponentPopupMenu();
if(jpm != null) {
Point pt = src.getPopupLocation(null);
if(pt == null) {
Rectangle vis = src.getVisibleRect();
pt = new Point(vis.x+vis.width/2,
vis.y+vis.height/2);
}
jpm.show(c, pt.x, pt.y);
}
}
}
else if (owner != null
&& SwingUtilities.getRootPane(owner) == root) {
if (key == PRESS) {
owner.doClick(20);
}
}
}
public boolean isEnabled(Object sender) {
String key = getName();
if(key == POST_POPUP) {
MenuElement[] elems = MenuSelectionManager
.defaultManager()
.getSelectedPath();
if(elems != null && elems.length != 0) {
return false;
// We shall not interfere with already opened menu
}
Component c = KeyboardFocusManager
.getCurrentKeyboardFocusManager()
.getFocusOwner();
if(c instanceof JComponent) {
JComponent src = (JComponent) c;
return src.getComponentPopupMenu() != null;
}
return false;
}
if (sender != null && sender instanceof JRootPane) {
JButton owner = ((JRootPane)sender).getDefaultButton();
return (owner != null && owner.getModel().isEnabled());
}
return true;
}
}
private static class RootPaneInputMap extends ComponentInputMapUIResource {
public RootPaneInputMap(JComponent c) {
super(c);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 1997, 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.basic;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SeparatorUI;
/**
* A Basic L&amp;F implementation of SeparatorUI. This implementation
* is a "combined" view/controller.
*
* @author Georges Saab
* @author Jeff Shapiro
*/
public class BasicSeparatorUI extends SeparatorUI
{
protected Color shadow;
protected Color highlight;
public static ComponentUI createUI( JComponent c )
{
return new BasicSeparatorUI();
}
public void installUI( JComponent c )
{
installDefaults( (JSeparator)c );
installListeners( (JSeparator)c );
}
public void uninstallUI(JComponent c)
{
uninstallDefaults( (JSeparator)c );
uninstallListeners( (JSeparator)c );
}
protected void installDefaults( JSeparator s )
{
LookAndFeel.installColors( s, "Separator.background", "Separator.foreground" );
LookAndFeel.installProperty( s, "opaque", Boolean.FALSE);
}
protected void uninstallDefaults( JSeparator s )
{
}
protected void installListeners( JSeparator s )
{
}
protected void uninstallListeners( JSeparator s )
{
}
public void paint( Graphics g, JComponent c )
{
Dimension s = c.getSize();
if ( ((JSeparator)c).getOrientation() == JSeparator.VERTICAL )
{
g.setColor( c.getForeground() );
g.drawLine( 0, 0, 0, s.height );
g.setColor( c.getBackground() );
g.drawLine( 1, 0, 1, s.height );
}
else // HORIZONTAL
{
g.setColor( c.getForeground() );
g.drawLine( 0, 0, s.width, 0 );
g.setColor( c.getBackground() );
g.drawLine( 0, 1, s.width, 1 );
}
}
public Dimension getPreferredSize( JComponent c )
{
if ( ((JSeparator)c).getOrientation() == JSeparator.VERTICAL )
return new Dimension( 2, 0 );
else
return new Dimension( 0, 2 );
}
public Dimension getMinimumSize( JComponent c ) { return null; }
public Dimension getMaximumSize( JComponent c ) { return null; }
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,961 @@
/*
* Copyright (c) 1997, 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.basic;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.table.*;
import sun.swing.*;
/**
* BasicTableHeaderUI implementation
*
* @author Alan Chung
* @author Philip Milne
*/
public class BasicTableHeaderUI extends TableHeaderUI {
private static Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
//
// Instance Variables
//
/** The JTableHeader that is delegating the painting to this UI. */
protected JTableHeader header;
protected CellRendererPane rendererPane;
// Listeners that are attached to the JTable
protected MouseInputListener mouseInputListener;
// The column header over which the mouse currently is.
private int rolloverColumn = -1;
// The column that should be highlighted when the table header has the focus.
private int selectedColumnIndex = 0; // Read ONLY via getSelectedColumnIndex!
private static FocusListener focusListener = new FocusListener() {
public void focusGained(FocusEvent e) {
repaintHeader(e.getSource());
}
public void focusLost(FocusEvent e) {
repaintHeader(e.getSource());
}
private void repaintHeader(Object source) {
if (source instanceof JTableHeader) {
JTableHeader th = (JTableHeader)source;
BasicTableHeaderUI ui =
(BasicTableHeaderUI)BasicLookAndFeel.
getUIOfType(th.getUI(),
BasicTableHeaderUI.class);
if (ui == null) {
return;
}
th.repaint(th.getHeaderRect(ui.getSelectedColumnIndex()));
}
}
};
/**
* This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of {@code BasicTableHeaderUI}.
*/
public class MouseInputHandler implements MouseInputListener {
private int mouseXOffset;
private Cursor otherCursor = resizeCursor;
public void mouseClicked(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
if (e.getClickCount() % 2 == 1 &&
SwingUtilities.isLeftMouseButton(e)) {
JTable table = header.getTable();
RowSorter sorter;
if (table != null && (sorter = table.getRowSorter()) != null) {
int columnIndex = header.columnAtPoint(e.getPoint());
if (columnIndex != -1) {
columnIndex = table.convertColumnIndexToModel(
columnIndex);
sorter.toggleSortOrder(columnIndex);
}
}
}
}
private TableColumn getResizingColumn(Point p) {
return getResizingColumn(p, header.columnAtPoint(p));
}
private TableColumn getResizingColumn(Point p, int column) {
if (column == -1) {
return null;
}
Rectangle r = header.getHeaderRect(column);
r.grow(-3, 0);
if (r.contains(p)) {
return null;
}
int midPoint = r.x + r.width/2;
int columnIndex;
if( header.getComponentOrientation().isLeftToRight() ) {
columnIndex = (p.x < midPoint) ? column - 1 : column;
} else {
columnIndex = (p.x < midPoint) ? column : column - 1;
}
if (columnIndex == -1) {
return null;
}
return header.getColumnModel().getColumn(columnIndex);
}
public void mousePressed(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
header.setDraggedColumn(null);
header.setResizingColumn(null);
header.setDraggedDistance(0);
Point p = e.getPoint();
// First find which header cell was hit
TableColumnModel columnModel = header.getColumnModel();
int index = header.columnAtPoint(p);
if (index != -1) {
// The last 3 pixels + 3 pixels of next column are for resizing
TableColumn resizingColumn = getResizingColumn(p, index);
if (canResize(resizingColumn, header)) {
header.setResizingColumn(resizingColumn);
if( header.getComponentOrientation().isLeftToRight() ) {
mouseXOffset = p.x - resizingColumn.getWidth();
} else {
mouseXOffset = p.x + resizingColumn.getWidth();
}
}
else if (header.getReorderingAllowed()) {
TableColumn hitColumn = columnModel.getColumn(index);
header.setDraggedColumn(hitColumn);
mouseXOffset = p.x;
}
}
if (header.getReorderingAllowed()) {
int oldRolloverColumn = rolloverColumn;
rolloverColumn = -1;
rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
}
}
private void swapCursor() {
Cursor tmp = header.getCursor();
header.setCursor(otherCursor);
otherCursor = tmp;
}
public void mouseMoved(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
if (canResize(getResizingColumn(e.getPoint()), header) !=
(header.getCursor() == resizeCursor)) {
swapCursor();
}
updateRolloverColumn(e);
}
public void mouseDragged(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
int mouseX = e.getX();
TableColumn resizingColumn = header.getResizingColumn();
TableColumn draggedColumn = header.getDraggedColumn();
boolean headerLeftToRight = header.getComponentOrientation().isLeftToRight();
if (resizingColumn != null) {
int oldWidth = resizingColumn.getWidth();
int newWidth;
if (headerLeftToRight) {
newWidth = mouseX - mouseXOffset;
} else {
newWidth = mouseXOffset - mouseX;
}
mouseXOffset += changeColumnWidth(resizingColumn, header,
oldWidth, newWidth);
}
else if (draggedColumn != null) {
TableColumnModel cm = header.getColumnModel();
int draggedDistance = mouseX - mouseXOffset;
int direction = (draggedDistance < 0) ? -1 : 1;
int columnIndex = viewIndexForColumn(draggedColumn);
int newColumnIndex = columnIndex + (headerLeftToRight ? direction : -direction);
if (0 <= newColumnIndex && newColumnIndex < cm.getColumnCount()) {
int width = cm.getColumn(newColumnIndex).getWidth();
if (Math.abs(draggedDistance) > (width / 2)) {
mouseXOffset = mouseXOffset + direction * width;
header.setDraggedDistance(draggedDistance - direction * width);
//Cache the selected column.
int selectedIndex =
SwingUtilities2.convertColumnIndexToModel(
header.getColumnModel(),
getSelectedColumnIndex());
//Now do the move.
cm.moveColumn(columnIndex, newColumnIndex);
//Update the selected index.
selectColumn(
SwingUtilities2.convertColumnIndexToView(
header.getColumnModel(), selectedIndex),
false);
return;
}
}
setDraggedDistance(draggedDistance, columnIndex);
}
updateRolloverColumn(e);
}
public void mouseReleased(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
setDraggedDistance(0, viewIndexForColumn(header.getDraggedColumn()));
header.setResizingColumn(null);
header.setDraggedColumn(null);
updateRolloverColumn(e);
}
public void mouseEntered(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
updateRolloverColumn(e);
}
public void mouseExited(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
int oldRolloverColumn = rolloverColumn;
rolloverColumn = -1;
rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
}
//
// Protected & Private Methods
//
private void setDraggedDistance(int draggedDistance, int column) {
header.setDraggedDistance(draggedDistance);
if (column != -1) {
header.getColumnModel().moveColumn(column, column);
}
}
}
//
// Factory methods for the Listeners
//
/**
* Creates the mouse listener for the JTableHeader.
*/
protected MouseInputListener createMouseInputListener() {
return new MouseInputHandler();
}
//
// The installation/uninstall procedures and support
//
public static ComponentUI createUI(JComponent h) {
return new BasicTableHeaderUI();
}
// Installation
public void installUI(JComponent c) {
header = (JTableHeader)c;
rendererPane = new CellRendererPane();
header.add(rendererPane);
installDefaults();
installListeners();
installKeyboardActions();
}
/**
* Initializes JTableHeader 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
*/
protected void installDefaults() {
LookAndFeel.installColorsAndFont(header, "TableHeader.background",
"TableHeader.foreground", "TableHeader.font");
LookAndFeel.installProperty(header, "opaque", Boolean.TRUE);
}
/**
* Attaches listeners to the JTableHeader.
*/
protected void installListeners() {
mouseInputListener = createMouseInputListener();
header.addMouseListener(mouseInputListener);
header.addMouseMotionListener(mouseInputListener);
header.addFocusListener(focusListener);
}
/**
* Register all keyboard actions on the JTableHeader.
*/
protected void installKeyboardActions() {
InputMap keyMap = (InputMap)DefaultLookup.get(header, this,
"TableHeader.ancestorInputMap");
SwingUtilities.replaceUIInputMap(header,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);
LazyActionMap.installLazyActionMap(header, BasicTableHeaderUI.class,
"TableHeader.actionMap");
}
// Uninstall methods
public void uninstallUI(JComponent c) {
uninstallDefaults();
uninstallListeners();
uninstallKeyboardActions();
header.remove(rendererPane);
rendererPane = null;
header = null;
}
protected void uninstallDefaults() {}
protected void uninstallListeners() {
header.removeMouseListener(mouseInputListener);
header.removeMouseMotionListener(mouseInputListener);
mouseInputListener = null;
}
/**
* Unregisters default key actions.
*/
protected void uninstallKeyboardActions() {
SwingUtilities.replaceUIInputMap(header, JComponent.WHEN_FOCUSED, null);
SwingUtilities.replaceUIActionMap(header, null);
}
/**
* Populates TableHeader's actions.
*/
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.TOGGLE_SORT_ORDER));
map.put(new Actions(Actions.SELECT_COLUMN_TO_LEFT));
map.put(new Actions(Actions.SELECT_COLUMN_TO_RIGHT));
map.put(new Actions(Actions.MOVE_COLUMN_LEFT));
map.put(new Actions(Actions.MOVE_COLUMN_RIGHT));
map.put(new Actions(Actions.RESIZE_LEFT));
map.put(new Actions(Actions.RESIZE_RIGHT));
map.put(new Actions(Actions.FOCUS_TABLE));
}
//
// Support for mouse rollover
//
/**
* Returns the index of the column header over which the mouse
* currently is. When the mouse is not over the table header,
* -1 is returned.
*
* @see #rolloverColumnUpdated(int, int)
* @return the index of the current rollover column
* @since 1.6
*/
protected int getRolloverColumn() {
return rolloverColumn;
}
/**
* This method gets called every time when a rollover column in the table
* header is updated. Every look and feel that supports a rollover effect
* in a table header should override this method and repaint the header.
*
* @param oldColumn the index of the previous rollover column or -1 if the
* mouse was not over a column
* @param newColumn the index of the new rollover column or -1 if the mouse
* is not over a column
* @see #getRolloverColumn()
* @see JTableHeader#getHeaderRect(int)
* @since 1.6
*/
protected void rolloverColumnUpdated(int oldColumn, int newColumn) {
}
private void updateRolloverColumn(MouseEvent e) {
if (header.getDraggedColumn() == null &&
header.contains(e.getPoint())) {
int col = header.columnAtPoint(e.getPoint());
if (col != rolloverColumn) {
int oldRolloverColumn = rolloverColumn;
rolloverColumn = col;
rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
}
}
}
//
// Support for keyboard and mouse access
//
private int selectNextColumn(boolean doIt) {
int newIndex = getSelectedColumnIndex();
if (newIndex < header.getColumnModel().getColumnCount() - 1) {
newIndex++;
if (doIt) {
selectColumn(newIndex);
}
}
return newIndex;
}
private int selectPreviousColumn(boolean doIt) {
int newIndex = getSelectedColumnIndex();
if (newIndex > 0) {
newIndex--;
if (doIt) {
selectColumn(newIndex);
}
}
return newIndex;
}
/**
* Selects the specified column in the table header. Repaints the
* affected header cells and makes sure the newly selected one is visible.
*/
void selectColumn(int newColIndex) {
selectColumn(newColIndex, true);
}
void selectColumn(int newColIndex, boolean doScroll) {
Rectangle repaintRect = header.getHeaderRect(selectedColumnIndex);
header.repaint(repaintRect);
selectedColumnIndex = newColIndex;
repaintRect = header.getHeaderRect(newColIndex);
header.repaint(repaintRect);
if (doScroll) {
scrollToColumn(newColIndex);
}
return;
}
/**
* Used by selectColumn to scroll horizontally, if necessary,
* to ensure that the newly selected column is visible.
*/
private void scrollToColumn(int col) {
Container container;
JTable table;
//Test whether the header is in a scroll pane and has a table.
if ((header.getParent() == null) ||
((container = header.getParent().getParent()) == null) ||
!(container instanceof JScrollPane) ||
((table = header.getTable()) == null)) {
return;
}
//Now scroll, if necessary.
Rectangle vis = table.getVisibleRect();
Rectangle cellBounds = table.getCellRect(0, col, true);
vis.x = cellBounds.x;
vis.width = cellBounds.width;
table.scrollRectToVisible(vis);
}
private int getSelectedColumnIndex() {
int numCols = header.getColumnModel().getColumnCount();
if (selectedColumnIndex >= numCols && numCols > 0) {
selectedColumnIndex = numCols - 1;
}
return selectedColumnIndex;
}
private static boolean canResize(TableColumn column,
JTableHeader header) {
return (column != null) && header.getResizingAllowed()
&& column.getResizable();
}
private int changeColumnWidth(TableColumn resizingColumn,
JTableHeader th,
int oldWidth, int newWidth) {
resizingColumn.setWidth(newWidth);
Container container;
JTable table;
if ((th.getParent() == null) ||
((container = th.getParent().getParent()) == null) ||
!(container instanceof JScrollPane) ||
((table = th.getTable()) == null)) {
return 0;
}
if (!container.getComponentOrientation().isLeftToRight() &&
!th.getComponentOrientation().isLeftToRight()) {
JViewport viewport = ((JScrollPane)container).getViewport();
int viewportWidth = viewport.getWidth();
int diff = newWidth - oldWidth;
int newHeaderWidth = table.getWidth() + diff;
/* Resize a table */
Dimension tableSize = table.getSize();
tableSize.width += diff;
table.setSize(tableSize);
/* If this table is in AUTO_RESIZE_OFF mode and
* has a horizontal scrollbar, we need to update
* a view's position.
*/
if ((newHeaderWidth >= viewportWidth) &&
(table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF)) {
Point p = viewport.getViewPosition();
p.x = Math.max(0, Math.min(newHeaderWidth - viewportWidth,
p.x + diff));
viewport.setViewPosition(p);
return diff;
}
}
return 0;
}
//
// Baseline
//
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
int baseline = -1;
TableColumnModel columnModel = header.getColumnModel();
for(int column = 0; column < columnModel.getColumnCount();
column++) {
TableColumn aColumn = columnModel.getColumn(column);
Component comp = getHeaderRenderer(column);
Dimension pref = comp.getPreferredSize();
int columnBaseline = comp.getBaseline(pref.width, height);
if (columnBaseline >= 0) {
if (baseline == -1) {
baseline = columnBaseline;
}
else if (baseline != columnBaseline) {
baseline = -1;
break;
}
}
}
return baseline;
}
//
// Paint Methods and support
//
public void paint(Graphics g, JComponent c) {
if (header.getColumnModel().getColumnCount() <= 0) {
return;
}
boolean ltr = header.getComponentOrientation().isLeftToRight();
Rectangle clip = g.getClipBounds();
Point left = clip.getLocation();
Point right = new Point( clip.x + clip.width - 1, clip.y );
TableColumnModel cm = header.getColumnModel();
int cMin = header.columnAtPoint( ltr ? left : right );
int cMax = header.columnAtPoint( ltr ? right : left );
// 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 = cm.getColumnCount()-1;
}
TableColumn draggedColumn = header.getDraggedColumn();
int columnWidth;
Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax);
TableColumn aColumn;
if (ltr) {
for(int column = cMin; column <= cMax ; column++) {
aColumn = cm.getColumn(column);
columnWidth = aColumn.getWidth();
cellRect.width = columnWidth;
if (aColumn != draggedColumn) {
paintCell(g, cellRect, column);
}
cellRect.x += columnWidth;
}
} else {
for(int column = cMax; column >= cMin; column--) {
aColumn = cm.getColumn(column);
columnWidth = aColumn.getWidth();
cellRect.width = columnWidth;
if (aColumn != draggedColumn) {
paintCell(g, cellRect, column);
}
cellRect.x += columnWidth;
}
}
// Paint the dragged column if we are dragging.
if (draggedColumn != null) {
int draggedColumnIndex = viewIndexForColumn(draggedColumn);
Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex);
// Draw a gray well in place of the moving column.
g.setColor(header.getParent().getBackground());
g.fillRect(draggedCellRect.x, draggedCellRect.y,
draggedCellRect.width, draggedCellRect.height);
draggedCellRect.x += header.getDraggedDistance();
// Fill the background.
g.setColor(header.getBackground());
g.fillRect(draggedCellRect.x, draggedCellRect.y,
draggedCellRect.width, draggedCellRect.height);
paintCell(g, draggedCellRect, draggedColumnIndex);
}
// Remove all components in the rendererPane.
rendererPane.removeAll();
}
private Component getHeaderRenderer(int columnIndex) {
TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
renderer = header.getDefaultRenderer();
}
boolean hasFocus = !header.isPaintingForPrint()
&& (columnIndex == getSelectedColumnIndex())
&& header.hasFocus();
return renderer.getTableCellRendererComponent(header.getTable(),
aColumn.getHeaderValue(),
false, hasFocus,
-1, columnIndex);
}
private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
Component component = getHeaderRenderer(columnIndex);
rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
cellRect.width, cellRect.height, true);
}
private int viewIndexForColumn(TableColumn aColumn) {
TableColumnModel cm = header.getColumnModel();
for (int column = 0; column < cm.getColumnCount(); column++) {
if (cm.getColumn(column) == aColumn) {
return column;
}
}
return -1;
}
//
// Size Methods
//
private int getHeaderHeight() {
int height = 0;
boolean accomodatedDefault = false;
TableColumnModel columnModel = header.getColumnModel();
for(int column = 0; column < columnModel.getColumnCount(); column++) {
TableColumn aColumn = columnModel.getColumn(column);
boolean isDefault = (aColumn.getHeaderRenderer() == null);
if (!isDefault || !accomodatedDefault) {
Component comp = getHeaderRenderer(column);
int rendererHeight = comp.getPreferredSize().height;
height = Math.max(height, rendererHeight);
// Configuring the header renderer to calculate its preferred size
// is expensive. Optimise this by assuming the default renderer
// always has the same height as the first non-zero height that
// it returns for a non-null/non-empty value.
if (isDefault && rendererHeight > 0) {
Object headerValue = aColumn.getHeaderValue();
if (headerValue != null) {
headerValue = headerValue.toString();
if (headerValue != null && !headerValue.equals("")) {
accomodatedDefault = true;
}
}
}
}
}
return height;
}
private Dimension createHeaderSize(long width) {
// None of the callers include the intercell spacing, do it here.
if (width > Integer.MAX_VALUE) {
width = Integer.MAX_VALUE;
}
return new Dimension((int)width, getHeaderHeight());
}
/**
* Return the minimum size of the header. The minimum width is the sum
* of the minimum widths of each column (plus inter-cell spacing).
*/
public Dimension getMinimumSize(JComponent c) {
long width = 0;
Enumeration enumeration = header.getColumnModel().getColumns();
while (enumeration.hasMoreElements()) {
TableColumn aColumn = (TableColumn)enumeration.nextElement();
width = width + aColumn.getMinWidth();
}
return createHeaderSize(width);
}
/**
* Return the preferred size of the header. The preferred height is the
* maximum of the preferred heights of all of the components provided
* by the header renderers. The preferred width is the sum of the
* preferred widths of each column (plus inter-cell spacing).
*/
public Dimension getPreferredSize(JComponent c) {
long width = 0;
Enumeration enumeration = header.getColumnModel().getColumns();
while (enumeration.hasMoreElements()) {
TableColumn aColumn = (TableColumn)enumeration.nextElement();
width = width + aColumn.getPreferredWidth();
}
return createHeaderSize(width);
}
/**
* Return the maximum size of the header. The maximum width is the sum
* of the maximum widths of each column (plus inter-cell spacing).
*/
public Dimension getMaximumSize(JComponent c) {
long width = 0;
Enumeration enumeration = header.getColumnModel().getColumns();
while (enumeration.hasMoreElements()) {
TableColumn aColumn = (TableColumn)enumeration.nextElement();
width = width + aColumn.getMaxWidth();
}
return createHeaderSize(width);
}
private static class Actions extends UIAction {
public static final String TOGGLE_SORT_ORDER =
"toggleSortOrder";
public static final String SELECT_COLUMN_TO_LEFT =
"selectColumnToLeft";
public static final String SELECT_COLUMN_TO_RIGHT =
"selectColumnToRight";
public static final String MOVE_COLUMN_LEFT =
"moveColumnLeft";
public static final String MOVE_COLUMN_RIGHT =
"moveColumnRight";
public static final String RESIZE_LEFT =
"resizeLeft";
public static final String RESIZE_RIGHT =
"resizeRight";
public static final String FOCUS_TABLE =
"focusTable";
public Actions(String name) {
super(name);
}
public boolean isEnabled(Object sender) {
if (sender instanceof JTableHeader) {
JTableHeader th = (JTableHeader)sender;
TableColumnModel cm = th.getColumnModel();
if (cm.getColumnCount() <= 0) {
return false;
}
String key = getName();
BasicTableHeaderUI ui =
(BasicTableHeaderUI)BasicLookAndFeel.getUIOfType(th.getUI(),
BasicTableHeaderUI.class);
if (ui != null) {
if (key == MOVE_COLUMN_LEFT) {
return th.getReorderingAllowed()
&& maybeMoveColumn(true, th, ui, false);
} else if (key == MOVE_COLUMN_RIGHT) {
return th.getReorderingAllowed()
&& maybeMoveColumn(false, th, ui, false);
} else if (key == RESIZE_LEFT ||
key == RESIZE_RIGHT) {
return canResize(cm.getColumn(ui.getSelectedColumnIndex()), th);
} else if (key == FOCUS_TABLE) {
return (th.getTable() != null);
}
}
}
return true;
}
public void actionPerformed(ActionEvent e) {
JTableHeader th = (JTableHeader)e.getSource();
BasicTableHeaderUI ui =
(BasicTableHeaderUI)BasicLookAndFeel.
getUIOfType(th.getUI(),
BasicTableHeaderUI.class);
if (ui == null) {
return;
}
String name = getName();
if (TOGGLE_SORT_ORDER == name) {
JTable table = th.getTable();
RowSorter sorter = table == null ? null : table.getRowSorter();
if (sorter != null) {
int columnIndex = ui.getSelectedColumnIndex();
columnIndex = table.convertColumnIndexToModel(
columnIndex);
sorter.toggleSortOrder(columnIndex);
}
} else if (SELECT_COLUMN_TO_LEFT == name) {
if (th.getComponentOrientation().isLeftToRight()) {
ui.selectPreviousColumn(true);
} else {
ui.selectNextColumn(true);
}
} else if (SELECT_COLUMN_TO_RIGHT == name) {
if (th.getComponentOrientation().isLeftToRight()) {
ui.selectNextColumn(true);
} else {
ui.selectPreviousColumn(true);
}
} else if (MOVE_COLUMN_LEFT == name) {
moveColumn(true, th, ui);
} else if (MOVE_COLUMN_RIGHT == name) {
moveColumn(false, th, ui);
} else if (RESIZE_LEFT == name) {
resize(true, th, ui);
} else if (RESIZE_RIGHT == name) {
resize(false, th, ui);
} else if (FOCUS_TABLE == name) {
JTable table = th.getTable();
if (table != null) {
table.requestFocusInWindow();
}
}
}
private void moveColumn(boolean leftArrow, JTableHeader th,
BasicTableHeaderUI ui) {
maybeMoveColumn(leftArrow, th, ui, true);
}
private boolean maybeMoveColumn(boolean leftArrow, JTableHeader th,
BasicTableHeaderUI ui, boolean doIt) {
int oldIndex = ui.getSelectedColumnIndex();
int newIndex;
if (th.getComponentOrientation().isLeftToRight()) {
newIndex = leftArrow ? ui.selectPreviousColumn(doIt)
: ui.selectNextColumn(doIt);
} else {
newIndex = leftArrow ? ui.selectNextColumn(doIt)
: ui.selectPreviousColumn(doIt);
}
if (newIndex != oldIndex) {
if (doIt) {
th.getColumnModel().moveColumn(oldIndex, newIndex);
} else {
return true; // we'd do the move if asked
}
}
return false;
}
private void resize(boolean leftArrow, JTableHeader th,
BasicTableHeaderUI ui) {
int columnIndex = ui.getSelectedColumnIndex();
TableColumn resizingColumn =
th.getColumnModel().getColumn(columnIndex);
th.setResizingColumn(resizingColumn);
int oldWidth = resizingColumn.getWidth();
int newWidth = oldWidth;
if (th.getComponentOrientation().isLeftToRight()) {
newWidth = newWidth + (leftArrow ? -1 : 1);
} else {
newWidth = newWidth + (leftArrow ? 1 : -1);
}
ui.changeColumnWidth(resizingColumn, th, oldWidth, newWidth);
}
}
} // End of Class BasicTableHeaderUI

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,394 @@
/*
* Copyright (c) 1997, 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.basic;
import java.beans.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.text.*;
import javax.swing.plaf.*;
/**
* Provides the look and feel for a plain text editor. 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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Timothy Prinzing
*/
public class BasicTextAreaUI extends BasicTextUI {
/**
* Creates a UI for a JTextArea.
*
* @param ta a text area
* @return the UI
*/
public static ComponentUI createUI(JComponent ta) {
return new BasicTextAreaUI();
}
/**
* Constructs a new BasicTextAreaUI object.
*/
public BasicTextAreaUI() {
super();
}
/**
* 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 ("TextArea")
*/
protected String getPropertyPrefix() {
return "TextArea";
}
protected void installDefaults() {
super.installDefaults();
//the fix for 4785160 is undone
}
/**
* 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
*/
protected void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
if (evt.getPropertyName().equals("lineWrap") ||
evt.getPropertyName().equals("wrapStyleWord") ||
evt.getPropertyName().equals("tabSize")) {
// rebuild the view
modelChanged();
} else if ("editable".equals(evt.getPropertyName())) {
updateFocusTraversalKeys();
}
}
/**
* The method is overridden to take into account caret width.
*
* @param c the editor component
* @return the preferred size
* @throws IllegalArgumentException if invalid value is passed
*
* @since 1.5
*/
public Dimension getPreferredSize(JComponent c) {
return super.getPreferredSize(c);
//the fix for 4785160 is undone
}
/**
* The method is overridden to take into account caret width.
*
* @param c the editor component
* @return the minimum size
* @throws IllegalArgumentException if invalid value is passed
*
* @since 1.5
*/
public Dimension getMinimumSize(JComponent c) {
return super.getMinimumSize(c);
//the fix for 4785160 is undone
}
/**
* Creates the view for an element. Returns a WrappedPlainView or
* PlainView.
*
* @param elem the element
* @return the view
*/
public View create(Element elem) {
Document doc = elem.getDocument();
Object i18nFlag = doc.getProperty("i18n"/*AbstractDocument.I18NProperty*/);
if ((i18nFlag != null) && i18nFlag.equals(Boolean.TRUE)) {
// build a view that support bidi
return createI18N(elem);
} else {
JTextComponent c = getComponent();
if (c instanceof JTextArea) {
JTextArea area = (JTextArea) c;
View v;
if (area.getLineWrap()) {
v = new WrappedPlainView(elem, area.getWrapStyleWord());
} else {
v = new PlainView(elem);
}
return v;
}
}
return null;
}
View createI18N(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new PlainParagraph(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new BoxView(elem, View.Y_AXIS);
}
}
return null;
}
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
Object i18nFlag = ((JTextComponent)c).getDocument().
getProperty("i18n");
Insets insets = c.getInsets();
if (Boolean.TRUE.equals(i18nFlag)) {
View rootView = getRootView((JTextComponent)c);
if (rootView.getViewCount() > 0) {
height = height - insets.top - insets.bottom;
int baseline = insets.top;
int fieldBaseline = BasicHTML.getBaseline(
rootView.getView(0), width - insets.left -
insets.right, height);
if (fieldBaseline < 0) {
return -1;
}
return baseline + fieldBaseline;
}
return -1;
}
FontMetrics fm = c.getFontMetrics(c.getFont());
return insets.top + fm.getAscent();
}
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public Component.BaselineResizeBehavior getBaselineResizeBehavior(
JComponent c) {
super.getBaselineResizeBehavior(c);
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
/**
* Paragraph for representing plain-text lines that support
* bidirectional text.
*/
static class PlainParagraph extends ParagraphView {
PlainParagraph(Element elem) {
super(elem);
layoutPool = new LogicalView(elem);
layoutPool.setParent(this);
}
public void setParent(View parent) {
super.setParent(parent);
if (parent != null) {
setPropertiesFromAttributes();
}
}
protected void setPropertiesFromAttributes() {
Component c = getContainer();
if ((c != null) && (! c.getComponentOrientation().isLeftToRight())) {
setJustification(StyleConstants.ALIGN_RIGHT);
} else {
setJustification(StyleConstants.ALIGN_LEFT);
}
}
/**
* Fetch the constraining span to flow against for
* the given child index.
*/
public int getFlowSpan(int index) {
Component c = getContainer();
if (c instanceof JTextArea) {
JTextArea area = (JTextArea) c;
if (! area.getLineWrap()) {
// no limit if unwrapped
return Integer.MAX_VALUE;
}
}
return super.getFlowSpan(index);
}
protected SizeRequirements calculateMinorAxisRequirements(int axis,
SizeRequirements r) {
SizeRequirements req = super.calculateMinorAxisRequirements(axis, r);
Component c = getContainer();
if (c instanceof JTextArea) {
JTextArea area = (JTextArea) c;
if (! area.getLineWrap()) {
// min is pref if unwrapped
req.minimum = req.preferred;
} else {
req.minimum = 0;
req.preferred = getWidth();
if (req.preferred == Integer.MAX_VALUE) {
// We have been initially set to MAX_VALUE, but we
// don't want this as our preferred.
req.preferred = 100;
}
}
}
return req;
}
/**
* Sets the size of the view. If the size has changed, layout
* is redone. The size is the full size of the view including
* the inset areas.
*
* @param width the width >= 0
* @param height the height >= 0
*/
public void setSize(float width, float height) {
if ((int) width != getWidth()) {
preferenceChanged(null, true, true);
}
super.setSize(width, height);
}
/**
* This class can be used to represent a logical view for
* a flow. It keeps the children updated to reflect the state
* of the model, gives the logical child views access to the
* view hierarchy, and calculates a preferred span. It doesn't
* do any rendering, layout, or model/view translation.
*/
static class LogicalView extends CompositeView {
LogicalView(Element elem) {
super(elem);
}
protected int getViewIndexAtPosition(int pos) {
Element elem = getElement();
if (elem.getElementCount() > 0) {
return elem.getElementIndex(pos);
}
return 0;
}
protected boolean updateChildren(DocumentEvent.ElementChange ec,
DocumentEvent e, ViewFactory f) {
return false;
}
protected void loadChildren(ViewFactory f) {
Element elem = getElement();
if (elem.getElementCount() > 0) {
super.loadChildren(f);
} else {
View v = new GlyphView(elem);
append(v);
}
}
public float getPreferredSpan(int axis) {
if( getViewCount() != 1 )
throw new Error("One child view is assumed.");
View v = getView(0);
return v.getPreferredSpan(axis);
}
/**
* Forward the DocumentEvent to the given child view. This
* is implemented to reparent the child to the logical view
* (the children may have been parented by a row in the flow
* if they fit without breaking) and then execute the superclass
* behavior.
*
* @param v the child view to forward the event to.
* @param e the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see #forwardUpdate
* @since 1.3
*/
protected void forwardUpdateToView(View v, DocumentEvent e,
Shape a, ViewFactory f) {
v.setParent(this);
super.forwardUpdateToView(v, e, a, f);
}
// The following methods don't do anything useful, they
// simply keep the class from being abstract.
public void paint(Graphics g, Shape allocation) {
}
protected boolean isBefore(int x, int y, Rectangle alloc) {
return false;
}
protected boolean isAfter(int x, int y, Rectangle alloc) {
return false;
}
protected View getViewAtPoint(int x, int y, Rectangle alloc) {
return null;
}
protected void childAllocation(int index, Rectangle a) {
}
}
}
}

View File

@@ -0,0 +1,426 @@
/*
* Copyright (c) 1997, 2019, 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.basic;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.beans.PropertyChangeEvent;
import java.io.Reader;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.plaf.*;
import sun.swing.DefaultLookup;
/**
* Basis of a look and feel for a 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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Timothy Prinzing
*/
public class BasicTextFieldUI extends BasicTextUI {
/**
* Creates a UI for a JTextField.
*
* @param c the text field
* @return the UI
*/
public static ComponentUI createUI(JComponent c) {
return new BasicTextFieldUI();
}
/**
* Creates a new BasicTextFieldUI.
*/
public BasicTextFieldUI() {
super();
}
/**
* 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 ("TextField")
*/
protected String getPropertyPrefix() {
return "TextField";
}
/**
* Creates a view (FieldView) based on an element.
*
* @param elem the element
* @return the view
*/
public View create(Element elem) {
Document doc = elem.getDocument();
Object i18nFlag = doc.getProperty("i18n"/*AbstractDocument.I18NProperty*/);
if (Boolean.TRUE.equals(i18nFlag)) {
// To support bidirectional text, we build a more heavyweight
// representation of the field.
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new GlyphView(elem){
@Override
public float getMinimumSpan(int axis) {
// no wrap
return getPreferredSpan(axis);
}
};
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new I18nFieldView(elem);
}
}
// this shouldn't happen, should probably throw in this case.
}
return new FieldView(elem);
}
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
View rootView = getRootView((JTextComponent)c);
if (rootView.getViewCount() > 0) {
Insets insets = c.getInsets();
height = height - insets.top - insets.bottom;
if (height > 0) {
int baseline = insets.top;
View fieldView = rootView.getView(0);
int vspan = (int)fieldView.getPreferredSpan(View.Y_AXIS);
if (height != vspan) {
int slop = height - vspan;
baseline += slop / 2;
}
if (fieldView instanceof I18nFieldView) {
int fieldBaseline = BasicHTML.getBaseline(
fieldView, width - insets.left - insets.right,
height);
if (fieldBaseline < 0) {
return -1;
}
baseline += fieldBaseline;
}
else {
FontMetrics fm = c.getFontMetrics(c.getFont());
baseline += fm.getAscent();
}
return baseline;
}
}
return -1;
}
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public Component.BaselineResizeBehavior getBaselineResizeBehavior(
JComponent c) {
super.getBaselineResizeBehavior(c);
return Component.BaselineResizeBehavior.CENTER_OFFSET;
}
/**
* A field view that support bidirectional text via the
* support provided by ParagraphView.
*/
static class I18nFieldView extends ParagraphView {
I18nFieldView(Element elem) {
super(elem);
}
/**
* Fetch the constraining span to flow against for
* the given child index. There is no limit for
* a field since it scrolls, so this is implemented to
* return <code>Integer.MAX_VALUE</code>.
*/
public int getFlowSpan(int index) {
return Integer.MAX_VALUE;
}
protected void setJustification(int j) {
// Justification is done in adjustAllocation(), so disable
// ParagraphView's justification handling by doing nothing here.
}
static boolean isLeftToRight( java.awt.Component c ) {
return c.getComponentOrientation().isLeftToRight();
}
/**
* Adjusts the allocation given to the view
* to be a suitable allocation for a text field.
* If the view has been allocated more than the
* preferred span vertically, the allocation is
* changed to be centered vertically. Horizontally
* the view is adjusted according to the horizontal
* alignment property set on the associated JTextField
* (if that is the type of the hosting component).
*
* @param a the allocation given to the view, which may need
* to be adjusted.
* @return the allocation that the superclass should use.
*/
Shape adjustAllocation(Shape a) {
if (a != null) {
Rectangle bounds = a.getBounds();
int vspan = (int) getPreferredSpan(Y_AXIS);
int hspan = (int) getPreferredSpan(X_AXIS);
if (bounds.height != vspan) {
int slop = bounds.height - vspan;
bounds.y += slop / 2;
bounds.height -= slop;
}
// horizontal adjustments
Component c = getContainer();
if (c instanceof JTextField) {
JTextField field = (JTextField) c;
BoundedRangeModel vis = field.getHorizontalVisibility();
int max = Math.max(hspan, bounds.width);
int value = vis.getValue();
int extent = Math.min(max, bounds.width - 1);
if ((value + extent) > max) {
value = max - extent;
}
vis.setRangeProperties(value, extent, vis.getMinimum(),
max, false);
if (hspan < bounds.width) {
// horizontally align the interior
int slop = bounds.width - 1 - hspan;
int align = ((JTextField)c).getHorizontalAlignment();
if(isLeftToRight(c)) {
if(align==LEADING) {
align = LEFT;
}
else if(align==TRAILING) {
align = RIGHT;
}
}
else {
if(align==LEADING) {
align = RIGHT;
}
else if(align==TRAILING) {
align = LEFT;
}
}
switch (align) {
case SwingConstants.CENTER:
bounds.x += slop / 2;
bounds.width -= slop;
break;
case SwingConstants.RIGHT:
bounds.x += slop;
bounds.width -= slop;
break;
}
} else {
// adjust the allocation to match the bounded range.
bounds.width = hspan;
bounds.x -= vis.getValue();
}
}
return bounds;
}
return null;
}
/**
* Update the visibility model with the associated JTextField
* (if there is one) to reflect the current visibility as a
* result of changes to the document model. The bounded
* range properties are updated. If the view hasn't yet been
* shown the extent will be zero and we just set it to be full
* until determined otherwise.
*/
void updateVisibilityModel() {
Component c = getContainer();
if (c instanceof JTextField) {
JTextField field = (JTextField) c;
BoundedRangeModel vis = field.getHorizontalVisibility();
int hspan = (int) getPreferredSpan(X_AXIS);
int extent = vis.getExtent();
int maximum = Math.max(hspan, extent);
extent = (extent == 0) ? maximum : extent;
int value = maximum - extent;
int oldValue = vis.getValue();
if ((oldValue + extent) > maximum) {
oldValue = maximum - extent;
}
value = Math.max(0, Math.min(value, oldValue));
vis.setRangeProperties(value, extent, 0, maximum, false);
}
}
// --- View methods -------------------------------------------
/**
* Renders using the given rendering surface and area on that surface.
* The view may need to do layout and create child views to enable
* itself to render into the given allocation.
*
* @param g the rendering surface to use
* @param a the allocated region to render into
*
* @see View#paint
*/
public void paint(Graphics g, Shape a) {
Rectangle r = (Rectangle) a;
g.clipRect(r.x, r.y, r.width, r.height);
super.paint(g, adjustAllocation(a));
}
/**
* Determines the resizability of the view along the
* given axis. A value of 0 or less is not resizable.
*
* @param axis View.X_AXIS or View.Y_AXIS
* @return the weight -> 1 for View.X_AXIS, else 0
*/
public int getResizeWeight(int axis) {
if (axis == View.X_AXIS) {
return 1;
}
return 0;
}
/**
* Provides a mapping from the document model coordinate space
* to the coordinate space of the view mapped to it.
*
* @param pos the position to convert >= 0
* @param a the allocated region to render into
* @return the bounding box of the given position
* @exception BadLocationException if the given position does not
* represent a valid location in the associated document
* @see View#modelToView
*/
public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
return super.modelToView(pos, adjustAllocation(a), b);
}
/**
* Provides a mapping from the document model coordinate space
* to the coordinate space of the view mapped to it.
*
* @param p0 the position to convert >= 0
* @param b0 the bias toward the previous character or the
* next character represented by p0, in case the
* position is a boundary of two views.
* @param p1 the position to convert >= 0
* @param b1 the bias toward the previous character or the
* next character represented by p1, in case the
* position is a boundary of two views.
* @param a the allocated region to render into
* @return the bounding box of the given position is returned
* @exception BadLocationException if the given position does
* not represent a valid location in the associated document
* @exception IllegalArgumentException for an invalid bias argument
* @see View#viewToModel
*/
public Shape modelToView(int p0, Position.Bias b0,
int p1, Position.Bias b1, Shape a)
throws BadLocationException
{
return super.modelToView(p0, b0, p1, b1, adjustAllocation(a));
}
/**
* Provides a mapping from the view coordinate space to the logical
* coordinate space of the model.
*
* @param fx the X coordinate >= 0.0f
* @param fy the Y coordinate >= 0.0f
* @param a the allocated region to render into
* @return the location within the model that best represents the
* given point in the view
* @see View#viewToModel
*/
public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {
return super.viewToModel(fx, fy, adjustAllocation(a), bias);
}
/**
* Gives notification that something was inserted into the document
* in a location that this view is responsible for.
*
* @param changes the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see View#insertUpdate
*/
public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
super.insertUpdate(changes, adjustAllocation(a), f);
updateVisibilityModel();
}
/**
* Gives notification that something was removed from the document
* in a location that this view is responsible for.
*
* @param changes the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see View#removeUpdate
*/
public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
super.removeUpdate(changes, adjustAllocation(a), f);
updateVisibilityModel();
}
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 1997, 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.basic;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.plaf.*;
import javax.swing.border.*;
/**
* Provides the look and feel for a styled text editor.
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Timothy Prinzing
*/
public class BasicTextPaneUI extends BasicEditorPaneUI {
/**
* Creates a UI for the JTextPane.
*
* @param c the JTextPane object
* @return the UI
*/
public static ComponentUI createUI(JComponent c) {
return new BasicTextPaneUI();
}
/**
* Creates a new BasicTextPaneUI.
*/
public BasicTextPaneUI() {
super();
}
/**
* 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")
*/
protected String getPropertyPrefix() {
return "TextPane";
}
public void installUI(JComponent c) {
super.installUI(c);
}
/**
* 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
*/
protected void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.awt.AppContext;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.text.View;
/**
* BasicToggleButton implementation
* <p>
*
* @author Jeff Dinkins
*/
public class BasicToggleButtonUI extends BasicButtonUI {
private static final Object BASIC_TOGGLE_BUTTON_UI_KEY = new Object();
private final static String propertyPrefix = "ToggleButton" + ".";
// ********************************
// Create PLAF
// ********************************
public static ComponentUI createUI(JComponent b) {
AppContext appContext = AppContext.getAppContext();
BasicToggleButtonUI toggleButtonUI =
(BasicToggleButtonUI) appContext.get(BASIC_TOGGLE_BUTTON_UI_KEY);
if (toggleButtonUI == null) {
toggleButtonUI = new BasicToggleButtonUI();
appContext.put(BASIC_TOGGLE_BUTTON_UI_KEY, toggleButtonUI);
}
return toggleButtonUI;
}
protected String getPropertyPrefix() {
return propertyPrefix;
}
// ********************************
// Paint Methods
// ********************************
public void paint(Graphics g, JComponent c) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Dimension size = b.getSize();
FontMetrics fm = g.getFontMetrics();
Insets i = c.getInsets();
Rectangle viewRect = new Rectangle(size);
viewRect.x += i.left;
viewRect.y += i.top;
viewRect.width -= (i.right + viewRect.x);
viewRect.height -= (i.bottom + viewRect.y);
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Font f = c.getFont();
g.setFont(f);
// layout the text and icon
String text = SwingUtilities.layoutCompoundLabel(
c, fm, b.getText(), b.getIcon(),
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect,
b.getText() == null ? 0 : b.getIconTextGap());
g.setColor(b.getBackground());
if (model.isArmed() && model.isPressed() || model.isSelected()) {
paintButtonPressed(g,b);
}
// Paint the Icon
if(b.getIcon() != null) {
paintIcon(g, b, iconRect);
}
// Draw the Text
if(text != null && !text.equals("")) {
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, textRect);
} else {
paintText(g, b, textRect, text);
}
}
// draw the dashed focus line.
if (b.isFocusPainted() && b.hasFocus()) {
paintFocus(g, b, viewRect, textRect, iconRect);
}
}
protected void paintIcon(Graphics g, AbstractButton b, Rectangle iconRect) {
ButtonModel model = b.getModel();
Icon icon = null;
if(!model.isEnabled()) {
if(model.isSelected()) {
icon = b.getDisabledSelectedIcon();
} else {
icon = b.getDisabledIcon();
}
} else if(model.isPressed() && model.isArmed()) {
icon = b.getPressedIcon();
if(icon == null) {
// Use selected icon
icon = b.getSelectedIcon();
}
} else if(model.isSelected()) {
if(b.isRolloverEnabled() && model.isRollover()) {
icon = b.getRolloverSelectedIcon();
if (icon == null) {
icon = b.getSelectedIcon();
}
} else {
icon = b.getSelectedIcon();
}
} else if(b.isRolloverEnabled() && model.isRollover()) {
icon = b.getRolloverIcon();
}
if(icon == null) {
icon = b.getIcon();
}
icon.paintIcon(b, g, iconRect.x, iconRect.y);
}
/**
* Overriden so that the text will not be rendered as shifted for
* Toggle buttons and subclasses.
*/
protected int getTextShiftOffset() {
return 0;
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 1998, 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.basic;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JToolBar;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicSeparatorUI;
/**
* A Basic L&amp;F implementation of ToolBarSeparatorUI. This implementation
* is a "combined" view/controller.
* <p>
*
* @author Jeff Shapiro
*/
public class BasicToolBarSeparatorUI extends BasicSeparatorUI
{
public static ComponentUI createUI( JComponent c )
{
return new BasicToolBarSeparatorUI();
}
protected void installDefaults( JSeparator s )
{
Dimension size = ( (JToolBar.Separator)s ).getSeparatorSize();
if ( size == null || size instanceof UIResource )
{
JToolBar.Separator sep = (JToolBar.Separator)s;
size = (Dimension)(UIManager.get("ToolBar.separatorSize"));
if (size != null) {
if (sep.getOrientation() == JSeparator.HORIZONTAL) {
size = new Dimension(size.height, size.width);
}
sep.setSeparatorSize(size);
}
}
}
public void paint( Graphics g, JComponent c )
{
}
public Dimension getPreferredSize( JComponent c )
{
Dimension size = ( (JToolBar.Separator)c ).getSeparatorSize();
if ( size != null )
{
return size.getSize();
}
else
{
return null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
/*
* Copyright (c) 1997, 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.basic;
import sun.swing.SwingUtilities2;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.border.Border;
import javax.swing.plaf.ToolTipUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.View;
/**
* Standard tool tip L&amp;F.
* <p>
*
* @author Dave Moore
*/
public class BasicToolTipUI extends ToolTipUI
{
static BasicToolTipUI sharedInstance = new BasicToolTipUI();
/**
* Global <code>PropertyChangeListener</code> that
* <code>createPropertyChangeListener</code> returns.
*/
private static PropertyChangeListener sharedPropertyChangedListener;
private PropertyChangeListener propertyChangeListener;
public static ComponentUI createUI(JComponent c) {
return sharedInstance;
}
public BasicToolTipUI() {
super();
}
public void installUI(JComponent c) {
installDefaults(c);
installComponents(c);
installListeners(c);
}
public void uninstallUI(JComponent c) {
// REMIND: this is NOT getting called
uninstallDefaults(c);
uninstallComponents(c);
uninstallListeners(c);
}
protected void installDefaults(JComponent c){
LookAndFeel.installColorsAndFont(c, "ToolTip.background",
"ToolTip.foreground",
"ToolTip.font");
LookAndFeel.installProperty(c, "opaque", Boolean.TRUE);
componentChanged(c);
}
protected void uninstallDefaults(JComponent c){
LookAndFeel.uninstallBorder(c);
}
/* Unfortunately this has to remain private until we can make API additions.
*/
private void installComponents(JComponent c){
BasicHTML.updateRenderer(c, ((JToolTip)c).getTipText());
}
/* Unfortunately this has to remain private until we can make API additions.
*/
private void uninstallComponents(JComponent c){
BasicHTML.updateRenderer(c, "");
}
protected void installListeners(JComponent c) {
propertyChangeListener = createPropertyChangeListener(c);
c.addPropertyChangeListener(propertyChangeListener);
}
protected void uninstallListeners(JComponent c) {
c.removePropertyChangeListener(propertyChangeListener);
propertyChangeListener = null;
}
/* Unfortunately this has to remain private until we can make API additions.
*/
private PropertyChangeListener createPropertyChangeListener(JComponent c) {
if (sharedPropertyChangedListener == null) {
sharedPropertyChangedListener = new PropertyChangeHandler();
}
return sharedPropertyChangedListener;
}
public void paint(Graphics g, JComponent c) {
Font font = c.getFont();
FontMetrics metrics = SwingUtilities2.getFontMetrics(c, g, font);
Dimension size = c.getSize();
g.setColor(c.getForeground());
// fix for bug 4153892
String tipText = ((JToolTip)c).getTipText();
if (tipText == null) {
tipText = "";
}
Insets insets = c.getInsets();
Rectangle paintTextR = new Rectangle(
insets.left + 3,
insets.top,
size.width - (insets.left + insets.right) - 6,
size.height - (insets.top + insets.bottom));
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, paintTextR);
} else {
g.setFont(font);
SwingUtilities2.drawString(c, g, tipText, paintTextR.x,
paintTextR.y + metrics.getAscent());
}
}
public Dimension getPreferredSize(JComponent c) {
Font font = c.getFont();
FontMetrics fm = c.getFontMetrics(font);
Insets insets = c.getInsets();
Dimension prefSize = new Dimension(insets.left+insets.right,
insets.top+insets.bottom);
String text = ((JToolTip)c).getTipText();
if ((text == null) || text.equals("")) {
text = "";
}
else {
View v = (c != null) ? (View) c.getClientProperty("html") : null;
if (v != null) {
prefSize.width += (int) v.getPreferredSpan(View.X_AXIS) + 6;
prefSize.height += (int) v.getPreferredSpan(View.Y_AXIS);
} else {
prefSize.width += SwingUtilities2.stringWidth(c,fm,text) + 6;
prefSize.height += fm.getHeight();
}
}
return prefSize;
}
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;
}
/**
* Invoked when the <code>JCompoment</code> associated with the
* <code>JToolTip</code> has changed, or at initialization time. This
* should update any state dependant upon the <code>JComponent</code>.
*
* @param c the JToolTip the JComponent has changed on.
*/
private void componentChanged(JComponent c) {
JComponent comp = ((JToolTip)c).getComponent();
if (comp != null && !(comp.isEnabled())) {
// For better backward compatibility, only install inactive
// properties if they are defined.
if (UIManager.getBorder("ToolTip.borderInactive") != null) {
LookAndFeel.installBorder(c, "ToolTip.borderInactive");
}
else {
LookAndFeel.installBorder(c, "ToolTip.border");
}
if (UIManager.getColor("ToolTip.backgroundInactive") != null) {
LookAndFeel.installColors(c,"ToolTip.backgroundInactive",
"ToolTip.foregroundInactive");
}
else {
LookAndFeel.installColors(c,"ToolTip.background",
"ToolTip.foreground");
}
} else {
LookAndFeel.installBorder(c, "ToolTip.border");
LookAndFeel.installColors(c, "ToolTip.background",
"ToolTip.foreground");
}
}
private static class PropertyChangeHandler implements
PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
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);
}
else if ("component".equals(name)) {
JToolTip tip = ((JToolTip) e.getSource());
if (tip.getUI() instanceof BasicToolTipUI) {
((BasicToolTipUI)tip.getUI()).componentChanged(tip);
}
}
}
}
}

View File

@@ -0,0 +1,293 @@
/*
* Copyright (c) 2000, 2002, 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.basic;
import sun.awt.datatransfer.DataTransferer;
import java.io.*;
import java.awt.datatransfer.*;
import javax.swing.plaf.UIResource;
/**
* A transferable implementation for the default data transfer of some Swing
* components.
*
* @author Timothy Prinzing
*/
class BasicTransferable implements Transferable, UIResource {
protected String plainData;
protected String htmlData;
private static DataFlavor[] htmlFlavors;
private static DataFlavor[] stringFlavors;
private static DataFlavor[] plainFlavors;
static {
try {
htmlFlavors = new DataFlavor[3];
htmlFlavors[0] = new DataFlavor("text/html;class=java.lang.String");
htmlFlavors[1] = new DataFlavor("text/html;class=java.io.Reader");
htmlFlavors[2] = new DataFlavor("text/html;charset=unicode;class=java.io.InputStream");
plainFlavors = new DataFlavor[3];
plainFlavors[0] = new DataFlavor("text/plain;class=java.lang.String");
plainFlavors[1] = new DataFlavor("text/plain;class=java.io.Reader");
plainFlavors[2] = new DataFlavor("text/plain;charset=unicode;class=java.io.InputStream");
stringFlavors = new DataFlavor[2];
stringFlavors[0] = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType+";class=java.lang.String");
stringFlavors[1] = DataFlavor.stringFlavor;
} catch (ClassNotFoundException cle) {
System.err.println("error initializing javax.swing.plaf.basic.BasicTranserable");
}
}
public BasicTransferable(String plainData, String htmlData) {
this.plainData = plainData;
this.htmlData = htmlData;
}
/**
* Returns an array of DataFlavor objects indicating the flavors the data
* can be provided in. The array should be ordered according to preference
* for providing the data (from most richly descriptive to least descriptive).
* @return an array of data flavors in which this data can be transferred
*/
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] richerFlavors = getRicherFlavors();
int nRicher = (richerFlavors != null) ? richerFlavors.length : 0;
int nHTML = (isHTMLSupported()) ? htmlFlavors.length : 0;
int nPlain = (isPlainSupported()) ? plainFlavors.length: 0;
int nString = (isPlainSupported()) ? stringFlavors.length : 0;
int nFlavors = nRicher + nHTML + nPlain + nString;
DataFlavor[] flavors = new DataFlavor[nFlavors];
// fill in the array
int nDone = 0;
if (nRicher > 0) {
System.arraycopy(richerFlavors, 0, flavors, nDone, nRicher);
nDone += nRicher;
}
if (nHTML > 0) {
System.arraycopy(htmlFlavors, 0, flavors, nDone, nHTML);
nDone += nHTML;
}
if (nPlain > 0) {
System.arraycopy(plainFlavors, 0, flavors, nDone, nPlain);
nDone += nPlain;
}
if (nString > 0) {
System.arraycopy(stringFlavors, 0, flavors, nDone, nString);
nDone += nString;
}
return flavors;
}
/**
* Returns whether or not the specified data flavor is supported for
* this object.
* @param flavor the requested flavor for the data
* @return boolean indicating whether or not the data flavor is supported
*/
public boolean isDataFlavorSupported(DataFlavor flavor) {
DataFlavor[] flavors = getTransferDataFlavors();
for (int i = 0; i < flavors.length; i++) {
if (flavors[i].equals(flavor)) {
return true;
}
}
return false;
}
/**
* Returns an object which represents the data to be transferred. The class
* of the object returned is defined by the representation class of the flavor.
*
* @param flavor the requested flavor for the data
* @see DataFlavor#getRepresentationClass
* @exception IOException if the data is no longer available
* in the requested flavor.
* @exception UnsupportedFlavorException if the requested data flavor is
* not supported.
*/
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
DataFlavor[] richerFlavors = getRicherFlavors();
if (isRicherFlavor(flavor)) {
return getRicherData(flavor);
} else if (isHTMLFlavor(flavor)) {
String data = getHTMLData();
data = (data == null) ? "" : data;
if (String.class.equals(flavor.getRepresentationClass())) {
return data;
} else if (Reader.class.equals(flavor.getRepresentationClass())) {
return new StringReader(data);
} else if (InputStream.class.equals(flavor.getRepresentationClass())) {
return createInputStream(flavor, data);
}
// fall through to unsupported
} else if (isPlainFlavor(flavor)) {
String data = getPlainData();
data = (data == null) ? "" : data;
if (String.class.equals(flavor.getRepresentationClass())) {
return data;
} else if (Reader.class.equals(flavor.getRepresentationClass())) {
return new StringReader(data);
} else if (InputStream.class.equals(flavor.getRepresentationClass())) {
return createInputStream(flavor, data);
}
// fall through to unsupported
} else if (isStringFlavor(flavor)) {
String data = getPlainData();
data = (data == null) ? "" : data;
return data;
}
throw new UnsupportedFlavorException(flavor);
}
private InputStream createInputStream(DataFlavor flavor, String data)
throws IOException, UnsupportedFlavorException {
String cs = DataTransferer.getTextCharset(flavor);
if (cs == null) {
throw new UnsupportedFlavorException(flavor);
}
return new ByteArrayInputStream(data.getBytes(cs));
}
// --- richer subclass flavors ----------------------------------------------
protected boolean isRicherFlavor(DataFlavor flavor) {
DataFlavor[] richerFlavors = getRicherFlavors();
int nFlavors = (richerFlavors != null) ? richerFlavors.length : 0;
for (int i = 0; i < nFlavors; i++) {
if (richerFlavors[i].equals(flavor)) {
return true;
}
}
return false;
}
/**
* Some subclasses will have flavors that are more descriptive than HTML
* or plain text. If this method returns a non-null value, it will be
* placed at the start of the array of supported flavors.
*/
protected DataFlavor[] getRicherFlavors() {
return null;
}
protected Object getRicherData(DataFlavor flavor) throws UnsupportedFlavorException {
return null;
}
// --- html flavors ----------------------------------------------------------
/**
* Returns whether or not the specified data flavor is an HTML flavor that
* is supported.
* @param flavor the requested flavor for the data
* @return boolean indicating whether or not the data flavor is supported
*/
protected boolean isHTMLFlavor(DataFlavor flavor) {
DataFlavor[] flavors = htmlFlavors;
for (int i = 0; i < flavors.length; i++) {
if (flavors[i].equals(flavor)) {
return true;
}
}
return false;
}
/**
* Should the HTML flavors be offered? If so, the method
* getHTMLData should be implemented to provide something reasonable.
*/
protected boolean isHTMLSupported() {
return htmlData != null;
}
/**
* Fetch the data in a text/html format
*/
protected String getHTMLData() {
return htmlData;
}
// --- plain text flavors ----------------------------------------------------
/**
* Returns whether or not the specified data flavor is an plain flavor that
* is supported.
* @param flavor the requested flavor for the data
* @return boolean indicating whether or not the data flavor is supported
*/
protected boolean isPlainFlavor(DataFlavor flavor) {
DataFlavor[] flavors = plainFlavors;
for (int i = 0; i < flavors.length; i++) {
if (flavors[i].equals(flavor)) {
return true;
}
}
return false;
}
/**
* Should the plain text flavors be offered? If so, the method
* getPlainData should be implemented to provide something reasonable.
*/
protected boolean isPlainSupported() {
return plainData != null;
}
/**
* Fetch the data in a text/plain format.
*/
protected String getPlainData() {
return plainData;
}
// --- string flavorss --------------------------------------------------------
/**
* Returns whether or not the specified data flavor is a String flavor that
* is supported.
* @param flavor the requested flavor for the data
* @return boolean indicating whether or not the data flavor is supported
*/
protected boolean isStringFlavor(DataFlavor flavor) {
DataFlavor[] flavors = stringFlavors;
for (int i = 0; i < flavors.length; i++) {
if (flavors[i].equals(flavor)) {
return true;
}
}
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 1998, 2010, 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.basic;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.awt.*;
import java.awt.event.*;
/**
* BasicViewport implementation
*
* @author Rich Schiavi
*/
public class BasicViewportUI extends ViewportUI {
// Shared UI object
private static ViewportUI viewportUI;
public static ComponentUI createUI(JComponent c) {
if(viewportUI == null) {
viewportUI = new BasicViewportUI();
}
return viewportUI;
}
public void installUI(JComponent c) {
super.installUI(c);
installDefaults(c);
}
public void uninstallUI(JComponent c) {
uninstallDefaults(c);
super.uninstallUI(c);
}
protected void installDefaults(JComponent c) {
LookAndFeel.installColorsAndFont(c,
"Viewport.background",
"Viewport.foreground",
"Viewport.font");
LookAndFeel.installProperty(c, "opaque", Boolean.TRUE);
}
protected void uninstallDefaults(JComponent c) {
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 1998, 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.basic;
import java.awt.*;
import java.io.*;
/**
* Center-positioning layout manager.
* @author Tom Santos
* @author Steve Wilson
*/
class CenterLayout implements LayoutManager, Serializable {
public void addLayoutComponent(String name, Component comp) { }
public void removeLayoutComponent(Component comp) { }
public Dimension preferredLayoutSize( Container container ) {
Component c = container.getComponent( 0 );
if ( c != null ) {
Dimension size = c.getPreferredSize();
Insets insets = container.getInsets();
return new Dimension(size.width + insets.left + insets.right,
size.height + insets.top + insets.bottom);
}
else {
return new Dimension( 0, 0 );
}
}
public Dimension minimumLayoutSize(Container cont) {
return preferredLayoutSize(cont);
}
public void layoutContainer(Container container) {
if (container.getComponentCount() > 0) {
Component c = container.getComponent(0);
Dimension pref = c.getPreferredSize();
int containerWidth = container.getWidth();
int containerHeight = container.getHeight();
Insets containerInsets = container.getInsets();
containerWidth -= containerInsets.left +
containerInsets.right;
containerHeight -= containerInsets.top +
containerInsets.bottom;
int left = (containerWidth - pref.width) / 2 +
containerInsets.left;
int right = (containerHeight - pref.height) / 2 +
containerInsets.top;
c.setBounds(left, right, pref.width, pref.height);
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 1998, 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.basic;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.KeyListener;
import javax.swing.JList;
/**
* The interface which defines the methods required for the implementation of the popup
* portion of a combo box.
* <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&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Tom Santos
*/
public interface ComboPopup {
/**
* Shows the popup
*/
public void show();
/**
* Hides the popup
*/
public void hide();
/**
* Returns true if the popup is visible (currently being displayed).
*
* @return <code>true</code> if the component is visible; <code>false</code> otherwise.
*/
public boolean isVisible();
/**
* Returns the list that is being used to draw the items in the combo box.
* This method is highly implementation specific and should not be used
* for general list manipulation.
*/
public JList getList();
/**
* Returns a mouse listener that will be added to the combo box or null.
* If this method returns null then it will not be added to the combo box.
*
* @return a <code>MouseListener</code> or null
*/
public MouseListener getMouseListener();
/**
* Returns a mouse motion listener that will be added to the combo box or null.
* If this method returns null then it will not be added to the combo box.
*
* @return a <code>MouseMotionListener</code> or null
*/
public MouseMotionListener getMouseMotionListener();
/**
* Returns a key listener that will be added to the combo box or null.
* If this method returns null then it will not be added to the combo box.
*/
public KeyListener getKeyListener();
/**
* Called to inform the ComboPopup that the UI is uninstalling.
* If the ComboPopup added any listeners in the component, it should remove them here.
*/
public void uninstallingUI();
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 1998, 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.basic;
import javax.swing.*;
import javax.swing.plaf.UIResource;
import java.awt.Container;
import java.awt.Dimension;
/**
* The default layout manager for Popup menus and menubars. This
* class is an extension of BoxLayout which adds the UIResource tag
* so that pluggable L&amp;Fs can distinguish it from user-installed
* layout managers on menus.
*
* @author Georges Saab
*/
public class DefaultMenuLayout extends BoxLayout implements UIResource {
public DefaultMenuLayout(Container target, int axis) {
super(target, axis);
}
public Dimension preferredLayoutSize(Container target) {
if (target instanceof JPopupMenu) {
JPopupMenu popupMenu = (JPopupMenu) target;
sun.swing.MenuItemLayoutHelper.clearUsedClientProperties(popupMenu);
if (popupMenu.getComponentCount() == 0) {
return new Dimension(0, 0);
}
}
// Make BoxLayout recalculate cached preferred sizes
super.invalidateLayout(target);
return super.preferredLayoutSize(target);
}
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) 2005, 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.basic;
import java.awt.Toolkit;
import java.awt.event.*;
import java.awt.dnd.DragSource;
import javax.swing.*;
import sun.awt.dnd.SunDragSourceContextPeer;
import sun.awt.AppContext;
/**
* Drag gesture recognition support for classes that have a
* <code>TransferHandler</code>. The gesture for a drag in this class is a mouse
* press followed by movement by <code>DragSource.getDragThreshold()</code>
* pixels. An instance of this class is maintained per AppContext, and the
* public static methods call into the appropriate instance.
*
* @author Shannon Hickey
*/
class DragRecognitionSupport {
private int motionThreshold;
private MouseEvent dndArmedEvent;
private JComponent component;
/**
* This interface allows us to pass in a handler to mouseDragged,
* so that we can be notified immediately before a drag begins.
*/
public static interface BeforeDrag {
public void dragStarting(MouseEvent me);
}
/**
* Returns the DragRecognitionSupport for the caller's AppContext.
*/
private static DragRecognitionSupport getDragRecognitionSupport() {
DragRecognitionSupport support =
(DragRecognitionSupport)AppContext.getAppContext().
get(DragRecognitionSupport.class);
if (support == null) {
support = new DragRecognitionSupport();
AppContext.getAppContext().put(DragRecognitionSupport.class, support);
}
return support;
}
/**
* Returns whether or not the event is potentially part of a drag sequence.
*/
public static boolean mousePressed(MouseEvent me) {
return getDragRecognitionSupport().mousePressedImpl(me);
}
/**
* If a dnd recognition has been going on, return the MouseEvent
* that started the recognition. Otherwise, return null.
*/
public static MouseEvent mouseReleased(MouseEvent me) {
return getDragRecognitionSupport().mouseReleasedImpl(me);
}
/**
* Returns whether or not a drag gesture recognition is ongoing.
*/
public static boolean mouseDragged(MouseEvent me, BeforeDrag bd) {
return getDragRecognitionSupport().mouseDraggedImpl(me, bd);
}
private void clearState() {
dndArmedEvent = null;
component = null;
}
private int mapDragOperationFromModifiers(MouseEvent me,
TransferHandler th) {
if (th == null || !SwingUtilities.isLeftMouseButton(me)) {
return TransferHandler.NONE;
}
return SunDragSourceContextPeer.
convertModifiersToDropAction(me.getModifiersEx(),
th.getSourceActions(component));
}
/**
* Returns whether or not the event is potentially part of a drag sequence.
*/
private boolean mousePressedImpl(MouseEvent me) {
component = (JComponent)me.getSource();
if (mapDragOperationFromModifiers(me, component.getTransferHandler())
!= TransferHandler.NONE) {
motionThreshold = DragSource.getDragThreshold();
dndArmedEvent = me;
return true;
}
clearState();
return false;
}
/**
* If a dnd recognition has been going on, return the MouseEvent
* that started the recognition. Otherwise, return null.
*/
private MouseEvent mouseReleasedImpl(MouseEvent me) {
/* no recognition has been going on */
if (dndArmedEvent == null) {
return null;
}
MouseEvent retEvent = null;
if (me.getSource() == component) {
retEvent = dndArmedEvent;
} // else component has changed unexpectedly, so return null
clearState();
return retEvent;
}
/**
* Returns whether or not a drag gesture recognition is ongoing.
*/
private boolean mouseDraggedImpl(MouseEvent me, BeforeDrag bd) {
/* no recognition is in progress */
if (dndArmedEvent == null) {
return false;
}
/* component has changed unexpectedly, so bail */
if (me.getSource() != component) {
clearState();
return false;
}
int dx = Math.abs(me.getX() - dndArmedEvent.getX());
int dy = Math.abs(me.getY() - dndArmedEvent.getY());
if ((dx > motionThreshold) || (dy > motionThreshold)) {
TransferHandler th = component.getTransferHandler();
int action = mapDragOperationFromModifiers(me, th);
if (action != TransferHandler.NONE) {
/* notify the BeforeDrag instance */
if (bd != null) {
bd.dragStarting(dndArmedEvent);
}
th.exportAsDrag(component, dndArmedEvent, action);
clearState();
}
}
return true;
}
}

View File

@@ -0,0 +1,165 @@
/*
* 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.basic;
import java.lang.reflect.*;
import javax.swing.*;
import javax.swing.plaf.*;
/**
* An ActionMap that populates its contents as necessary. The
* contents are populated by invoking the <code>loadActionMap</code>
* method on the passed in Object.
*
* @author Scott Violet
*/
class LazyActionMap extends ActionMapUIResource {
/**
* Object to invoke <code>loadActionMap</code> on. This may be
* a Class object.
*/
private transient Object _loader;
/**
* Installs an ActionMap that will be populated by invoking the
* <code>loadActionMap</code> method on the specified Class
* when necessary.
* <p>
* This should be used if the ActionMap can be shared.
*
* @param c JComponent to install the ActionMap on.
* @param loaderClass Class object that gets loadActionMap invoked
* on.
* @param defaultsKey Key to use to defaults table to check for
* existing map and what resulting Map will be registered on.
*/
static void installLazyActionMap(JComponent c, Class loaderClass,
String defaultsKey) {
ActionMap map = (ActionMap)UIManager.get(defaultsKey);
if (map == null) {
map = new LazyActionMap(loaderClass);
UIManager.getLookAndFeelDefaults().put(defaultsKey, map);
}
SwingUtilities.replaceUIActionMap(c, map);
}
/**
* Returns an ActionMap that will be populated by invoking the
* <code>loadActionMap</code> method on the specified Class
* when necessary.
* <p>
* This should be used if the ActionMap can be shared.
*
* @param c JComponent to install the ActionMap on.
* @param loaderClass Class object that gets loadActionMap invoked
* on.
* @param defaultsKey Key to use to defaults table to check for
* existing map and what resulting Map will be registered on.
*/
static ActionMap getActionMap(Class loaderClass,
String defaultsKey) {
ActionMap map = (ActionMap)UIManager.get(defaultsKey);
if (map == null) {
map = new LazyActionMap(loaderClass);
UIManager.getLookAndFeelDefaults().put(defaultsKey, map);
}
return map;
}
private LazyActionMap(Class loader) {
_loader = loader;
}
public void put(Action action) {
put(action.getValue(Action.NAME), action);
}
public void put(Object key, Action action) {
loadIfNecessary();
super.put(key, action);
}
public Action get(Object key) {
loadIfNecessary();
return super.get(key);
}
public void remove(Object key) {
loadIfNecessary();
super.remove(key);
}
public void clear() {
loadIfNecessary();
super.clear();
}
public Object[] keys() {
loadIfNecessary();
return super.keys();
}
public int size() {
loadIfNecessary();
return super.size();
}
public Object[] allKeys() {
loadIfNecessary();
return super.allKeys();
}
public void setParent(ActionMap map) {
loadIfNecessary();
super.setParent(map);
}
private void loadIfNecessary() {
if (_loader != null) {
Object loader = _loader;
_loader = null;
Class<?> klass = (Class<?>)loader;
try {
Method method = klass.getDeclaredMethod("loadActionMap",
new Class[] { LazyActionMap.class });
method.invoke(klass, new Object[] { this });
} catch (NoSuchMethodException nsme) {
assert false : "LazyActionMap unable to load actions " +
klass;
} catch (IllegalAccessException iae) {
assert false : "LazyActionMap unable to load actions " +
iae;
} catch (InvocationTargetException ite) {
assert false : "LazyActionMap unable to load actions " +
ite;
} catch (IllegalArgumentException iae) {
assert false : "LazyActionMap unable to load actions " +
iae;
}
}
}
}