|
This page last changed on Jun 16, 2006 by iiley.
Customizing The LookAndFeel III
This tutorial shows you create your UI for the JButton component.
So by now you should be familiar with the LookAndFeel class and its methods. You should know how to change colours for all the assets of the component.
Lets take a look at all the different assets we can change about the JButton
"Button.background", new ASColorUIResource (0xE7E7E5) ,
"Button.foreground", table.get ("controlText") ,
"Button.opaque", true,
"Button.focusable", true,
"Button.shadow", table.getColor ("controlShadow") ,
"Button.darkShadow", table.getColor ("controlDkShadow") ,
"Button.light", table.getColor ("controlHighlight") ,
"Button.highlight", table.getColor ("controlLtHighlight") ,
"Button.font", table.getFont ("controlFont") ,
"Button.border", org.aswing.plaf.basic.border.ButtonBorder,
"Button.margin", new InsetsUIResource (0, 0, 0, 0) ,
"Button.textShiftOffset", 1
Below is an image showing what properties effect which asset of the button

Now suppose we wanted to change the shape of our button then we would have to create our own UI classes. By looking at the LookAndFeel class we observe that we have to implement two classes. One is for the ButtonUI and the other is the ButtonBorder class.
"ButtonUI", org.aswing.plaf.basic.BasicButtonUI,
"Button.border", org.aswing.plaf.basic.border.ButtonBorder,
So lets create a folder inside our royale class called border and then create our custom border class ButtonBorder. Now add the following code to our class.
/*
Copyright aswing.org, see the LICENCE.txt.
*/
import org.aswing.AbstractButton;
import org.aswing.ASColor;
import org.aswing.border.Border;
import org.aswing.ButtonModel;
import org.aswing.Component;
import org.aswing.geom.Rectangle;
import org.aswing.graphics.Graphics;
import org.aswing.Insets;
import org.aswing.plaf.basic.BasicGraphicsUtils;
import org.aswing.plaf.UIResource;
import org.aswing.UIDefaults;
import org.aswing.UIManager;
/**
*
* @author firdosh
*/
class org.aswing.plaf.royale.border.ButtonBorder implements Border, UIResource
{
private var shadow : ASColor;
private var darkShadow : ASColor;
private var highlight : ASColor;
private var lightHighlight : ASColor;
private static var instance : Border;
/**
* this make shared instance and construct when use.
*/
public static function createInstance () : Border
{
if (instance == null)
{
instance = new ButtonBorder ();
}
return instance;
}
private function ButtonBorder ()
{
var table : UIDefaults = UIManager.getLookAndFeelDefaults ();
this.shadow = table.getColor ("Button.shadow");
this.darkShadow = table.getColor ("Button.darkShadow");
this.highlight = table.getColor ("Button.light");
this.lightHighlight = table.getColor ("Button.highlight");
}
/**
* paint the ButtonBorder content.
*/
public function paintBorder (c : Component, g : Graphics, bounds : Rectangle) : Void
}
public function getBorderInsets (c : Component, bounds : Rectangle) : Insets
{
return new Insets (2, 2, 2, 2);
}
public function uninstallBorder (c : Component) : Void
{
}
}
As you can see we have our 4 colors for the border defined
private var shadow : ASColor;
private var darkShadow : ASColor;
private var highlight : ASColor;
private var lightHighlight : ASColor;
In the constructor we get our custom colours that we had set from the LookAndFeel class
this.shadow = table.getColor ("Button.shadow");
this.darkShadow = table.getColor ("Button.darkShadow");
this.highlight = table.getColor ("Button.light");
this.lightHighlight = table.getColor ("Button.highlight");
The paintBorder method is where we actually draw our border.
It takes in 3 parameters.
- Component - The component object ( in this case the AbstractButton)
- Graphics - The graphics object to create fills and lines.
- Rectangle - The bounds for the component.
Now since our button has two different states (onMouseUp / onMouseDown ) we need to figure out first which state the button is currently in.
var isPressed : Boolean = false;
if (c instanceof AbstractButton)
{
var model : ButtonModel = (AbstractButton (c)).getModel ();
isPressed = model.isPressed () || model.isSelected ();
}
if(isPressed){
}
else{
}
Note : The org.aswing.graphics package has a lot of classes to help you create your interfaces.
For this tutorial I am going to create a simple button but a single border.
var h:Number = bounds.height - 1;
var w:Number = bounds.width - 1;
var x:Number = bounds.x + 0.5;
var y:Number = bounds.y + 0.5;
var p:Pen=new Pen(lightHighlight,1,100);
if(isPressed){
g.drawRoundRect(p,x,y,w,h,6,6,6,6);
}
else{
p.setASColor(shadow);
g.drawRoundRect(p,x+1,y+1,w-1,h-1,6,6,6,6);
}
Since our button is going to have a single border we should set our Insets to 1.
public function getBorderInsets(c:Component, bounds:Rectangle):Insets{
return new Insets(1, 1, 1, 1);
}
This basically creates a round rectangle border for our button. Now lets goto our RoyaleLookAndFeel class and inside the initComponentDefaults method make the following change.
"Button.border", org.aswing.plaf.royale.border.ButtonBorder,
Now org.aswing.plaf.royale.border.ButtonBorder class will be called to draw the border for JButton.
Now lets create a UI class for the JButton. Create a new class called
RoyaleButtonUI under the royale folder.
Add the following code to the class
/*
Copyright aswing.org, see the LICENCE.txt.
*/
import org.aswing.AbstractButton;
import org.aswing.ASColor;
import org.aswing.Component;
import org.aswing.geom.Rectangle;
import org.aswing.graphics.GradientBrush;
import org.aswing.graphics.Graphics;
import org.aswing.graphics.SolidBrush;
import org.aswing.plaf.basic.BasicButtonUI;
import org.aswing.plaf.ComponentUI;
class org.aswing.plaf.royale.RoyaleButtonUI extends BasicButtonUI
{
private static var royaleButtonUI : RoyaleButtonUI;
public function RoyaleButtonUI ()
{
super ();
}
public static function createInstance (c : Component) : ComponentUI
{
if (royaleButtonUI == null)
{
royaleButtonUI = new RoyaleButtonUI ();
}
return royaleButtonUI;
}
/**
* Paint gradient background for AsWing LAF Buttons.
*/
private function paintBackGround (com : Component, g : Graphics, b : Rectangle) : Void
{
}
}
All our code for rendering and drawing the button will fall inside the paintBackGround method.
var c : AbstractButton = AbstractButton (com);
var bgColor : ASColor = (c.getBackground () == null ? ASColor.WHITE : c.getBackground ());
if (c.isOpaque ())
{
if (c.getModel ().isPressed () || c.getModel ().isSelected ())
{
g.fillRoundRect (new SolidBrush (bgColor) , b.x, b.y, b.width, b.height, 6, 6, 6, 6);
return;
}
g.fillRoundRect (new SolidBrush (new ASColor (0xFF8000, 50)) , b.x, b.y, b.width, b.height, 6, 6, 6, 6);
}
Here again we get the state of the button and draw a round rectangle for the button background.
The in the RoyaleLookAndFeel class and inside the initClassDefaults method make the following change.
"ButtonUI", org.aswing.plaf.royale.RoyaleButtonUI,
Now when you run and compile the application file you should see a simple rounded button.
Hope this tutorial series will help you guys get started on creating your own ASWing Themes .
cheers
firdosh
|