| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to you under the Apache License, |
| * Version 2.0 (the "License"); you may not use this file except in |
| * compliance with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.pivot.wtk.skin.terra; |
| |
| import java.awt.BasicStroke; |
| import java.awt.Color; |
| import java.awt.Font; |
| import java.awt.GradientPaint; |
| import java.awt.Graphics2D; |
| import java.awt.geom.Rectangle2D; |
| |
| import org.apache.pivot.collections.Dictionary; |
| import org.apache.pivot.collections.List; |
| import org.apache.pivot.util.Utils; |
| import org.apache.pivot.wtk.ApplicationContext; |
| import org.apache.pivot.wtk.Bounds; |
| import org.apache.pivot.wtk.Component; |
| import org.apache.pivot.wtk.Dimensions; |
| import org.apache.pivot.wtk.GraphicsUtilities; |
| import org.apache.pivot.wtk.Keyboard.KeyCode; |
| import org.apache.pivot.wtk.Keyboard.KeyLocation; |
| import org.apache.pivot.wtk.Mouse; |
| import org.apache.pivot.wtk.Orientation; |
| import org.apache.pivot.wtk.Spinner; |
| import org.apache.pivot.wtk.SpinnerListener; |
| import org.apache.pivot.wtk.SpinnerSelectionListener; |
| import org.apache.pivot.wtk.Theme; |
| import org.apache.pivot.wtk.media.Image; |
| import org.apache.pivot.wtk.skin.ComponentSkin; |
| import org.apache.pivot.wtk.skin.ContainerSkin; |
| |
| /** |
| * Spinner skin. |
| */ |
| public class TerraSpinnerSkin extends ContainerSkin implements Spinner.Skin, SpinnerListener, |
| SpinnerSelectionListener { |
| /** |
| * Encapsulates the code needed to perform timer-controlled spinning. |
| */ |
| private static class AutomaticSpinner { |
| public Spinner spinner; |
| public int direction; |
| |
| private ApplicationContext.ScheduledCallback scheduledSpinnerCallback = null; |
| |
| /** |
| * Starts spinning the specified spinner. |
| * |
| * @param spinnerArgument The spinner to spin |
| * @param directionArgument <tt>1</tt> to adjust the spinner's selected |
| * index larger; <tt>-1</tt> to adjust it smaller |
| * @exception IllegalStateException If automatic spinner of any spinner |
| * is already in progress. Only one spinner may be automatically spun at |
| * one time |
| */ |
| public void start(Spinner spinnerArgument, int directionArgument) { |
| assert (directionArgument != 0) : "Spinner direction must be positive or negative"; |
| |
| if (scheduledSpinnerCallback != null) { |
| throw new IllegalStateException("Spinner is already running"); |
| } |
| |
| this.spinner = spinnerArgument; |
| this.direction = directionArgument; |
| |
| // Run once to register we've started, then wait a timeout period and begin rapidly spinning |
| scheduledSpinnerCallback = ApplicationContext.runAndScheduleRecurringCallback(() -> spin(), 400, 30); |
| } |
| |
| private void spin() { |
| boolean circular = spinner.isCircular(); |
| int selectedIndex = spinner.getSelectedIndex(); |
| int count = spinner.getSpinnerData().getLength(); |
| if (count < 1) { |
| // empty spinner |
| stop(); |
| return; |
| } |
| |
| if (direction > 0) { |
| if (selectedIndex < count - 1) { |
| spinner.setSelectedIndex(selectedIndex + 1); |
| } else if (circular) { |
| spinner.setSelectedIndex(0); |
| } else { |
| stop(); |
| } |
| } else { |
| if (selectedIndex > 0) { |
| spinner.setSelectedIndex(selectedIndex - 1); |
| } else if (circular) { |
| spinner.setSelectedIndex(count - 1); |
| } else { |
| stop(); |
| } |
| } |
| } |
| |
| /** |
| * Stops any automatic spinning in progress. |
| */ |
| public void stop() { |
| if (scheduledSpinnerCallback != null) { |
| scheduledSpinnerCallback.cancel(); |
| scheduledSpinnerCallback = null; |
| } |
| } |
| } |
| |
| /** |
| * Component that holds the content of a spinner. It is the focusable part |
| * of a spinner. |
| */ |
| protected class SpinnerContent extends Component { |
| public SpinnerContent() { |
| setSkin(new SpinnerContentSkin()); |
| } |
| } |
| |
| /** |
| * SpinnerContent skin. |
| */ |
| protected class SpinnerContentSkin extends ComponentSkin { |
| @Override |
| public int getPreferredWidth(int height) { |
| int preferredWidth = 0; |
| |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| Spinner.ItemRenderer itemRenderer = spinner.getItemRenderer(); |
| |
| if (sizeToContent) { |
| List<?> spinnerData = spinner.getSpinnerData(); |
| for (Object item : spinnerData) { |
| itemRenderer.render(item, spinner); |
| preferredWidth = Math.max(preferredWidth, |
| itemRenderer.getPreferredWidth(height)); |
| } |
| } else { |
| itemRenderer.render(spinner.getSelectedItem(), spinner); |
| preferredWidth = itemRenderer.getPreferredWidth(height); |
| } |
| |
| return preferredWidth; |
| } |
| |
| @Override |
| public int getPreferredHeight(int width) { |
| int preferredHeight = 0; |
| |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| Spinner.ItemRenderer itemRenderer = spinner.getItemRenderer(); |
| |
| itemRenderer.render(spinner.getSelectedItem(), spinner); |
| preferredHeight = itemRenderer.getPreferredHeight(width); |
| |
| return preferredHeight; |
| } |
| |
| @Override |
| public int getBaseline(int width, int height) { |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| |
| int baseline = -1; |
| |
| Spinner.ItemRenderer itemRenderer = spinner.getItemRenderer(); |
| itemRenderer.render(spinner.getSelectedItem(), spinner); |
| baseline = itemRenderer.getBaseline(width, height); |
| |
| return baseline; |
| } |
| |
| @Override |
| public Dimensions getPreferredSize() { |
| Dimensions preferredSize; |
| |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| Spinner.ItemRenderer itemRenderer = spinner.getItemRenderer(); |
| |
| if (sizeToContent) { |
| preferredSize = new Dimensions(getPreferredWidth(-1), getPreferredHeight(-1)); |
| } else { |
| itemRenderer.render(spinner.getSelectedItem(), spinner); |
| preferredSize = itemRenderer.getPreferredSize(); |
| } |
| |
| return preferredSize; |
| } |
| |
| @Override |
| public void layout() { |
| // No-op |
| } |
| |
| @Override |
| public void paint(Graphics2D graphics) { |
| SpinnerContent spinnerContentLocal = (SpinnerContent) getComponent(); |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| |
| int width = getWidth(); |
| int height = getHeight(); |
| |
| // Paint the content |
| Spinner.ItemRenderer itemRenderer = spinner.getItemRenderer(); |
| itemRenderer.render(spinner.getSelectedItem(), spinner); |
| |
| Graphics2D contentGraphics = (Graphics2D) graphics.create(); |
| itemRenderer.setSize(width, height); |
| itemRenderer.paint(contentGraphics); |
| contentGraphics.dispose(); |
| |
| // Paint the focus state |
| if (spinnerContentLocal.isFocused()) { |
| BasicStroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, |
| BasicStroke.JOIN_ROUND, 1.0f, new float[] {0.0f, 2.0f}, 0.0f); |
| |
| graphics.setStroke(dashStroke); |
| graphics.setColor(borderColor); |
| |
| GraphicsUtilities.setAntialiasingOn(graphics); |
| |
| graphics.draw(new Rectangle2D.Double(1, 1.5, Math.max(width - 2.5, 0), Math.max( |
| height - 3, 0))); |
| } |
| } |
| |
| @Override |
| public boolean isOpaque() { |
| return false; |
| } |
| |
| @Override |
| public void focusedChanged(Component component, Component obverseComponent) { |
| super.focusedChanged(component, obverseComponent); |
| |
| repaintComponent(); |
| } |
| |
| /** |
| * {@link KeyCode#UP UP} Select the previous spinner item.<br> |
| * {@link KeyCode#DOWN DOWN} Select the next spinner item. |
| */ |
| @Override |
| public boolean keyPressed(Component component, int keyCode, KeyLocation keyLocation) { |
| boolean consumed = false; |
| |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| |
| boolean circular = spinner.isCircular(); |
| int count = spinner.getSpinnerData().getLength(); |
| |
| int selectedIndex = spinner.getSelectedIndex(); |
| int newSelectedIndex = selectedIndex; |
| |
| if (keyCode == KeyCode.UP) { |
| if (selectedIndex < count - 1) { |
| newSelectedIndex++; |
| } else if (circular) { |
| newSelectedIndex = 0; |
| } |
| } else if (keyCode == KeyCode.DOWN) { |
| if (selectedIndex > 0) { |
| newSelectedIndex--; |
| } else if (circular) { |
| newSelectedIndex = count - 1; |
| } |
| } else { |
| consumed = super.keyPressed(component, keyCode, keyLocation); |
| } |
| |
| if (newSelectedIndex != selectedIndex) { |
| spinner.setSelectedIndex(newSelectedIndex); |
| consumed = true; |
| } |
| |
| return consumed; |
| } |
| |
| /** |
| * Select the next spinner item where the first character of the |
| * rendered text matches the typed key (case insensitive). |
| */ |
| @Override |
| public boolean keyTyped(Component component, char character) { |
| boolean consumed = super.keyTyped(component, character); |
| |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| List<?> spinnerData = spinner.getSpinnerData(); |
| Spinner.ItemRenderer itemRenderer = spinner.getItemRenderer(); |
| |
| char characterUpper = Character.toUpperCase(character); |
| |
| for (int i = spinner.getSelectedIndex() + 1, n = spinnerData.getLength(); i < n; i++) { |
| String string = itemRenderer.toString(spinnerData.get(i)); |
| |
| if (string != null && string.length() > 0) { |
| char first = Character.toUpperCase(string.charAt(0)); |
| |
| if (first == characterUpper) { |
| spinner.setSelectedIndex(i); |
| consumed = true; |
| break; |
| } |
| } |
| } |
| |
| return consumed; |
| } |
| } |
| |
| /** |
| * Spinner button. |
| */ |
| protected class SpinButton extends Component { |
| private int direction; |
| private Image buttonImage; |
| |
| public SpinButton(int direction, Image buttonImage) { |
| this.direction = direction; |
| this.buttonImage = buttonImage; |
| |
| setSkin(new SpinButtonSkin()); |
| } |
| |
| public int getDirection() { |
| return direction; |
| } |
| |
| public Image getButtonImage() { |
| return buttonImage; |
| } |
| } |
| |
| /** |
| * Spinner button skin. |
| */ |
| protected class SpinButtonSkin extends ComponentSkin { |
| private boolean highlighted = false; |
| private boolean pressed = false; |
| |
| @Override |
| public int getPreferredWidth(int height) { |
| return BUTTON_IMAGE_SIZE + 6; |
| } |
| |
| @Override |
| public int getPreferredHeight(int width) { |
| return BUTTON_IMAGE_SIZE + 2; |
| } |
| |
| @Override |
| public void layout() { |
| // No-op |
| } |
| |
| @Override |
| public void paint(Graphics2D graphics) { |
| // Apply spinner styles to the button |
| SpinButton spinButton = (SpinButton) getComponent(); |
| |
| int width = getWidth(); |
| int height = getHeight(); |
| |
| // Paint the background |
| float alpha = pressed ? 0.5f : highlighted ? 0.25f : 0.0f; |
| graphics.setPaint(new Color(0, 0, 0, alpha)); |
| graphics.fillRect(0, 0, width, height); |
| |
| // Paint the image |
| SpinButtonImage buttonImage = (SpinButtonImage) spinButton.getButtonImage(); |
| graphics.translate((width - BUTTON_IMAGE_SIZE) / 2, (height - BUTTON_IMAGE_SIZE) / 2); |
| buttonImage.paint(graphics); |
| } |
| |
| @Override |
| public boolean isFocusable() { |
| return false; |
| } |
| |
| @Override |
| public boolean isOpaque() { |
| return false; |
| } |
| |
| @Override |
| public void enabledChanged(Component component) { |
| super.enabledChanged(component); |
| |
| automaticSpinner.stop(); |
| |
| pressed = false; |
| highlighted = false; |
| repaintComponent(); |
| } |
| |
| @Override |
| public void mouseOver(Component component) { |
| super.mouseOver(component); |
| |
| highlighted = true; |
| repaintComponent(); |
| } |
| |
| @Override |
| public void mouseOut(Component component) { |
| super.mouseOut(component); |
| |
| automaticSpinner.stop(); |
| |
| pressed = false; |
| highlighted = false; |
| repaintComponent(); |
| } |
| |
| @Override |
| public boolean mouseDown(Component component, Mouse.Button button, int x, int y) { |
| boolean consumed = super.mouseDown(component, button, x, y); |
| |
| if (button == Mouse.Button.LEFT) { |
| SpinButton spinButton = (SpinButton) getComponent(); |
| Spinner spinner = (Spinner) TerraSpinnerSkin.this.getComponent(); |
| |
| // Start the automatic spinner. It'll be stopped when we |
| // mouse up or mouse out |
| automaticSpinner.start(spinner, spinButton.getDirection()); |
| |
| pressed = true; |
| repaintComponent(); |
| } |
| |
| return consumed; |
| } |
| |
| @Override |
| public boolean mouseUp(Component component, Mouse.Button button, int x, int y) { |
| boolean consumed = super.mouseUp(component, button, x, y); |
| |
| if (button == Mouse.Button.LEFT) { |
| automaticSpinner.stop(); |
| |
| pressed = false; |
| repaintComponent(); |
| } |
| |
| return consumed; |
| } |
| } |
| |
| /** |
| * Abstract base class for button images. |
| */ |
| protected abstract class SpinButtonImage extends Image { |
| @Override |
| public int getWidth() { |
| return BUTTON_IMAGE_SIZE; |
| } |
| |
| @Override |
| public int getHeight() { |
| return BUTTON_IMAGE_SIZE; |
| } |
| |
| @Override |
| public void paint(Graphics2D graphics) { |
| graphics.setStroke(new BasicStroke(0)); |
| graphics.setPaint(buttonColor); |
| } |
| } |
| |
| protected class SpinUpImage extends SpinButtonImage { |
| @Override |
| public void paint(Graphics2D graphics) { |
| super.paint(graphics); |
| |
| int[] xPoints = {0, 2, 4}; |
| int[] yPoints = {3, 1, 3}; |
| graphics.fillPolygon(xPoints, yPoints, 3); |
| graphics.drawPolygon(xPoints, yPoints, 3); |
| } |
| } |
| |
| protected class SpinDownImage extends SpinButtonImage { |
| @Override |
| public void paint(Graphics2D graphics) { |
| super.paint(graphics); |
| |
| int[] xPoints = {0, 2, 4}; |
| int[] yPoints = {1, 3, 1}; |
| graphics.fillPolygon(xPoints, yPoints, 3); |
| graphics.drawPolygon(xPoints, yPoints, 3); |
| } |
| } |
| |
| private SpinnerContent spinnerContent = new SpinnerContent(); |
| private SpinButton upButton = new SpinButton(1, new SpinUpImage()); |
| private SpinButton downButton = new SpinButton(-1, new SpinDownImage()); |
| |
| private Font font; |
| private Color color; |
| private Color disabledColor; |
| private Color borderColor; |
| private Color buttonColor; |
| private Color buttonBackgroundColor; |
| private boolean sizeToContent = false; |
| |
| // Derived colors |
| private Color buttonBevelColor; |
| |
| private static AutomaticSpinner automaticSpinner = new AutomaticSpinner(); |
| |
| public static final int BUTTON_IMAGE_SIZE = 5; |
| |
| public TerraSpinnerSkin() { |
| setColor(1); |
| setBackgroundColor(4); |
| setDisabledColor(7); |
| setBorderColor(7); |
| setButtonColor(1); |
| setButtonBackgroundColor(10); |
| |
| Theme theme = currentTheme(); |
| setFont(theme.getFont()); |
| } |
| |
| @Override |
| public void setSize(int width, int height) { |
| int previousWidth = getWidth(); |
| int previousHeight = getHeight(); |
| |
| super.setSize(width, height); |
| |
| if (previousWidth != width || previousHeight != height) { |
| automaticSpinner.stop(); |
| } |
| } |
| |
| @Override |
| public void install(Component component) { |
| super.install(component); |
| |
| Spinner spinner = (Spinner) component; |
| spinner.getSpinnerListeners().add(this); |
| spinner.getSpinnerSelectionListeners().add(this); |
| |
| spinner.add(spinnerContent); |
| spinner.add(upButton); |
| spinner.add(downButton); |
| } |
| |
| @Override |
| public int getPreferredWidth(int height) { |
| // Preferred width is the sum of our maximum button width plus the |
| // content width, plus the border |
| |
| // Border thickness |
| int preferredWidth = 2; |
| |
| int buttonHeight = (height < 0 ? -1 : height / 2); |
| preferredWidth += Math.max(upButton.getPreferredWidth(buttonHeight), |
| downButton.getPreferredWidth(buttonHeight)); |
| |
| if (height >= 0) { |
| // Subtract border thickness from height constraint |
| height = Math.max(height - 2, 0); |
| } |
| |
| preferredWidth += spinnerContent.getPreferredWidth(height); |
| |
| return preferredWidth; |
| } |
| |
| @Override |
| public int getPreferredHeight(int width) { |
| // Preferred height is the maximum of the button height and the |
| // renderer's preferred height (plus the border), where button |
| // height is defined as the larger of the two buttons' preferred |
| // height, doubled. |
| |
| Dimensions upButtonPreferredSize = upButton.getPreferredSize(); |
| Dimensions downButtonPreferredSize = downButton.getPreferredSize(); |
| |
| int preferredHeight = Math.max(upButtonPreferredSize.height, downButtonPreferredSize.height) * 2; |
| |
| if (width >= 0) { |
| // Subtract the button and border width from width constraint |
| int buttonWidth = Math.max(upButtonPreferredSize.width, downButtonPreferredSize.width); |
| |
| width = Math.max(width - buttonWidth - 2, 0); |
| } |
| |
| preferredHeight = Math.max(preferredHeight, spinnerContent.getPreferredHeight(width)) + 1; |
| |
| return preferredHeight; |
| } |
| |
| @Override |
| public int getBaseline(int width, int height) { |
| Dimensions upButtonPreferredSize = upButton.getPreferredSize(); |
| Dimensions downButtonPreferredSize = downButton.getPreferredSize(); |
| int buttonWidth = Math.max(upButtonPreferredSize.width, downButtonPreferredSize.width); |
| |
| int clientWidth = Math.max(width - buttonWidth - 2, 0); |
| int clientHeight = Math.max(height - 2, 0); |
| |
| int baseline = spinnerContent.getBaseline(clientWidth, clientHeight); |
| |
| if (baseline != -1) { |
| baseline += 1; |
| } |
| |
| return baseline; |
| } |
| |
| @Override |
| public void layout() { |
| int width = getWidth(); |
| int height = getHeight(); |
| |
| int buttonHeight = Math.max((height - 3) / 2, 0); |
| int buttonWidth = Math.max(upButton.getPreferredWidth(buttonHeight), |
| downButton.getPreferredWidth(buttonHeight)); |
| |
| spinnerContent.setSize(Math.max(width - buttonWidth - 3, 0), Math.max(height - 2, 0)); |
| spinnerContent.setLocation(1, 1); |
| |
| upButton.setSize(buttonWidth, buttonHeight); |
| upButton.setLocation(width - buttonWidth - 1, 1); |
| |
| downButton.setSize(buttonWidth, Math.max(height - buttonHeight - 3, 0)); |
| downButton.setLocation(width - buttonWidth - 1, buttonHeight + 2); |
| } |
| |
| @Override |
| public void paint(Graphics2D graphics) { |
| super.paint(graphics); |
| |
| int width = getWidth(); |
| int height = getHeight(); |
| |
| int buttonX = upButton.getX(); |
| int buttonWidth = upButton.getWidth(); |
| int buttonHeight = upButton.getHeight(); |
| |
| if (!themeIsFlat()) { |
| graphics.setPaint(new GradientPaint(buttonX + buttonWidth / 2, 0, buttonBevelColor, buttonX |
| + buttonWidth / 2, buttonHeight, buttonBackgroundColor)); |
| graphics.fillRect(buttonX, 0, buttonWidth, height); |
| |
| graphics.setPaint(borderColor); |
| GraphicsUtilities.drawRect(graphics, 0, 0, width, height); |
| GraphicsUtilities.drawLine(graphics, width - buttonWidth - 2, 0, height, |
| Orientation.VERTICAL); |
| GraphicsUtilities.drawLine(graphics, width - buttonWidth - 2, buttonHeight + 1, |
| buttonWidth + 1, Orientation.HORIZONTAL); |
| } else { |
| graphics.setPaint(buttonBackgroundColor); |
| graphics.fillRect(buttonX, 0, width, height); |
| } |
| } |
| |
| @Override |
| public void enabledChanged(Component component) { |
| super.enabledChanged(component); |
| repaintComponent(); |
| } |
| |
| @Override |
| public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) { |
| spinnerContent.requestFocus(); |
| return false; |
| } |
| |
| protected void invalidateContent() { |
| spinnerContent.invalidate(); |
| spinnerContent.repaint(); |
| } |
| |
| public Color getColor() { |
| return color; |
| } |
| |
| public void setColor(Color color) { |
| Utils.checkNull(color, "color"); |
| |
| this.color = color; |
| repaintComponent(); |
| } |
| |
| public final void setColor(String color) { |
| setColor(GraphicsUtilities.decodeColor(color, "color")); |
| } |
| |
| public final void setColor(int color) { |
| Theme theme = currentTheme(); |
| setColor(theme.getColor(color)); |
| } |
| |
| public Color getDisabledColor() { |
| return disabledColor; |
| } |
| |
| public void setDisabledColor(Color disabledColor) { |
| Utils.checkNull(disabledColor, "disabledColor"); |
| |
| this.disabledColor = disabledColor; |
| repaintComponent(); |
| } |
| |
| public final void setDisabledColor(String disabledColor) { |
| setDisabledColor(GraphicsUtilities.decodeColor(disabledColor, "disabledColor")); |
| } |
| |
| public final void setDisabledColor(int disabledColor) { |
| Theme theme = currentTheme(); |
| setDisabledColor(theme.getColor(disabledColor)); |
| } |
| |
| public Color getBorderColor() { |
| return borderColor; |
| } |
| |
| public void setBorderColor(Color borderColor) { |
| Utils.checkNull(borderColor, "borderColor"); |
| |
| this.borderColor = borderColor; |
| repaintComponent(); |
| } |
| |
| public final void setBorderColor(String borderColor) { |
| setBorderColor(GraphicsUtilities.decodeColor(borderColor, "borderColor")); |
| } |
| |
| public final void setBorderColor(int borderColor) { |
| Theme theme = currentTheme(); |
| setBorderColor(theme.getColor(borderColor)); |
| } |
| |
| public Color getButtonColor() { |
| return buttonColor; |
| } |
| |
| public void setButtonColor(Color buttonColor) { |
| // TODO: is null acceptable here? |
| this.buttonColor = buttonColor; |
| repaintComponent(); |
| } |
| |
| public final void setButtonColor(String buttonColor) { |
| setButtonColor(GraphicsUtilities.decodeColor(buttonColor, "buttonColor")); |
| } |
| |
| public final void setButtonColor(int buttonColor) { |
| Theme theme = currentTheme(); |
| setButtonColor(theme.getColor(buttonColor)); |
| } |
| |
| public Color getButtonBackgroundColor() { |
| return buttonBackgroundColor; |
| } |
| |
| public void setButtonBackgroundColor(Color buttonBackgroundColor) { |
| // TODO: not sure if null is acceptable here (certainly if theme is flat) |
| this.buttonBackgroundColor = buttonBackgroundColor; |
| this.buttonBevelColor = TerraTheme.brighten(buttonBackgroundColor); |
| repaintComponent(); |
| } |
| |
| public final void setButtonBackgroundColor(String buttonBackgroundColor) { |
| setButtonBackgroundColor(GraphicsUtilities.decodeColor(buttonBackgroundColor, "buttonBackgroundColor")); |
| } |
| |
| public final void setButtonBackgroundColor(int buttonBackgroundColor) { |
| Theme theme = currentTheme(); |
| setButtonBackgroundColor(theme.getColor(buttonBackgroundColor)); |
| } |
| |
| public Font getFont() { |
| return font; |
| } |
| |
| public void setFont(Font font) { |
| Utils.checkNull(font, "font"); |
| |
| this.font = font; |
| invalidateContent(); |
| } |
| |
| public final void setFont(String font) { |
| setFont(decodeFont(font)); |
| } |
| |
| public final void setFont(Dictionary<String, ?> font) { |
| setFont(Theme.deriveFont(font)); |
| } |
| |
| public boolean isSizeToContent() { |
| return sizeToContent; |
| } |
| |
| public void setSizeToContent(boolean sizeToContent) { |
| this.sizeToContent = sizeToContent; |
| invalidateContent(); |
| } |
| |
| // Spinner.Skin methods |
| |
| @Override |
| public Bounds getContentBounds() { |
| return spinnerContent.getBounds(); |
| } |
| |
| // SpinnerListener methods |
| |
| @Override |
| public void spinnerDataChanged(Spinner spinner, List<?> previousSpinnerData) { |
| invalidateContent(); |
| } |
| |
| @Override |
| public void itemRendererChanged(Spinner spinner, Spinner.ItemRenderer previousItemRenderer) { |
| invalidateContent(); |
| } |
| |
| @Override |
| public void circularChanged(Spinner spinner) { |
| // No-op |
| } |
| |
| // SpinnerSelectionListener methods |
| @Override |
| public void selectedIndexChanged(Spinner spinner, int previousSelectedIndex) { |
| // No-op |
| } |
| |
| @Override |
| public void selectedItemChanged(Spinner spinner, Object previousSelectedItem) { |
| invalidateContent(); |
| } |
| } |