Mercurial > hg > release > thermostat-2.0
changeset 2587:cabc8dcc4b08
More tab look and feel tweaks
review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-February/022135.html
reviewed-by: almac
author | Mario Torre <neugens.limasoftware@gmail.com> |
---|---|
date | Thu, 09 Feb 2017 15:16:53 +0100 |
parents | 2f3899d0dd36 |
children | ac0f70abdcb1 |
files | client/swing/src/main/java/com/redhat/thermostat/client/swing/components/CleanTabUI.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTabbedPane.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ThermostatTabbedPaneDemo.java |
diffstat | 4 files changed, 219 insertions(+), 80 deletions(-) [+] |
line wrap: on
line diff
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/CleanTabUI.java Wed Feb 08 21:02:33 2017 +0100 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/CleanTabUI.java Thu Feb 09 15:16:53 2017 +0100 @@ -36,24 +36,32 @@ package com.redhat.thermostat.client.swing.components; +import java.awt.Color; +import java.awt.GradientPaint; import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Insets; +import java.awt.Paint; import java.awt.Rectangle; -import java.lang.reflect.Field; +import java.awt.geom.AffineTransform; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.SwingConstants; +import javax.swing.UIManager; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicTabbedPaneUI; -import com.redhat.thermostat.client.swing.IconResource; +import com.redhat.thermostat.client.swing.GraphicsUtils; +import com.redhat.thermostat.client.swing.UIDefaults; +import com.redhat.thermostat.client.swing.internal.vmlist.UIDefaultsImpl; import com.redhat.thermostat.client.ui.Palette; class CleanTabUI extends BasicTabbedPaneUI { private Insets cleantabInsets; - + private UIDefaults uiDefaults = UIDefaultsImpl.getInstance(); + @SuppressWarnings("serial") private class ArrowButton extends ActionButton implements UIResource, SwingConstants { @@ -68,7 +76,7 @@ } public CleanTabUI() { - cleantabInsets = new Insets(5, 10, 2, 10); + cleantabInsets = new Insets(5, 10, 5, 10); } @Override @@ -76,86 +84,137 @@ super.installUI(c); tabPane.setOpaque(true); } - + + @Override + protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) { + return 0; + } + @Override protected void installDefaults() { + UIManager.getDefaults().put("TabbedPane.tabsOverlapBorder", true); + UIManager.getDefaults().put("TabbedPane.contentAreaColor", uiDefaults.getComponentBGColor()); + UIManager.getDefaults().put("TabbedPane.shadow", Palette.GRAY.getColor()); + super.installDefaults(); - lightHighlight = Palette.EARL_GRAY.getColor(); - contentBorderInsets = new Insets(1, 1, 1, 1); - setTabsOverlap(); + lightHighlight = Palette.GRAY.getColor(); + + contentBorderInsets = new Insets(1, 0, 0, 0); + selectedTabPadInsets = new Insets(0, 0, 0, 0); + tabAreaInsets = new Insets(1, 0, 1, 0); + tabInsets = cleantabInsets; } - - private void setTabsOverlap() { - try { - Field tabsOverlapBorderField = getClass().getSuperclass().getDeclaredField("tabsOverlapBorder"); - tabsOverlapBorderField.setAccessible(true); - tabsOverlapBorderField.set(this, true); - - } catch (IllegalArgumentException | IllegalAccessException | - NoSuchFieldException | SecurityException ignore) {} - } - + @Override public void paint(Graphics g, JComponent c) { - lightHighlight = Palette.EARL_GRAY.getColor(); + lightHighlight = Palette.GRAY.getColor(); + + g.setColor((Color) uiDefaults.getComponentBGColor()); + g.fillRect(0, 0, tabPane.getWidth(), tabPane.getHeight()); + + g.setColor(lightHighlight); super.paint(g, c); + + if (tabPane.getTabPlacement() == TOP) { + g.setColor(Palette.DARK_GRAY.getColor()); + g.drawLine(0, 0, tabPane.getWidth(), 0); + g.setColor(Palette.GRAY.getColor()); + g.drawLine(0, 1, tabPane.getWidth(), 1); + } } - + @Override protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int width, int height, boolean isSelected) { - if (!isSelected) { - // TODO: implement for all orientations - g.setColor(Palette.PALE_GRAY.getColor().darker()); - g.drawRect(x, y, width, height); + g.setColor(Palette.DARK_GRAY.getColor()); + + if (tabIndex > 0) { + g.drawLine(x, y, x, y + height - 1); + } - g.setColor(lightHighlight); - g.drawLine(x, y + height, x + width + 1, y + height); - - } else { - g.setColor(lightHighlight); - g.drawRect(x, y, width, height - 2); - - g.setColor(Palette.GRANITA_ORANGE.getColor()); - g.fillRect(x, y, width + 1, y + 1); - - g.setColor(Palette.LIGHT_GRAY.getColor()); - g.drawLine(x + 1, y + height - 2, x + width - 1, y + height - 2); + if (tabIndex == tabPane.getTabCount() - 1) { + g.drawLine(x + width, y, x + width, y + height - 1); + } + + if (isSelected && tabPlacement == TOP) { + g.setColor((Color) uiDefaults.getComponentBGColor()); + g.drawLine(x + (tabIndex > 0 ? 1 : 0), y - 1, x + width - 1, y - 1); } } protected JButton createScrollButton(int direction) { - IconResource resource = IconResource.ARROW_LEFT; + FontAwesomeIcon resource = null; switch (direction) { case EAST: case NORTH: - resource = IconResource.ARROW_RIGHT; + resource = new FontAwesomeIcon('\uf105', 20, uiDefaults.getSelectedComponentBGColor()); break; case WEST: case SOUTH: default: - resource = IconResource.ARROW_LEFT; + resource = new FontAwesomeIcon('\uf104', 20, uiDefaults.getSelectedComponentBGColor()); break; } - return new ArrowButton(resource.getIcon()); + return new ArrowButton(resource); + } + + private void paintTabAreaTopInset(Graphics2D graphics2D) { + if (tabPane.getTabPlacement() == TOP) { + graphics2D.setColor(Palette.DARK_GRAY.getColor()); + graphics2D.drawLine(0, 0, tabPane.getWidth(), 0); + + graphics2D.setColor(Palette.GRAY.getColor()); + graphics2D.drawLine(0, 1, tabPane.getWidth(), 1); + } + } + + private void paintTabAreaBottomInset(Graphics2D graphics2D) { + if (tabPane.getTabPlacement() == TOP) { + graphics2D.setColor(Palette.DARK_GRAY.getColor()); + Rectangle tabBounds = rects[0].getBounds(); + int h = tabBounds.height + tabAreaInsets.bottom; + graphics2D.drawLine(tabPane.getX(), h, tabPane.getWidth(), h); + } } - + + @Override + protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) { + + Graphics2D graphics2D = (Graphics2D) g; + + graphics2D.setColor((Color) uiDefaults.getComponentBGColor()); + graphics2D.fillRect(0, 0, tabPane.getWidth(), tabPane.getHeight()); + + // this is a bit weird, we need to do it twice with and without the + // affine transform because the caller sometime shift the content + // depending if the scroll buttons are visible or not but unfortunately + // we can't access this information + paintTabAreaTopInset(graphics2D); + AffineTransform transform = graphics2D.getTransform(); + graphics2D.setTransform(new AffineTransform()); + paintTabAreaTopInset(graphics2D); + + graphics2D.setTransform(transform); + super.paintTabArea(g, tabPlacement, selectedIndex); + + paintTabAreaBottomInset(graphics2D); + transform = graphics2D.getTransform(); + graphics2D.setTransform(new AffineTransform()); + paintTabAreaBottomInset(graphics2D); + graphics2D.setTransform(transform); + } + @Override protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { - g.setColor(lightHighlight); - if (tabPlacement != BOTTOM) { - g.drawLine(x, y + h - 1, x + w, y + h - 1); - } else { - // TODO - } + // no border } @Override @@ -163,12 +222,7 @@ int selectedIndex, int x, int y, int w, int h) { - g.setColor(lightHighlight); - if (tabPlacement != LEFT) { - g.drawLine(x, y, x, y + h - 1); - } else { - // TODO - } + // no border } @Override @@ -176,12 +230,7 @@ int selectedIndex, int x, int y, int w, int h) { - g.setColor(lightHighlight); - if (tabPlacement != RIGHT) { - g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); - } else { - // TODO - } + // no border } @Override @@ -189,32 +238,28 @@ int selectedIndex, int x, int y, int w, int h) { - Rectangle bounds = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect); - - g.setColor(lightHighlight); - if (tabPlacement != TOP || bounds == null) { - g.drawLine(x, y, x + w - 1, y); + g.setColor(Palette.DARK_GRAY.getColor()); + g.drawLine(x, y, x + w, y); + } - } else { - g.drawLine(x, y, bounds.x, y); - g.drawLine(bounds.x + bounds.width, y, x + w - 1, y); - - g.setColor(Palette.LIGHT_GRAY.getColor()); - g.drawLine(bounds.x + 1, y, bounds.x + bounds.width - 1, y); - } - } - @Override protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int width, int height, boolean isSelected) { - g.setColor(Palette.LIGHT_GRAY.getColor()); - int delta = 2; - if (!isSelected) { - delta = 1; + GraphicsUtils utils = GraphicsUtils.getInstance(); + Graphics2D graphics = utils.createAAGraphics(g); + if (isSelected) { + Paint gradient = new GradientPaint(x, y, (Color) uiDefaults.getComponentBGColor(), + x, height, Palette.GRAY.getColor()); + graphics.setPaint(gradient); + + } else { + graphics.setColor(Palette.GRAY.getColor()); } - g.fillRect(x, y + 1, width, height - delta); + + graphics.fillRect(x, y, width, height); + graphics.dispose(); } @Override
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java Wed Feb 08 21:02:33 2017 +0100 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java Thu Feb 09 15:16:53 2017 +0100 @@ -59,6 +59,7 @@ import javax.swing.SwingUtilities; import com.redhat.thermostat.client.swing.internal.LocaleResources; +import com.redhat.thermostat.client.swing.internal.vmlist.UIDefaultsImpl; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; @@ -104,7 +105,7 @@ setName(HeaderPanel.class.getName()); headerLabel = new ShadowLabel(header, new EmptyIcon(5, 5)); - headerPanel = new GradientPanel(Color.WHITE, getBackground()); + headerPanel = new GradientPanel(Color.WHITE, UIDefaultsImpl.getInstance().getComponentBGColor()); headerPanel.setName("clickableArea"); headerPanel.setPreferredSize(new Dimension(HeaderPanel.this.getWidth(), 40));
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTabbedPane.java Wed Feb 08 21:02:33 2017 +0100 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTabbedPane.java Thu Feb 09 15:16:53 2017 +0100 @@ -45,6 +45,7 @@ public class ThermostatTabbedPane extends JTabbedPane { public ThermostatTabbedPane() { + super(TOP, SCROLL_TAB_LAYOUT); setUI(new CleanTabUI()); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ThermostatTabbedPaneDemo.java Thu Feb 09 15:16:53 2017 +0100 @@ -0,0 +1,92 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.components; + +import com.redhat.thermostat.shared.locale.LocalizedString; + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; + +/** + */ +public class ThermostatTabbedPaneDemo { + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setMinimumSize(new Dimension(500, 500)); + + HeaderPanel header = new HeaderPanel(new LocalizedString("A Simple Tab Demo")); + frame.setContentPane(header); + + ThermostatTabbedPane tabs = new ThermostatTabbedPane(); + tabs.addTab("Content #1", createContent("Some Content")); + tabs.addTab("Content #2", createContent("Some Other Content")); + tabs.addTab("Content #3", createContent("Some More Content Longer")); + tabs.addTab("Content #4", createContent("Some More Content Even Longer")); + tabs.addTab("Content #5", createContent("Some More Content Very Very Long!!!")); + tabs.addTab("Content #6", createContent("Some More Content The Longest One!!!!!!!!")); + + header.setContent(tabs); + + frame.setVisible(true); + } + }); + } + + private static Component createContent(String text) { + JPanel panel = new JPanel(); + panel.setBackground(Color.WHITE); + + panel.setLayout(new BorderLayout()); + JLabel content = new JLabel(text); + content.setHorizontalAlignment(SwingConstants.CENTER); + + panel.add(content); + + return panel; + } +} \ No newline at end of file