/*
* Copyright 2009 Peter Karich, peat_hal ‘at’ users ‘dot’ sourceforge ‘dot’ net.
*
* 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.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.
* under the License.
*/
package de.timefinder.planner;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.text.AttributedString;
import java.util.ArrayList;
/**
* This class can be used to display a round box with a string.
*
* @author Peter Karich, peat_hal ‘at’ users ‘dot’ sourceforge ‘dot’ net
*/
public class RoundBox {
private Rectangle2D rect;
private static Color cornFlowerBlue = new Color(155, 155, 255);
private static Color lightBlue = new Color(0.6f, 0.6f, 1.0f, .6f);
private static GradientPaint gradient = new GradientPaint(0, 0, lightBlue, 0, 50, cornFlowerBlue, true);
private static AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .4f);
private static AlphaComposite compositeIfTransparent = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .8f);
private String text;
private int arc = 20;
private boolean transparent = true;
private int textWidthOffset = 4;
private float widthMultiplier = 1;
public RoundBox() {
}
public RoundBox(String text) {
setText(text);
}
/**
* @param widthMultiplier the factor by which the width
* in the zoom mode will be multiplied
*/
public RoundBox(String text, float widthMultiplier) {
setText(text);
this.widthMultiplier = widthMultiplier;
}
public void paintComponent(Graphics2D g2d) {
Paint oldPaint = g2d.getPaint();
Composite oldComposite = g2d.getComposite();
Color oldColor = g2d.getColor();
Shape oldClip = g2d.getClip();
if (!transparent) {
g2d.setColor(Color.WHITE);
g2d.setComposite(compositeIfTransparent);
g2d.fillRoundRect((int) rect.getX(), (int) rect.getY(),
(int) rect.getWidth(), (int) rect.getHeight(), arc, arc);
g2d.setColor(lightBlue);
g2d.fillRoundRect((int) rect.getX(), (int) rect.getY(),
(int) rect.getWidth(), (int) rect.getHeight(), arc, arc);
} else {
g2d.setComposite(composite);
g2d.setPaint(gradient);
g2d.fillRoundRect((int) rect.getX(), (int) rect.getY(),
(int) rect.getWidth(), (int) rect.getHeight(), arc, arc);
}
g2d.setPaint(oldPaint);
g2d.setComposite(oldComposite);
g2d.setColor(Color.DARK_GRAY);
g2d.drawRoundRect((int) rect.getX(), (int) rect.getY(),
(int) rect.getWidth(), (int) rect.getHeight(), arc, arc);
g2d.clip(rect);
if (text != null) {
FontMetrics metrics = g2d.getFontMetrics(g2d.getFont());
ArrayList<TextLayout> layouts = breakLines((int) rect.getWidth() - textWidthOffset * 2,
text, metrics);
int textHeight = metrics.getHeight();
int top = textHeight;
for (TextLayout layout : layouts) {
layout.draw(g2d, (float) rect.getX() + textWidthOffset, (float) rect.getY() + top);
top += textHeight;
}
}
g2d.setClip(oldClip);
g2d.setColor(oldColor);
}
public void setRect(Rectangle2D rect) {
this.rect = rect;
}
public void setTransparent(boolean tr) {
transparent = tr;
}
public void zoom(Shape oldClip) {
float nWidth = (float) (widthMultiplier * rect.getWidth());
float nHeight = (float) (1f * rect.getHeight());
int offset = 30;
rect.setRect(rect.getX() - offset, rect.getY() - offset,
nWidth + offset * 2, nHeight + offset * 2);
rect = rect.createIntersection(oldClip.getBounds2D());
}
public void setText(String s) {
text = s;
}
/**
* This method breaks a string into TextLayout's so that every string fits
* into the specified wrapWidth.
*/
public static ArrayList<TextLayout> breakLines(int wrapWidth, String str,
FontMetrics metrics) {
ArrayList<TextLayout> layoutList = new ArrayList<TextLayout>();
if (str.length() > 0 && wrapWidth > 5) {
// expensive methode, because if wrapWidth is too small => layoutList could be very large!!
String lines[] = str.split("\\n");
TextLayout layout;
for (String text : lines) {
final AttributedString attStr = new AttributedString(text);
//attStr.addAttribute(TextAttribute.FONT, new Font ("TimesRoman", Font.PLAIN, 12));
final LineBreakMeasurer measurer =
new LineBreakMeasurer(attStr.getIterator(),
metrics.getFontRenderContext());
while ((layout = measurer.nextLayout(wrapWidth)) != null) {
layoutList.add(layout);
}
}
}
return layoutList;
}
}