/* * Copyright 2004-2010 Information & Software Engineering Group (188/1) * Institute of Software Technology and Interactive Systems * Vienna University of Technology, Austria * * Licensed 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.ifs.tuwien.ac.at/dm/somtoolbox/license.html * * 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 at.tuwien.ifs.somtoolbox.apps.viewer.controls; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import javax.swing.JComponent; import javax.swing.SwingConstants; import at.tuwien.ifs.somtoolbox.visualization.Palette; /** * Component to display a Palette. <br> * Nice-to-have features: * <ul> * <li>scaling (just showing some part of the palette)</li> * </ul> * * @author Rudolf Mayer * @author Jakob Frank * @version $Id: PaletteDisplayer.java 3587 2010-05-21 10:35:33Z mayer $ */ public class PaletteDisplayer extends JComponent { private static final long serialVersionUID = 1L; private static final int MIN_PALETTE_WIDTH = 35; private Palette palette; private boolean showScale; private boolean autoOrientation; private int orientation; private Font font; private boolean showPercent; public boolean getShowPercent() { return showPercent; } public void setShowPercent(boolean showPercent) { this.showPercent = showPercent; revalidate(); repaint(); } private double minValue = 0, maxValue = 100; /** * Create a new PaletteDisplayer. */ public PaletteDisplayer() { super(); palette = null; showScale = true; showPercent = true; autoOrientation = true; font = new Font("Monospaced", Font.PLAIN, 9); orientation = SwingConstants.HORIZONTAL; } /** * Create a new PaletteDisplayer, displaying the given Palette. * * @param palette the Palette to display. */ public PaletteDisplayer(Palette palette) { this(); this.palette = palette; } @Override protected void paintComponent(Graphics g) { if (isAutoOrientation()) { if (getWidth() < getHeight()) { setOrientation(SwingConstants.VERTICAL); } if (getWidth() > getHeight()) { setOrientation(SwingConstants.HORIZONTAL); } } if (isOpaque()) { // paint background g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); } if (palette != null) { Graphics2D g2d = (Graphics2D) g.create(); Insets insets = getInsets(); int scaleHeight = 0; int scaleWidth = 0; double max = 100d; double min = 0d; if (!showPercent) { max = maxValue; min = minValue; } if (orientation == SwingConstants.HORIZONTAL) { // Write the scale if (isShowScale()) { g2d.setColor(Color.BLACK); g2d.setFont(font); FontMetrics metrics = g2d.getFontMetrics(font); scaleHeight = metrics.getHeight() + 2; scaleWidth = metrics.stringWidth(Math.round(max) + (showPercent ? " %" : " ")); // System.out.println("Font: " + scaleWidth + "x" + scaleHeight); int werte = (getWidth() - insets.left - insets.right) / (scaleWidth * 3); double step = (max - min) / werte; for (int i = 0; i <= werte; i++) { String text = Math.round(min + i * step) + (showPercent ? "%" : ""); int x = insets.left + scaleWidth / 2 - metrics.stringWidth(text) / 2 + (int) Math.round((getWidth() - insets.left - insets.right - scaleWidth) * i * step / (max - min)); int y = getHeight() - insets.bottom - metrics.getDescent(); g2d.drawString(text, x, y); } } int xStart = insets.left + scaleWidth / 2; int xEnd = getWidth() - insets.right - scaleWidth / 2; int paletteHeight = getHeight() - insets.top - insets.bottom - scaleHeight; Color[] colors = getPalette().getColors(); float step = (float) (xEnd - xStart) / (float) colors.length; for (int i = 0; i < colors.length; i++) { g2d.setColor(colors[i]); g2d.fillRect(xStart + Math.round(step * i), insets.top, Math.round(step + 1), paletteHeight); } } else { // VERTICAL // Write the scale if (isShowScale()) { g2d.setColor(Color.BLACK); g2d.setFont(font); FontMetrics metrics = g2d.getFontMetrics(font); scaleHeight = metrics.getHeight(); scaleWidth = metrics.stringWidth(Math.round(max) + (showPercent ? " %" : " ")) + 2; int werte = (getHeight() - insets.top - insets.bottom) / (scaleHeight * 4); double step = (max - min) / werte; for (int i = 0; i <= werte; i++) { String text = Math.round(min + i * step) + (showPercent ? "% " : " "); int x = insets.left + scaleWidth - metrics.stringWidth(text); int y = getHeight() - insets.bottom - (int) Math.round((getHeight() - insets.top - insets.bottom - scaleHeight) * i * step / (max - min)); g2d.drawString(text, x, y); } } int yStart = insets.top + scaleHeight / 2; int yEnd = getHeight() - insets.top - scaleHeight / 2; int paletteWidth = getWidth() - insets.left - insets.right - scaleWidth; Color[] colors = getPalette().getColors(); float step = (float) (yEnd - yStart) / (float) colors.length; for (int i = 0; i < colors.length; i++) { g2d.setColor(colors[i]); g2d.fillRect(insets.left + scaleWidth, yEnd - Math.round(step * (i + 1)), paletteWidth, Math.round(step + 1)); } } g2d.dispose(); } } /** * Returns wheter the Components orientation is automatically adjusted. Default is <c>true</c> * * @return Returns the autoOrientation. */ public boolean isAutoOrientation() { return autoOrientation; } /** * Sets wheter the components orientation should be automatically adjusted. * * @param autoOrientation The autoOrientation to set. */ public void setAutoOrientation(boolean autoOrientation) { this.autoOrientation = autoOrientation; } /** * Returns the font used for the scale. * * @return Returns the font. */ @Override public Font getFont() { return font; } /** * Sets the Font used for the scale. * * @param font The font to set. */ @Override public void setFont(Font font) { this.font = font; } /** * Returns the components orientation. Default is {@link SwingConstants#HORIZONTAL} * * @return Returns the orientation. * @see #getOrientation() */ public int getOrientation() { return orientation; } /** * Set the Orientation. This can either be {@link SwingConstants#HORIZONTAL} or {@link SwingConstants#VERTICAL} * * @param orientation The orientation to set. * @see SwingConstants */ public void setOrientation(int orientation) { if (orientation == SwingConstants.HORIZONTAL || orientation == SwingConstants.VERTICAL) { this.orientation = orientation; } } /** * Get the palette that is displayed. * * @return Returns the palette. */ public Palette getPalette() { return palette; } /** * Set the palette to display. * * @param palette The palette to set. */ public void setPalette(Palette palette) { this.palette = palette; revalidate(); repaint(); } /** * Determines whether a scale is shown or not. Default is <c>true<c>. * * @return Returns the showScale. */ public boolean isShowScale() { return showScale; } /** * Set to <c>true</c> if a scale should be shown. * * @param showScale The showScale to set. */ public void setShowScale(boolean showScale) { this.showScale = showScale; } @Override public Dimension getMinimumSize() { Dimension s = super.getMinimumSize(); if (s == null) { s = new Dimension(0, 0); } int h = 0, w = 0; Insets insets = getInsets(); h = insets.top + insets.bottom + MIN_PALETTE_WIDTH; w = insets.left + insets.right + MIN_PALETTE_WIDTH; if (h > s.height) { s.height = h; } if (w > s.width) { s.width = w; } return new Dimension(w > s.width ? w : s.width, h > s.height ? h : s.height); } @Override public Dimension getPreferredSize() { Dimension s = super.getPreferredSize(); if (s == null) { s = new Dimension(0, 0); } int h = 0, w = 0; Insets insets = getInsets(); h = insets.top + insets.bottom + MIN_PALETTE_WIDTH; w = insets.left + insets.right + MIN_PALETTE_WIDTH; if (h > s.height) { s.height = h; } if (w > s.width) { s.width = w; } return new Dimension(w > s.width ? w : s.width, h > s.height ? h : s.height); } public void setRange(double minValue, double maxValue) { this.minValue = minValue; this.maxValue = maxValue; revalidate(); repaint(); } }