Mercurial > hg > release > thermostat-1.6
view client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapBreadcrumb.java @ 2049:a92d602216ad
Update copyright license headers for 2017
PR3290
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-January/021974.html
author | Andrew Azores <aazores@redhat.com> |
---|---|
date | Tue, 17 Jan 2017 12:19:56 -0500 |
parents | 5a3e91f53ee3 |
children |
line wrap: on
line source
/* * 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.experimental; import java.awt.Font; import java.awt.Image; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.FontRenderContext; import java.util.LinkedList; import java.util.Objects; import java.util.Stack; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.UIManager; import com.redhat.thermostat.client.swing.components.Icon; /** * This object creates a breadcrumb navigation bar used to trace * {@link TreeMapComponent} objects' state. */ public class TreeMapBreadcrumb extends JComponent implements TreeMapObserver { private static final long serialVersionUID = 1L; /** * Font used by breadcrumb items. */ private Font FONT = (Font) UIManager.get("thermostat-default-font"); /** * Stack containing all items part of the breadcrumb. */ private Stack<BreadcrumbItem> items; /** * The TreeMap object to interact with. */ private TreeMapComponent treemap; /** * Constructor. Creates a breadcumbs navigation bar with the starting * element and register itself as observer to the given treemap. * * @param start the treemap's root. */ public TreeMapBreadcrumb(TreeMapComponent treemap, TreeMapNode start) { super(); setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); this.items = new Stack<>(); this.treemap = Objects.requireNonNull(treemap); this.treemap.register(this); buildBreadcrumb(start); } /** * Builds the breadcrumb using the nodes'ancestors. * @param node the tree's branch to represent ad breadcrumb bar. */ public void buildBreadcrumb(TreeMapNode node) { LinkedList<TreeMapNode> nodes = node.getAncestors(); while (!nodes.isEmpty()) { BreadcrumbItem item = new BreadcrumbItem(nodes.removeLast()); items.push(item); add(item); } // the first element has no tail items.get(0).setAsFirst(); //the last element has no head items.peek().setAsLast(); } @Override public void notifySelection(TreeMapNode node) { // do nothing } @Override public void notifyZoomIn(TreeMapNode node) { items.clear(); removeAll(); buildBreadcrumb(node); } @Override public void notifyZoomOut() { this.remove(items.pop()); items.peek().setAsLast(); items.peek().repaint(); } @Override public void notifyZoomFull() { items.clear(); this.removeAll(); BreadcrumbItem item = new BreadcrumbItem(treemap.getTreeMapRoot()); item.setAsFirst(); item.setAsLast(); items.push(item); this.add(item); } /** * Package-private for testing only. * @return the number of BreadcrumbItems in the items stack */ int getItemCount() { return items.size(); } /** * This class allows to create a single item in a breadcrumb object. * This component has 3 {@link JLabel}s which contain the images needed * to draw an arrow. * _____ * > |_____| > * | | | * tail body head * */ class BreadcrumbItem extends JComponent { private static final long serialVersionUID = 1L; private final String ROOT_TEXT = "root"; private JLabel tail; private JLabel body; private JLabel head; /** * The node this items represents. */ private TreeMapNode node; /** * The constructor creates a complete item, including both tail and head * @param node */ public BreadcrumbItem(final TreeMapNode node) { super(); this.node = node; this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); initComponent(); /** * Simulate the click effect increasing and reducing the font size */ this.addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent arg0) { increaseFont(body, 2); } @Override public void mousePressed(MouseEvent arg0) { increaseFont(body, -2); } @Override public void mouseClicked(MouseEvent arg0) { treemap.zoomIn(node); } }); } /** * Increases the given component's font size. * @param comp the component which edit the font size to. * @param increment value of the increment. Negative values reduce the * font size. */ private void increaseFont(JComponent comp, int increment) { Font f = comp.getFont(); int newSize = f.getSize() + increment; f = new Font(f.getName(), f.getStyle(), newSize); comp.setFont(f); comp.repaint(); } private void initComponent() { initTail(); initBody(); initHead(); } private void initTail() { tail = new JLabel(); tail.setIcon(new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_TAIL))); this.add(tail); } private void initHead() { head = new JLabel(); head.setIcon(new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_HEAD))); this.add(head); } private void initBody() { body = new JLabel(); body.setFont(FONT); body.setHorizontalTextPosition(JLabel.CENTER); body.setText(node.getLabel()); adaptIcon(body, new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_BODY))); this.add(body); } public TreeMapNode getNode() { return this.node; } /** * Remove the tail of his breadcrumb item. */ public void setAsFirst() { this.remove(tail); this.tail = null; this.body.setText(ROOT_TEXT); adaptIcon(body, new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_BODY))); } /** * Remove the head of his breadcrumb item. */ public void setAsLast() { this.remove(head); this.head = null; } /** * Sets the text of this item, which is placed in the body. * @param text */ public void setText(String text) { body.setText(text); } public int getHeight() { return body.getPreferredSize().height; } } /** * Calculates the labels' text size in order to scale the given image * and to apply to it. * * Package-private for testing only. */ void adaptIcon(JLabel label, ImageIcon icon) { Rectangle fontArea; try { fontArea = label.getFont().getStringBounds(label.getText(), new FontRenderContext(label.getFont().getTransform(), false, false)).getBounds(); } catch (NullPointerException npe) { fontArea = label.getBounds(); } Image img = icon.getImage(); Image newimg = img.getScaledInstance(fontArea.getBounds().width + 10, img.getHeight(null), java.awt.Image.SCALE_SMOOTH); icon = new ImageIcon(newimg); label.setIcon(icon); } }