- /*
- * @(#)WindowsScrollBarUI.java 1.19 03/12/19
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package com.sun.java.swing.plaf.windows;
-
- import java.awt.*;
- import java.awt.image.*;
- import java.lang.ref.*;
- import java.util.*;
- import javax.swing.plaf.basic.*;
- import javax.swing.*;
- import javax.swing.plaf.ComponentUI;
-
-
-
- /**
- * Windows rendition of the component.
- * <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. A future release of Swing will provide support for
- * long term persistence.
- */
- public class WindowsScrollBarUI extends BasicScrollBarUI {
- private Grid thumbGrid;
- private Grid highlightGrid;
-
- /**
- * Creates a UI for a JScrollBar.
- *
- * @param c the text field
- * @return the UI
- */
- public static ComponentUI createUI(JComponent c) {
- return new WindowsScrollBarUI();
- }
-
- protected void installDefaults() {
- super.installDefaults();
-
- if (XPStyle.getXP() != null) {
- scrollbar.setBorder(null);
- }
- }
-
- public void uninstallUI(JComponent c) {
- super.uninstallUI(c);
- thumbGrid = highlightGrid = null;
- }
-
- protected void configureScrollBarColors() {
- super.configureScrollBarColors();
- Color color = UIManager.getColor("ScrollBar.trackForeground");
- if (color != null && trackColor != null) {
- thumbGrid = Grid.getGrid(color, trackColor);
- }
-
- color = UIManager.getColor("ScrollBar.trackHighlightForeground");
- if (color != null && trackHighlightColor != null) {
- highlightGrid = Grid.getGrid(color, trackHighlightColor);
- }
- }
-
- protected JButton createDecreaseButton(int orientation) {
- return new WindowsArrowButton(orientation,
- UIManager.getColor("ScrollBar.thumb"),
- UIManager.getColor("ScrollBar.thumbShadow"),
- UIManager.getColor("ScrollBar.thumbDarkShadow"),
- UIManager.getColor("ScrollBar.thumbHighlight"));
- }
-
- protected JButton createIncreaseButton(int orientation) {
- return new WindowsArrowButton(orientation,
- UIManager.getColor("ScrollBar.thumb"),
- UIManager.getColor("ScrollBar.thumbShadow"),
- UIManager.getColor("ScrollBar.thumbDarkShadow"),
- UIManager.getColor("ScrollBar.thumbHighlight"));
- }
-
-
- protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds){
- boolean v = (scrollbar.getOrientation() == JScrollBar.VERTICAL);
-
- XPStyle xp = XPStyle.getXP();
- if (xp != null) {
- JScrollBar sb = (JScrollBar)c;
- int index = 0;
- // Pending: Implement rollover 1 and pressed 2
- if (!sb.isEnabled()) {
- index = 3;
- }
- String category = v ? "scrollbar.lowertrackvert" : "scrollbar.lowertrackhorz";
- xp.getSkin(category).paintSkin(g, trackBounds, index);
- } else if (thumbGrid == null) {
- super.paintTrack(g, c, trackBounds);
- }
- else {
- thumbGrid.paint(g, trackBounds.x, trackBounds.y, trackBounds.width,
- trackBounds.height);
- if (trackHighlight == DECREASE_HIGHLIGHT) {
- paintDecreaseHighlight(g);
- }
- else if (trackHighlight == INCREASE_HIGHLIGHT) {
- paintIncreaseHighlight(g);
- }
- }
- }
-
- protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
- boolean v = (scrollbar.getOrientation() == JScrollBar.VERTICAL);
-
- XPStyle xp = XPStyle.getXP();
- if (xp != null) {
- JScrollBar sb = (JScrollBar)c;
- int index = 0;
- if (!sb.isEnabled()) {
- index = 3;
- } else if (isDragging) {
- index = 2;
- } else if (isThumbRollover()) {
- index = 1;
- }
- // Paint thumb
- XPStyle.Skin skin = xp.getSkin(v ? "scrollbar.thumbbtnvert" : "scrollbar.thumbbtnhorz");
- skin.paintSkin(g, thumbBounds, index);
- // Paint gripper
- skin = xp.getSkin(v ? "scrollbar.grippervert" : "scrollbar.gripperhorz");
- skin.paintSkin(g,
- thumbBounds.x + (thumbBounds.width - skin.getWidth()) / 2,
- thumbBounds.y + (thumbBounds.height - skin.getHeight()) / 2,
- skin.getWidth(), skin.getHeight(), index);
-
- } else {
- super.paintThumb(g, c, thumbBounds);
- }
- }
-
-
- protected void paintDecreaseHighlight(Graphics g) {
- if (highlightGrid == null) {
- super.paintDecreaseHighlight(g);
- }
- else {
- Insets insets = scrollbar.getInsets();
- Rectangle thumbR = getThumbBounds();
- int x, y, w, h;
-
- if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
- x = insets.left;
- y = decrButton.getY() + decrButton.getHeight();
- w = scrollbar.getWidth() - (insets.left + insets.right);
- h = thumbR.y - y;
- }
- else {
- x = decrButton.getX() + decrButton.getHeight();
- y = insets.top;
- w = thumbR.x - x;
- h = scrollbar.getHeight() - (insets.top + insets.bottom);
- }
- highlightGrid.paint(g, x, y, w, h);
- }
- }
-
-
- protected void paintIncreaseHighlight(Graphics g) {
- if (highlightGrid == null) {
- super.paintDecreaseHighlight(g);
- }
- else {
- Insets insets = scrollbar.getInsets();
- Rectangle thumbR = getThumbBounds();
- int x, y, w, h;
-
- if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
- x = insets.left;
- y = thumbR.y + thumbR.height;
- w = scrollbar.getWidth() - (insets.left + insets.right);
- h = incrButton.getY() - y;
- }
- else {
- x = thumbR.x + thumbR.width;
- y = insets.top;
- w = incrButton.getX() - x;
- h = scrollbar.getHeight() - (insets.top + insets.bottom);
- }
- highlightGrid.paint(g, x, y, w, h);
- }
- }
-
-
- /**
- * WindowsArrowButton is used for the buttons to position the
- * document up/down. It differs from BasicArrowButton in that the
- * preferred size is always a square.
- */
- private class WindowsArrowButton extends BasicArrowButton {
-
- public WindowsArrowButton(int direction, Color background, Color shadow,
- Color darkShadow, Color highlight) {
- super(direction, background, shadow, darkShadow, highlight);
- }
-
- public WindowsArrowButton(int direction) {
- super(direction);
- }
-
- public void paint(Graphics g) {
- XPStyle xp = XPStyle.getXP();
- if (xp != null) {
- ButtonModel model = getModel();
- XPStyle.Skin skin = xp.getSkin("scrollbar.arrowbtn");
- int index = 0;
- switch (direction) {
- case NORTH: index = 0; break;
- case SOUTH: index = 4; break;
- case WEST: index = 8; break;
- case EAST: index = 12; break;
- }
-
- // normal, rollover, pressed, disabled
- if (model.isArmed() && model.isPressed()) {
- index += 2;
- } else if (!model.isEnabled()) {
- index += 3;
- } else if (model.isRollover() || model.isPressed()) {
- index += 1;
- }
-
- skin.paintSkin(g, 0, 0, getSize().width, getSize().height, index);
- } else {
- super.paint(g);
- }
- }
-
- public Dimension getPreferredSize() {
- int size = 16;
- if (scrollbar != null) {
- switch (scrollbar.getOrientation()) {
- case JScrollBar.VERTICAL:
- size = scrollbar.getWidth();
- break;
- case JScrollBar.HORIZONTAL:
- size = scrollbar.getHeight();
- break;
- }
- size = Math.max(size, 5);
- }
- return new Dimension(size, size);
- }
- }
-
-
- /**
- * This should be pulled out into its own class if more classes need to
- * use it.
- * <p>
- * Grid is used to draw the track for windows scrollbars. Grids
- * are cached in a HashMap, with the key being the rgb components
- * of the foreground/background colors. Further the Grid is held through
- * a WeakRef so that it can be freed when no longer needed. As the
- * Grid is rather expensive to draw, it is drawn in a BufferedImage.
- */
- private static class Grid {
- private static final int BUFFER_SIZE = 64;
- private static HashMap map;
-
- private BufferedImage image;
-
- static {
- map = new HashMap();
- }
-
- public static Grid getGrid(Color fg, Color bg) {
- String key = fg.getRGB() + " " + bg.getRGB();
- WeakReference ref = (WeakReference)map.get(key);
- Grid grid = (ref == null) ? null : (Grid)ref.get();
- if (grid == null) {
- grid = new Grid(fg, bg);
- map.put(key, new WeakReference(grid));
- }
- return grid;
- }
-
- public Grid(Color fg, Color bg) {
- int cmap[] = { fg.getRGB(), bg.getRGB() };
- IndexColorModel icm = new IndexColorModel(8, 2, cmap, 0, false, -1,
- DataBuffer.TYPE_BYTE);
- image = new BufferedImage(BUFFER_SIZE, BUFFER_SIZE,
- BufferedImage.TYPE_BYTE_INDEXED, icm);
- Graphics g = image.getGraphics();
- try {
- g.setClip(0, 0, BUFFER_SIZE, BUFFER_SIZE);
- paintGrid(g, fg, bg);
- }
- finally {
- g.dispose();
- }
- }
-
- /**
- * Paints the grid into the specified Graphics at the specified
- * location.
- */
- public void paint(Graphics g, int x, int y, int w, int h) {
- Rectangle clipRect = g.getClipBounds();
- int minX = Math.max(x, clipRect.x);
- int minY = Math.max(y, clipRect.y);
- int maxX = Math.min(clipRect.x + clipRect.width, x + w);
- int maxY = Math.min(clipRect.y + clipRect.height, y + h);
-
- if (maxX <= minX || maxY <= minY) {
- return;
- }
- int xOffset = (minX - x) % 2;
- for (int xCounter = minX; xCounter < maxX;
- xCounter += BUFFER_SIZE) {
- int yOffset = (minY - y) % 2;
- int width = Math.min(BUFFER_SIZE - xOffset,
- maxX - xCounter);
-
- for (int yCounter = minY; yCounter < maxY;
- yCounter += BUFFER_SIZE) {
- int height = Math.min(BUFFER_SIZE - yOffset,
- maxY - yCounter);
-
- g.drawImage(image, xCounter, yCounter,
- xCounter + width, yCounter + height,
- xOffset, yOffset,
- xOffset + width, yOffset + height, null);
- if (yOffset != 0) {
- yCounter -= yOffset;
- yOffset = 0;
- }
- }
- if (xOffset != 0) {
- xCounter -= xOffset;
- xOffset = 0;
- }
- }
- }
-
- /**
- * Actually renders the grid into the Graphics <code>g</code>.
- */
- private void paintGrid(Graphics g, Color fg, Color bg) {
- Rectangle clipRect = g.getClipBounds();
- g.setColor(bg);
- g.fillRect(clipRect.x, clipRect.y, clipRect.width,
- clipRect.height);
- g.setColor(fg);
- g.translate(clipRect.x, clipRect.y);
- int width = clipRect.width;
- int height = clipRect.height;
- int xCounter = clipRect.x % 2;
- for (int end = width - height; xCounter < end; xCounter += 2) {
- g.drawLine(xCounter, 0, xCounter + height, height);
- }
- for (int end = width; xCounter < end; xCounter += 2) {
- g.drawLine(xCounter, 0, width, width - xCounter);
- }
-
- int yCounter = ((clipRect.x % 2) == 0) ? 2 : 1;
- for (int end = height - width; yCounter < end; yCounter += 2) {
- g.drawLine(0, yCounter, width, yCounter + width);
- }
- for (int end = height; yCounter < end; yCounter += 2) {
- g.drawLine(0, yCounter, height - yCounter, height);
- }
- g.translate(-clipRect.x, -clipRect.y);
- }
- }
- }