/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program 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 * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.look; import java.awt.Color; import java.awt.Component; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.RoundRectangle2D; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JProgressBar; import javax.swing.JToolBar; import javax.swing.plaf.ColorUIResource; import javax.swing.table.JTableHeader; import com.rapidminer.gui.look.painters.CachedPainter; import com.vlsolutions.swing.toolbars.VLToolBar; /** * Some tool methods in regards to the Look and Feel of the UI. * * @author Ingo Mierswa, Marco Boeck */ public final class RapidLookTools { private static boolean vlDockingAvailable = true; /** * The client property of a {@link JProgressBar} if the text should not appear below it but * instead the progress bar should have full height and the text should appear in front of it. * Expected type: {@link Boolean} * * @since 7.0.0 */ public static final String PROPERTY_PROGRESSBAR_COMPRESSED = "progressbar_compressed"; /** * The client property of a {@link JTableHeader} if the background should not be the default * background color. Expected type: {@link ColorUIResource} * * @since 7.0.0 */ public static final String PROPERTY_TABLE_HEADER_BACKGROUND = "table_header_bg"; /** * The client property of a few {@link JComponent}s (currently supported by: {@link JComboBox}) * which take input and should not be displayed in a bright theme but rather in a dark theme. * Expected type: {@link Boolean} * * @since 7.0.0 */ public static final String PROPERTY_INPUT_BACKGROUND_DARK = "input_dark_bg"; static { try { VLToolBar.class.getName(); } catch (NoClassDefFoundError e) { vlDockingAvailable = false; } } public static void clearMenuCache() { CachedPainter.clearMenuCache(); } public static void drawMenuItemBackground(Graphics g, JMenuItem menuItem) { Color oldColor = g.getColor(); ButtonModel model = menuItem.getModel(); int w = menuItem.getWidth(); int h = menuItem.getHeight(); if (model.isArmed() || model.isSelected() && menuItem instanceof JMenu) { g.setColor(Colors.MENU_ITEM_BACKGROUND_SELECTED); g.fillRect(0, 0, w, h); } else if (!(menuItem instanceof JMenu && ((JMenu) menuItem).isTopLevelMenu())) { drawMenuItemFading(menuItem, g); } g.setColor(oldColor); } public static boolean drawMenuItemFading(Component c, Graphics g) { int w = c.getWidth(); int h = c.getHeight(); if (h < 0 || w < 0) { return true; } g.setColor(Colors.MENU_ITEM_BACKGROUND); g.fillRect(0, 0, c.getWidth(), c.getHeight()); return true; } public static boolean isToolbarButton(JComponent b) { return b.getParent() instanceof JToolBar || vlDockingAvailable && isVLToolbarButton(b); } public static boolean isVLToolbarButton(JComponent b) { return b.getParent() instanceof VLToolBar; } /** * Drasw a button in a toolbar. * * @param b * the button * @param g * the graphics instance */ public static void drawToolbarButton(Graphics g, AbstractButton b) { if (!b.isEnabled()) { return; } if (b.getModel().isSelected() && b.isRolloverEnabled() || b.getModel().isPressed() && b.getModel().isArmed() && b.isRolloverEnabled()) { if (b.isContentAreaFilled()) { drawButton(b, g, createShapeForButton(b)); } if (b.isBorderPainted()) { drawButtonBorder(b, g, createBorderShapeForButton(b)); } } else if (b.getModel().isRollover() && b.isRolloverEnabled()) { if (b.isBorderPainted()) { drawButtonBorder(b, g, createBorderShapeForButton(b)); } } } public static boolean isLeftToRight(Component c) { return c.getComponentOrientation().isLeftToRight(); } public static Colors getColors() { return RapidLookAndFeel.getColors(); } /** * Creates the default {@link Shape} for the given button. * * @param b * the button to create the shape for * @return the shape instance */ public static Shape createShapeForButton(AbstractButton b) { int w = b.getWidth(); int h = b.getHeight(); return new RoundRectangle2D.Double(1, 1, w - 2, h - 2, RapidLookAndFeel.CORNER_DEFAULT_RADIUS, RapidLookAndFeel.CORNER_DEFAULT_RADIUS); } /** * Creates the border {@link Shape} for the given button. * * @param b * the button to create the border shape for * @return the border shape instance */ public static Shape createBorderShapeForButton(AbstractButton b) { int w = b.getWidth(); int h = b.getHeight(); return new RoundRectangle2D.Double(0, 0, w - 1, h - 1, RapidLookAndFeel.CORNER_DEFAULT_RADIUS, RapidLookAndFeel.CORNER_DEFAULT_RADIUS); } /** * Draws the given button border with the specified shape. * * @param b * @param g * @param shape */ public static void drawButtonBorder(AbstractButton b, Graphics g, Shape shape) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (b.isEnabled()) { if (b.hasFocus()) { g2.setColor(Colors.BUTTON_BORDER_FOCUS); } else { g2.setColor(Colors.BUTTON_BORDER); } } else { g2.setColor(Colors.BUTTON_BORDER_DISABLED); } g2.draw(shape); } /** * Draws the given button with the specified shape. * * @param b * @param g * @param shape */ public static void drawButton(AbstractButton b, Graphics g, Shape shape) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int h = (int) shape.getBounds().getHeight(); if (b.isEnabled()) { if (b.getModel().isPressed() || b.getModel().isSelected()) { Paint gp = new GradientPaint(0, 0, Colors.BUTTON_BACKGROUND_PRESSED_GRADIENT_START, 0, h, Colors.BUTTON_BACKGROUND_PRESSED_GRADIENT_END); g2.setPaint(gp); } else if (b.getModel().isRollover()) { Paint gp = new GradientPaint(0, 0, Colors.BUTTON_BACKGROUND_ROLLOVER_GRADIENT_START, 0, h, Colors.BUTTON_BACKGROUND_ROLLOVER_GRADIENT_END); g2.setPaint(gp); } else { Paint gp = new GradientPaint(0, 0, Colors.BUTTON_BACKGROUND_GRADIENT_START, 0, h, Colors.BUTTON_BACKGROUND_GRADIENT_END); g2.setPaint(gp); } } else { Paint gp = new GradientPaint(0, 0, Colors.BUTTON_BACKGROUND_DISABLED_GRADIENT_START, 0, h, Colors.BUTTON_BACKGROUND_DISABLED_GRADIENT_END); g2.setPaint(gp); } g2.fill(shape); } }