package net.xoetrope.swing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.RenderingHints;
import javax.swing.JPanel;
import net.xoetrope.swing.painter.XImagePainter;
import org.jdesktop.swingx.painter.Painter;
import net.xoetrope.swing.painter.XTitlePainter;
import net.xoetrope.xui.XAttributedComponent;
import net.xoetrope.xui.XProjectManager;
import net.xoetrope.xui.helper.XuiUtilities;
import net.xoetrope.xui.style.XStyle;
import net.xoetrope.xui.style.XStyleManager;
/**
* A basic container for components. The panel can optional draw a
* border. By default no frame is displayed.
* <p>Copyright (c) Xoetrope Ltd., 1998-2004<br>
* License: see license.txt
* @version 1.0
*/
public class XPanel extends JPanel implements XAttributedComponent
{
/**
* No border
*/
public static final int BORDER_NONE = 0;
/**
* A line border
*/
public static final int BORDER_FLAT = 1;
/**
* A bevel border
*/
public static final int BORDER_BEVEL = 2;
protected int drawFrame = BORDER_NONE;
protected boolean usesLaf = false;
protected boolean translucent = false;
protected int arc = 0;
protected int padding = 0;
private Painter painter;
/**
* Constructs a new panel with a null layout
*/
public XPanel()
{
super();
setLayout( null );
setOpaque( true );
}
/**
* Repaint the component once it has been created
*/
public void addNotify()
{
super.addNotify();
invalidate();
}
/**
* Update the component by painting its background
* @param g the graphics context
*/
public void update( Graphics g )
{
paint( g );
}
/**
* Get the insets
* @return the insets
*/
public Insets getInsets()
{
Insets ins = new Insets( padding, padding, padding, padding );
if ( getBorder() != null ) {
Insets insets = getBorder().getBorderInsets( this );
ins = new Insets( ins.top + insets.top,
ins.left + insets.left,
ins.bottom + insets.bottom,
ins.right + insets.right );
}
return ins;
}
/**
* Update the panel by erasing and then rendering the frame if any
* @param g the graphics context
*/
public void paintComponent( Graphics g )
{
int w = getSize().width;
int h = getSize().height;
Color bkColor = getBackground();
if ( usesLaf )
bkColor = bkColor.brighter();
else
bkColor = bkColor.darker();
if ( isOpaque() || translucent ) {
if ( usesLaf )
super.paintComponent( g );
else if ( painter != null )
painter.paint( (Graphics2D)g, this, w, h );
else {
g.setColor( getBackground());
Insets insets = getInsets();
if ( arc <= 0 ) {
// g.fillRect( insets.left, insets.top, w - insets.left - insets.right, h - insets.top - insets.bottom );
g.fillRect( 0, 0, w, h );
}
else {
Graphics2D g2d = (Graphics2D)g;
Object oldHint = g2d.getRenderingHint( RenderingHints.KEY_RENDERING );
g2d.setRenderingHint( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
g2d.fillRoundRect( 0, 0, w, h, arc, arc );
g2d.setRenderingHint( RenderingHints.KEY_RENDERING, oldHint );
}
}
}
if ( drawFrame > BORDER_NONE ) {
if ( drawFrame == BORDER_BEVEL ) {
g.setColor( Color.white );
g.drawLine( 0, 0, w-1, 0 );
g.drawLine( 0, 0, 0, h-1 );
g.setColor( bkColor );
g.drawLine( w-1, 0, w-1, h-1 );
g.drawLine( 0, h-1, w-1, h-1 );
}
else {
g.setColor( bkColor );
if ( arc <= 0 )
g.drawRect( 0, 0, w - 1, h - 1 );
else
g.drawRoundRect( 0, 0, w - 1, h - 1, arc, arc );
}
}
}
/**
* Get the arc size
* @return the arc size
*/
public int getArc()
{
return arc;
}
/**
* Set the arc size
* @param value the arc size
*/
public void setArc( int value )
{
arc = value;
}
/**
* Set the background painter object
* @param xp the painter object
*/
public void setPainter( Painter xp )
{
painter = xp;
}
/**
* Get the background painter object
* @return the painter object
*/
public Painter getPainter()
{
return painter;
}
/**
* Toggle the frame display.
* @param value 0 for no frame, 1 for a bevel, 2 for a flat frame
*/
public void setDrawFrame( int value )
{
drawFrame = value;
}
/**
* Set the painting of the background
* @param value true to have the LAF paint the background or false for the
* component to paint it itself using the colours specified in the styles (if any)
*/
public void setUsesLaf( boolean value )
{
usesLaf = value;
}
/**
* Get the flag for painting of the background
* @return true when the LAF paint the background or otherwise false when the
* component to paint it itself using the colours specified in the styles (if any)
*/
public boolean getUsesLaf()
{
return usesLaf;
}
/**
* Get the frame display value.
* @return val 0 for no frame, 1 for a bevel, 2 for a flat frame
*/
public int getDrawFrame()
{
return drawFrame;
}
/**
* Set one or more attributes of the component.
* <OL>
* <LI>border value=(0|1) for nor border or for a border</LI>
* <LI>laf value=(true|false) rely on the look and feel to paint the background</LI>
* <LI>opaque value=(true|false) false to rely on the parent component to paint the background</LI>
* <LI>translucent value=(true|false) when a non-opaque window is render a value
* of true for this property causes the background to be painted, whereas with
* the default false value the background is not painted</LI>
* <LI>imagename value=the name of a background image to use as a watermark</LI>
* <LI>painter value=the class name of an Painter class for painting the panel backgrounds</LI>
* <LI>title value=the text for the panel title</LI>
* <LI>arc value=the radius for teh panel corners</LI>
* <LI>buffered value=true for double buffering</LI>
* <LI>titleStyle value=the name of the style for the title</LI>
* </OL>
* @param attribName the attribute name
* @param attribValue the attribute value
* @return 0 for success, non zero for failure or to require some further action
*/
public int setAttribute( String attribName, Object attribValue )
{
String attribNameLwr = attribName.toLowerCase();
String attribValueStr = (String)attribValue;
String attribValueLwr = null;
if ( attribValue != null )
attribValueLwr = attribValueStr.toLowerCase();
if ( attribValueLwr == null )
return -1;
if ( attribNameLwr.equals( "border" ))
setDrawFrame( Integer.parseInt( attribValueLwr ) );
else if ( attribNameLwr.equals( "laf" ))
setUsesLaf( attribValueLwr.equals( "true" ) );
else if ( attribNameLwr.equals( "opaque" ))
setOpaque( attribValueLwr.equals( "true" ));
else if ( attribNameLwr.equals( "translucent" ))
translucent = attribValueLwr.equals( "true" );
else if ( attribNameLwr.equals( "arc" ))
arc = Integer.parseInt( attribValueStr );
else if ( attribNameLwr.equals( "pad" ))
padding = Integer.parseInt( attribValueStr );
else if ( attribNameLwr.equals( "buffered" ))
setDoubleBuffered( attribValue.equals( "true" ));
else if ( attribNameLwr.equals( "tooltip" ))
setToolTipText( attribValueStr );
else if ( attribNameLwr.equals( "imagename" )) {
try {
XImagePainter xp = new XImagePainter();
xp.setImage( attribValueStr );
setPainter( xp );
}
catch ( Exception e )
{}
}
else if ( attribNameLwr.equals( "painter" )) {
try {
Painter xp = (Painter)Class.forName( attribValueStr.trim()).newInstance();
setPainter( xp );
}
catch ( Exception e )
{}
}
else if ( painter != null ) {
if ( painter instanceof XTitlePainter ) {
if ( attribNameLwr.equals( "blend" ))
((XTitlePainter)painter).setBlend( attribValueLwr.equals( "true" ) );
else if ( attribNameLwr.equals( "title" ))
((XTitlePainter)painter).setTitle( attribValueStr );
else if ( attribNameLwr.equals( "titlepos" ))
((XTitlePainter)painter).setTitlePosition( Integer.parseInt( attribValueStr ));
else if ( attribNameLwr.equals( "titlestyle" )) {
XStyleManager sm = XProjectManager.getStyleManager();
XStyle xstyle = sm.getStyle( attribValueStr );
((XTitlePainter)painter).setTitleColor( xstyle.getStyleAsColor( XStyle.COLOR_BACK ));
((XTitlePainter)painter).setTitleTextColor( xstyle.getStyleAsColor( XStyle.COLOR_FORE ));
((XTitlePainter)painter).setTitleFont( sm.getFont( attribValueStr ));
}
}
}
else
return -1;
return 0;
}
/**
* Get the preferred size of the panel. If no layout is used then the
* maximum X and y coordinates used in this panel are returned.
* @return the preferred size of this panel
*/
public Dimension getPreferredSize()
{
if ( getLayout() == null ) {
Point p = XuiUtilities.getMaxCoordinates( this );
Point pt = getLocation();
p = new Point( p.x - pt.x, p.y - pt.y );
if ( getBorder() != null ) {
Insets insets = getBorder().getBorderInsets( this );
p.setLocation( p.getX() + insets.left + insets.right, p.getY()
+ insets.top + insets.bottom );
}
if (( p.x <= 0 ) || ( p.y <= 0 ))
return new Dimension( 0, 0 );
return new Dimension( p.x, p.y );
}
Dimension dim = super.getPreferredSize();
Insets insets = getInsets();
dim.setSize( dim.getWidth() + insets.left + insets.right,
dim .getHeight() + insets.top + insets.bottom );
return dim;
}
public void setBounds( int x, int y, int w, int h )
{
if (( h >= 0 ) && ( w >= 0 ))
super.setBounds( x, y, w, h );
}
}