/*-
* #%L
* Fiji distribution of ImageJ for the life sciences.
* %%
* Copyright (C) 2007 - 2017 Fiji developers.
* %%
* This program 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/
package spim.fiji.plugin.util;
import ij.gui.GenericDialog;
import java.awt.Canvas;
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.Panel;
import java.awt.RenderingHints;
public class MyMultiLineLabel extends Canvas
{
private static final long serialVersionUID = 1L;
protected String[] lines;
protected int num_lines;
protected int margin_width = 6;
protected int margin_height = 6;
protected int line_height;
protected int line_ascent;
protected int[] line_widths;
protected int min_width, max_width;
final GenericDialog gd;
final Panel panel;
// Breaks the specified label up into an array of lines.
public MyMultiLineLabel( final GenericDialog gd, final Panel panel, final String[] label )
{
this( gd, panel, label, 0 );
}
public MyMultiLineLabel( final GenericDialog gd, final Panel panel, final String[] label, final int minimumWidth )
{
num_lines = label.length;
lines = label;
line_widths = new int[ num_lines ];
min_width = minimumWidth;
this.gd = gd;
this.panel = panel;
}
public String[] getLines() { return lines; }
public void setText( final String[] lines )
{
for ( int i = 0; i < this.lines.length; ++i )
{
if ( i >= lines.length )
this.lines[ i ] = " ";
else
this.lines[ i ] = lines[ i ];
}
updateLabel();
}
public void updateLabel()
{
this.update( this.getGraphics() );
}
/** Adds a message consisting of one or more lines of text,
which will be displayed using the specified font and color. */
public static MyMultiLineLabel addMessage( final GenericDialog gd, final String[] text, final Font font, final Color color )
{
final Panel panel = new Panel();
final MyMultiLineLabel l = new MyMultiLineLabel( gd, panel, text );
l.setFont( font );
l.setForeground( color );
panel.add( l );
gd.addPanel( panel );
return l;
}
// Figures out how wide each line of the label
// is, and how wide the widest line is.
protected void measure()
{
final FontMetrics fm = this.getFontMetrics( this.getFont() );
// If we don't have font metrics yet, just return.
if (fm == null) return;
line_height = fm.getHeight();
line_ascent = fm.getAscent();
max_width = 0;
for( int i = 0; i < num_lines; i++ )
{
line_widths[ i ] = fm.stringWidth( lines[ i ] );
if ( line_widths[ i ] > max_width )
max_width = line_widths[i];
}
}
public void setFont( final Font f )
{
super.setFont( f );
measure();
repaint();
}
// This method is invoked after our Canvas is first created
// but before it can actually be displayed. After we've
// invoked our superclass's addNotify() method, we have font
// metrics and can successfully call measure() to figure out
// how big the label is.
public void addNotify()
{
super.addNotify();
measure();
}
// Called by a layout manager when it wants to
// know how big we'd like to be.
public Dimension getPreferredSize()
{
return new Dimension( Math.max( min_width, max_width + 2*margin_width ),
num_lines * line_height + 2*margin_height );
}
// Called when the layout manager wants to know
// the bare minimum amount of space we need to get by.
public Dimension getMinimumSize()
{
return new Dimension(Math.max(min_width, max_width), num_lines * line_height);
}
// Draws the label
public void paint( final Graphics g )
{
int x, y;
final Dimension d = this.getSize();
if ( !ij.IJ.isLinux() ) setAntialiasedText( g );
y = line_ascent + (d.height - num_lines * line_height)/2;
for( int i = 0; i < num_lines; i++, y += line_height )
{
x = margin_width;
g.drawString( lines[ i ], x, y );
}
}
void setAntialiasedText( final Graphics g )
{
final Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
}