Monday, June 11, 2007
Saturday, June 9, 2007
GRAPHICS DEBUGGING.
GRAPHICS DEBUGGING.
Debugging graphics involves the ability to observe every painting operation as it occur during the rendering of a component and all of its children. Intended for problem finding with rendering, layout and container hierarchies. i.e everything display related.
When graphics debugging is enabled, the graphics object used in painting is an instance of DebugGraphics class which extends the Graphics class. JComponent and every swing component support graphics debugging which can be turned on or off with Jcomponent's setDebugGraphicsOption( ) method. This methods takes an int parameter that details the debug options. This parameter determines how the component should display the information:
if :
1.DebugGraphics.LOG_OPTION – a text message is printed.
2.DebugGraphics.FLASH_OPTION - The display flashes several times.
3.DebugGraphics.BUFFERED_OPTION - It creates an external window that displays the operations performed on this view's offscreen buffer.
4.DebugGraphics.NON_OPTION - Debug disabled.
5.If 0 no change is issued to the debugging option.
Note that these values can be bitwise OR'd into the current value.
Let's explore the options one after the other:
1.DebugGraphices.FLASH_OPTION.
Each paint operation flashes a specified number of times, in a specified flash color, with a specified flash interval.
You set this values with the following methods from the DebugGraphcics static methods :
setFlashTime(int flashTime)
setFlashCount (int flashCount)
setFlashColor (Color flashColor)
to see the flashing as it occurs you must disable buffering like this:
RepaintManager.currentManager(null).setDoubleBuffereingEnabled(false).
After this every component's doubleBuffered properyty will henceforth be ignored.
I loved the flashing at first instance and have been flashing my computer since.
So let me drop a code for that. See how the buttons changed color.
package tests;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Property extends JPanel{
//declaring an instance
static Color dColor = new Color(0, 255, 100, 125);
//the dimension
static Dimension dim = new Dimension(400, 400);
static JButton jButton1 = new JButton(" ");
static JTextArea jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("click me");
add(jButton1);
//we'll use the instance as foreground.
jButton1.setBackground(dColor);
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
//buffering and opaque value for painting and updating
nProp.setOpaque(true);
nProp.setDoubleBuffered(true);
//graphics debugging
nProp.setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION);
DebugGraphics.setFlashColor(Color.red);
DebugGraphics.setFlashCount(5);
DebugGraphics.setFlashTime(10);
RepaintManager.currentManager(null).setDoubleBufferingEnabled(false);
//set max, min and preferred sizes
nProp.setMaximumSize(dim);
nProp.setMinimumSize(dim);
nProp.setPreferredSize(dim);
frame.setContentPane(nProp);
//let the above size stay 4ever
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
public static void simplyText(String txt){
jText.append(txt+"\n");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
//counter
int c = 0;
//for use below
int w=0;
int h=0;
int d=0;
//get damaged region
Rectangle r = g.getClipBounds();
int clipx = r.x;
int clipy = r.y;
int clipw = r.width;
int cliph = r.height;
//fill only damaged region
g.setColor(Color.white);
g.fillRect(clipx, clipy, clipw, cliph);
//filled yellow circle only if bounding region is damaged
if (clipx <= 240 && clipy <= 240){
g.setColor(Color.yellow);
g.fillOval(0, 0, 240, 240);
c++;
}
//filled magenta cirlce if bounding region has been damaged
if (clipx + clipw>=160 && clipx<=400 && clipy+cliph>=160 && clipy<=400){
g.setColor(Color.magenta);
g.fillOval(160, 160, 240, 240);
c++;
}
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
2.DebugGraphics.LOG_OPTION: each paint operation is messaged as they occur and by default are directed to standard output i.e System.out. Note that these output can be redirected with DebugGraphic's static setLogStream() method which method takes a PrintStream instance as a parameter.
we can also instance any string into the log using the debuggraphics static logStream () method.
3.DebugGraphics.BUFFERED_OPTION . This pops up a frame that gives offscreen rendering. Double-buffering must be enabbled.
4.DebugGraphics.NONE_OPTION. Basically shuts down graphics debugging by nullifying the settings.
Caveats in graphics debugging.
You'll notice that the button color changed from the default to brown due to its being blended with the flash color, red. Yeah, that's a caveat in graphics debugging.
1. Where the UI delegate of the component is null. If a component's UI delegate is null, graphics debugging will not work. The best way to go around this is if you declared a class without a UI delegate so as to define a trivial (empty) UI delegate.
2. DebugGraphics does not properly clean up after itself. A flash results in painting over of the color of the components and it does not get erased. This presents a problem because transparent rendering now becomes alpha blended with the flash color. You can hide the flash color though by giving its color an alpha value of invisible, i.e 0 or 0.0. we can sidestep this blending by making the flash time and flashcount to wait long enough between operations.
To implement the above we can rewrite the above code adding the below:
package tests;
import javax.swing.plaf.ComponentUI;
import javax.swing.*;
public class EmptyUI extends ComponentUI {
private static final EmptyUI sharedInstance = new EmptyUI();
public static ComponentUI createUI(JComponent c){
return sharedInstance;
}
}
then to the Property class we add this code as the first line in its constructor:
super.setUI(EmptyUI.createUI(this));
Posted by
cyprian.ekere
at
9:56 AM
8
comments
Friday, June 8, 2007
DEALING WITH GRAPHICS AND TEXT
DEALING WITH GRAPHICS AND TEXT
first of all know that every component owns its own graphics context, which context is defined in the Graphics class of java.awt package and has the following properties:
1.the component object on which to draw
2.a translation origin for rendering and clipping coordinates
3.the current clip
4.the current color
5.the current font
6.the current logical pixel operation function (XOR or paint)
7.the current XOR alternation color
although in AWT to paint we typically override component's paint() method, to do rendering we use the update() method for implementing our own double buffering and background filling before calling paint(), but in swing, if any component wants to take charge of its rendering, it should override the paintComponent() method and not the paint() method and should always begin the paintComponent() method with a call to super.paintComponent() thereby it acts as its own lightweight canvas.
Note before: the above is useful for simple custom components but for normal swing component, since the UI delegate is in charge of rendering, never attempt it.
Inside the paintComponent() method, we have access to the component's graphics object or its graphics context used for painting shapes and drawing lines and text. Check the graphics class for useful methods.
Some code that illustrates the above.
package tests;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Property extends JPanel{
//declaring an instance
static Color dColor = new Color(0, 255, 100, 125);
static Color mainRed = new Color(255, 0, 0, 150);
static Color mainGreen = new Color(0, 255, 0, 150);
static Color mainBlue = new Color (0, 0, 255, 150);
static Font mainBIFont = new Font("Monospace", Font.BOLD| Font.ITALIC, 36);
static Font mainPFont = new Font("SansSerif", Font.PLAIN, 12);
static Font mainBFont = new Font("Serif", Font.BOLD, 24);
//the dimension
static Dimension dim = new Dimension(400, 400);
static JButton jButton1 = new JButton(" ");
static JTextArea jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("click me");
add(jButton1);
//we'll use the instance as foreground.
jButton1.setBackground(dColor);
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
//buffering and opaque value for painting and updating
nProp.setOpaque(true);
nProp.setDoubleBuffered(true);
//set max, min and preferred sizes
nProp.setMaximumSize(dim);
nProp.setMinimumSize(dim);
nProp.setPreferredSize(dim);
frame.setContentPane(nProp);
//let the above size stay 4ever
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
public static void simplyText(String txt){
jText.append(txt+"\n");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
//fill entire component white
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
//fills yellow circle
g.setColor(Color.yellow);
g.fillOval(0, 0, 240, 240);
//filled magenta circle
g.setColor(Color.magenta);
g.fillOval(160, 160, 240, 240);
g.setColor(Color.black);
//text is bold, italic, 36-point, "Nigeria"
g.setFont(mainBIFont);
FontMetrics fm = g.getFontMetrics();
int w = fm.stringWidth("NIGERIA");
int h = fm.getAscent();
g.drawString("NIGERIA", 120-(w/2), 120+(h/4));
//plain, 12-point, "go"
g.setFont(mainPFont);
fm = g.getFontMetrics();
w = fm.stringWidth("go");
h = fm.getAscent();
g.drawString("go", 200-(w/2), 200+(h/4));
//bold, 24-point, "SURVIVE"
g.setFont(mainBFont);
fm = g.getFontMetrics();
w = fm.stringWidth("GO");
h = fm.getAscent();
g.drawString("SURVIVE", 280-(w/2), 280+(h/4));
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
If you run the above code, it'll display: “NIGERIA go SURVIVE” in bright colors that illustrates the power of the rendering and painting properties of every graphics context for swing component. Worthy of note though is that not the totality of the area of a component is painted but for the sake of efficiency there are some so-called “dirtied” areas or damaged areas which are defined as the bounds of the clipping area which are not painted. You can get a Rectangle object showing this by calling getClipBounds() method of the Graphics class.
Posted by
cyprian.ekere
at
10:38 AM
0
comments
Labels: awt, canvas, clipping coordinates, color
COLORS IN SWING
COLORS IN SWING
the color class encapsulates colors in the default sRGB color space or colors in the arbitrary color spaces identified by a ColorSpace class. Every color has an implicit alpha value of 1.0 or an explicit one provided in the constructor, which alpha values denote the color's transparency and 1.0 means totally transparent if denoted with a float range or 255 if an int range. Also alpha values of 0 or 0.0 means completely transparent color. Note that color classes do not pre-multiply alpha values.
Information on the sRGB color space is defined by the World Wide Web consortium
the overloaded constructors for color take a colorspace parameter, float or int values. Check this out in the api.
Like the font accessor methods, getXX() methods are specified for the color class but in modifying any color instance, one is usually expected to create a new one. By specifying an alpha value, we can use a color instance on a component's background to make it transparent. Note that when setting the foreground of a component the look and feel may ignore the color specified.
Our button and textareas colored with Color.
package tests;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Property extends JPanel{
//declaring an instance
static Color dColor = new Color(0, 255, 100, 125);
static JButton jButton1 = new JButton(" ");
static JTextArea jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("click me");
add(jButton1);
//we'll use the instance as foreground.
jButton1.setBackground(dColor);
jText = new JTextArea(" ", 10, 20);
add(jText);
GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames = genv.getAvailableFontFamilyNames();
for (int i=0; i
}
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
nProp.setOpaque(true);
//and also use it here too
nProp.setBackground(dColor);
frame.setContentPane(nProp);
frame.pack();
frame.setVisible(true);
}
public static void simplyText(String txt){
jText.append(txt+"\n");
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
keywords: color, swing, colorspace, alpha value, sRGB, GraphicsEnvironment
Posted by
cyprian.ekere
at
6:30 AM
0
comments
FONTS
FONTS
to work with fonts, two classes are worth noting, the GraphicsEnvironment and Font classes which are both in the java.awt package.
GraphicsEnvironment: this class describes a collection of GraphicsDevices and font objects that are available to a java application on a particular platform and note that the resources might be local or remote. GraphicsDevices might be screens, printers or image buffers. Each GraphicsDevice has a number of Graphicsconfiguration objects associated with it that specifies configuration usage for different GraphicsDevices.
Font: this represents a class for rendring text in a visible way. A font provides information needed to map sequence of characters to sequence of glyphs and to render a sequence of glyphs as Graphics on component classes.
we can retrieve font related properties from a local or remote machine using the GraphicsEnvironment and font classes working together.
Here is a code that demonstrates the fonts available on my windows xp machine:
package tests;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Property extends JPanel{
static JButton jButton1 = new JButton(" ");
static JTextArea jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("click me");
add(jButton1);
jText = new JTextArea(" ", 10, 20);
add(jText);
GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames = genv.getAvailableFontFamilyNames();
for (int i=0; i
}
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
nProp.setOpaque(true);
frame.setContentPane(nProp);
frame.pack();
frame.setVisible(true);
}
public static void simplyText(String txt){
jText.append(txt+"\n");
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
Although we can use the classic getXX() accessor methods for font objects note that to set them we have to derive fonts using an overloaded deriveFont() method.
Posted by
cyprian.ekere
at
4:20 AM
0
comments
Labels: fonts, glyphs, graphicsconfiguration, graphicsenvironment, jpanel, package
USING TIMERS WITH SWING.
USING TIMERS WITH SWING.
A timer instance can be considered as a unique thread that fires one or more action events at specified intervals. The timer class for use in GUI contexts in java is defined in the javax.swing.Timer class.
Let's write a code for creating a Timer class.
package tests;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Property extends JPanel{
static JButton jButton1 = new JButton(" ");
static JTextArea jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("click me");
add(jButton1);
jText = new JTextArea("welcome", 2, 50);
add(jText);
//start the timer
int delay = 10000; // 3 sec. delay initially and between firing
//the action listener that processes the timer event
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEvent ae){
simplyText("Don't forget me.");
}
};
//create an instance of a timer with delay and action listener
//then start timer thread
Timer tim = new Timer (delay, al);
tim.start();
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
nProp.setOpaque(true);
frame.setContentPane(nProp);
frame.pack();
frame.setVisible(true);
}
public static void simplyText(String txt){
jText.setText(txt);
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
Posted by
cyprian.ekere
at
4:19 AM
0
comments
Labels: timers and swing
THE EVENT DISPATCHING THREAD
THE EVENT DISPATCHING THREAD
Listeners, as we've mentioned before, process every event and every event is in an event-dispatching thread. In the api, a FIFO queue of events is associated with this thread, an EventQueue instance, that is the system events queue and defined in the java.awt.EventQueue class. This queue is filled in a serial fashion, FIFO-like. As events are executed, this is done serially too, whether the event is a component property update or repainting .
Please ensure that all your events are within this thread and none should be dispatched outside this event dispatching thread. Also ensure that event handling code and painting codes will be executed quickly, i.e keep them simple. Otherwise, one event that takes up time could block the whole queue and your application gets frozen or locked up.
I have written a code here that makes use of the event dispatching threads on two listeners that listen for the same type of event, a mouse click.
package tests;
import java.awt.event.*;
public class FirstListener extends MouseAdapter {
public void mouseClicked(MouseEvent e){
//after this listener processes event, remove from queue
//and just add the second to make sure we did not remove
//it earlier also
Property.simplyText("the first listener at attention.");
Property.jButton1.removeMouseListener(this);
Property.jButton1.addMouseListener(new SecondListener());
}
}
import java.awt.event.*;
public class SecondListener extends MouseAdapter {
public void mouseClicked(MouseEvent e){
//after this listener processes event, remove from queue
//and just add the second to make sure we did not remove
//it earlier also
Property.simplyText("the second listener at attention.");
Property.jButton1.removeMouseListener(this);
Property.jButton1.addMouseListener(new FirstListener());
}
}
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Property extends JPanel{
EventListenerList listenerList = new EventListenerList();
FirstListener fl = new FirstListener();
SecondListener sl = new SecondListener();
MouseEvent me;
static JButton jButton1 = new JButton(" ");
static JTextArea jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("click me");
add(jButton1);
//here are the two listeners added to the event dispatching
//queue
jButton1.addMouseListener(fl);
jButton1.addMouseListener(sl);
jText = new JTextArea("welcome", 5, 50);
add(jText);
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
nProp.setOpaque(true);
frame.setContentPane(nProp);
frame.pack();
frame.setVisible(true);
}
public static void simplyText(String txt){
jText.setText(txt);
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
Posted by
cyprian.ekere
at
3:56 AM
0
comments
Labels: event dispatching, fifo, java, mouseadapter, queue, thread
EVENT LISTENER LIST.
EVENT LISTENER LIST.
The EventListenerList class is defined in the javax,swing.event package. An EventListernerList is an array of XXEvent/XXListener pairs. JComponent and each of its descendants use an EventListenerList to maintain their listeners. All default models also maintain listeners and an EventListenerList.
On adding a listener to a swing component or model, the associated event's Class instance (used to identify event type) is added to its EventListenerList array followed by the listener itself.
Since these pairs are stored in an array rather than a mutable collection, a new array is created on each addition or removal using the System.arrayCopy() methods.
When events are received, the list is walked through and events are sent to each listener with a matching type. Because the array is ordered in an XXEvent, XXListener, YYEvent, YYListener fashion, a listener corresponding to a given event type is always next in the array. This gives for very efficient event-dispatching routines.
For thread safety, the methods for adding and removing listeners from an event listener synchronises access to the array when it is manipulated.
In JComponent, the EventListenerList is a protected field called listenerList so that all subclasses inherit it and most listeners are managed through listenerList.
Here is a code where the class itself handles the event and is the sole occupant of the component's event listener list.
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.lang.*;
public class Property extends JPanel implements ActionListener{
JButton jButton1 = new JButton(" ");
JTextField jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("click me");
add(jButton1);
//this object is its own action listener
jButton1.addActionListener(this);
jText = new JTextField("welcome", 50);
add(jText);
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
nProp.setOpaque(true);
frame.setContentPane(nProp);
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e){
//get the action listeners associated with this object, here one
ActionListener[] al = jButton1.getActionListeners();
jText.setText("the "+al[0].getClass().toString()+" is the action listener " +
"in the list");
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
Posted by
cyprian.ekere
at
3:50 AM
0
comments
Labels: event, jcomponent, listener lists, Swingutilities
EVENT HANDLING AND DISPATCHING.
EVENT HANDLING AND DISPATCHING.
Pressing a key or mouse button generates events. The type of events that swing components can generate whether in java.awt.event or javax.swing.event packages are of different types. Some event types are component specific.
Each event type is represented by an object that identifies the source of the event and other additional information about what specific kind of event it is and information about the state of the source before and after the event was generated. Sources of events are most commonly components or models but also different kinds of objects can generate events.
To receive notification of events, we need to register listeners with the target object . A listener is an implementation of any of the XXListener classes (where XX is an event type) defined in the java.awt.event, java.beans and javax.swing.event packages. There is at least one method defined in each interface that takes a corresponding XXEvent as parameter. Any class supporting XXEvents notification generally implements the XXListener interface and have support for registering those listeners through addXXListener methods and unregistering those listeners through removeXXLister methods. Most event targets allow any number of listeners to be registered with them. Also any listener instance can be registered to receive events for any number of event source. Usually classes that support XXEvents() provide protected fireXX() methods used for constructing event objects and sending them to the event handlers for processing.
The code below was repeated from an earlier one but with comments that emphasis some aspects of events handling.
import javax.swing.*;
import java.awt.event.*;
//implementing listeners that processes this event type
public class Property extends JPanel implements ActionListener{
JButton jButton1 = new JButton(" ");
JTextField jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("button1");
add(jButton1);
//registering instances of this class to receive this events
jButton1.addActionListener(this);
jText = new JTextField("welcome", 20);
add(jText);
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
nProp.setOpaque(true);
frame.setContentPane(nProp);
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e){
//event handler with associated object as parameter
jText.setText(jButton1.getMaximumSize().toString());
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
Posted by
cyprian.ekere
at
3:43 AM
0
comments
Wednesday, June 6, 2007
JCOMPONENT SIZING AND POSITIONING METHODS.
JCOMPONENT SIZING AND POSITIONING METHODS.
Since JComponent extends java.awt.container, it inherits the sizing and positioning functionality of the AWT (for those familiar with AWT).
To manage a component's preferred, minimum and maximum size, the following methods are used:
the setters: setPreferred size(), setMinimumSize(), setMaximumsize().
The getters: getPreferredSize(), getMinimumSize(), getMaximumSize().
All these methods return a Dimension instance. Note that the size of components in a container is layout manager specific (the layout manager is the class responsible for laying out the components of a a container. ) The layout manager might ignore or respect sizing commands.
To assign a component both a size and a position with its parent container, we use JComponent's setBounds() method. The method takes a rectangle parameter or 4 int parameters that represent the x-coordinate, y-coordinate, width and height. Note that layout managers always have the first crack at component sizing, so setBounds() might be ignored in some cases. Use setBounds though if your component has no layout manager.
You can query a component's size using its getHeight() and getWidth() methods.
Also we can set a component's position within its container using the setLocation(int x, int y) method.
JComponent also maintains an alignment. Horizontal and vertical alignment can be specified by float values between 0.0 and 1.0. 0.5 means center, close to 0.0 means left or top and closer to 1.0 means right or bottom. The JComponent methods are : setAlignmentX(float f), setAlignmentY(float f).
Posted by
cyprian.ekere
at
6:05 AM
0
comments
JCOMPONENT PROPERTIES.
JCOMPONENT PROPERTIES.
All swing components conform to the javabeans specification. The javabeans specification will be discussed later. Among the five features a javabean is expected to support are a set of properties and associated accessor methods for them.
Property: a property is a global variable. Accessor methods, if any, of a property are of the setPropertyName(), getPropertyName(), or isPropertyName() methods.
a. Simple, bound and constrained properties.
A simple property is a property that has no event firing associated with a change in its value.
A bound property is a property from which a property change event is/are fired after it changes state. We can register propertyChangeListeners to listen for propertyChangeEvents through JComponent's addPropertyChangeListener method.
Constrained porperty is a property for which propertyChangeEvents are fired before a change in state occurs. We can register vetoableChangeListeners to listen for propertyChangeEvents through JComponent's addVetoableChangeListener method. A change can be vetoed in the event handling code of a vetoableChangeListener by throwing a propertyVetoException. Only one swing class has constrained properties, the JInternalFrame class.
PropertyChangeEvents carry three pieces of information: name of the property, old value and new values. Beans can use an instance of propertyChangeSuppport to manage the dispatching of propertyChangeEvents corresponding to each bound property to each registered listener. Also, an instance of vetoabableChangeSupport can be used to manage the sending of all propertyChangeEvents corresponding to each constrained property. There is a class in swing, swingPropertyChangeSupport in the javax.swing.events package that extends the propertyChangeSupport class and provides more efficient methods.
Code for a class that demonstrates bound properties.
import javax.swing.*;
import java.awt.event.*;
public class Property extends JPanel implements ActionListener{
JButton jButton1 = new JButton(" ");
JTextField jText;
/** Creates a new instance of Property */
public Property() {
jButton1 = new JButton("button1");
add(jButton1);
jButton1.addActionListener(this);
jText = new JTextField("welcome", 20);
add(jText);
}
private static void dButton(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Property");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Property nProp = new Property();
nProp.setOpaque(true);
frame.setContentPane(nProp);
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e){
jText.setText(jButton1.getText());
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
dButton();
}
});
}
}
b. Change properties.
Change properties carry information about the source of a change. We use changeListeners to listen for changeEvents that get fired when these properties change state. ChangeEvents carry only one information, the source of the event.
c. client property
this property is implemented on a list such that for every propertyChange associated with a propertyChangeEvent, a list of propertyChangeListeners sought to notify all listeners for that event that a change has occurred.
Properties of swing components will be discussed in the course of these discussion.
Posted by
cyprian.ekere
at
6:01 AM
0
comments
HOW SWING IMPLEMENTS MVC.
HOW SWING IMPLEMENTS MVC.
Swing packages each component's view and controller into an object called a user interface (UI) delegate, that is why, while reading the online java tutorial you'll be told that swing's architecture is not really MVC but a model-delegate. Model-delegate communication is indirect, like the MVC conception therefore one UI delegate can be associated with more than one model.
The base class of all UI delegates is in the swing pluggable look and feel architecture, i.e javax.swing.plaf.ComponentUI or in brief, ComponentUI class.
Important methods of the ComponentUI class although this class is not invoked directly are:
a. createUI. This method is a static public method and it returns a ComponentUI while accepting a JComponent as its parameter. The method returns an instance of the UI delegate for the specified component. Each subclass of this class must provide a static createUI method.
b. installUI. This method configures the specified component appropriate for the look and feel. Invoked when the ComponentUI instance is being installed as the UI delegate on the specified component. This method completely configures the component for the look and feel.
Read up the above method and others in the api. UI delegate and their use in swing components will be discussed in forthcoming discussions.
In swing, there are sets of UI delegates which contains ComponentUI implementation of most swing components, and each of the sets is called a look and feel or a pluggable look and feel (PLAF). From the api, you'll realize that there are four pluggable look and feel packages, basic, metal, multiplexing and synth. Basic is the set from which every component implements
Posted by
cyprian.ekere
at
5:57 AM
0
comments
MVC ARCHITECTURE:
MVC ARCHITECTURE:
Model view controller, (MVC), is a user interface design decomposition that breaks down components into three parts: a model, a view and a controller.
In this three-way separation model, a mode l is responsible for maintaining all aspects of the component state e.g whether a button was pressed or unpressed, the character data of a text component, the opacity value of a window. A model communicates indirectly with the view and the controller i.e this communication is carried out without the model knowing its view or controller.
The view is the visual representation of the component's model or what is called the “look”. One noticeable example is the font of a character on a button or color of a label. The view receives indirect messages from the model and direct messages from the controller and is responsible for keeping its on-screen representation updated.
The controller is responsible for event management or the reaction of the component to events such as input devices such as the keyboard or mouse. The controller is the “feel” of the component, determining component actions. The controller receives direct messages from the view, and indirect messages from the model.
Let's illustrate the MVC concept: imagine a button with the state unpressed. On the model, this is the state and the view shows a button that is unpressed, idle. If a user clicks on the button, an event received by the controller, the controller translates this as a press or the button sends a direct message to the view, the view now looks “pressed” and send a message to the model to change its state to press = true.
Advantages of the MVC architecture:
1.we can customize the “look”(view) and “feel”(controller) of a component without affect the model.
2.We can customize specific parts of a component without affecting the model.
3.We can customize and replace a component's data model.
If you check the api there are various interfaces for the swing components that implement models and you will find references to the models that are implemented. In the course of the following weeks we will also be implementing this models in our classes for the swing components.
Posted by
cyprian.ekere
at
5:54 AM
0
comments
Z-ORDER IN SWING.
Z-ORDER IN SWING.
According to the api, swing components are lightweight. On the other hand AWT components are heavyweight. The difference between the two terms is z-order i.e the notion of depth or layering.
A heavyweight component occupies its own z-order layer while all lightweight components are contained inside heavyweight components and maintain their own layering scheme as defined by swing. If a heavyweight container is placed inside another heavyweight container, it will, by definition, overlap all lightweights in that container. Therefore, avoid using both heavyweight and lightweight components in the same container wherever possible. Although they can both be mixed one has to be careful while doing so.
Note though that:
1.you should not place heavyweight components inside lightweight containers that commonly support overlapping children.
2.If using popup menus in a container holding a heavyweight component, force that popup to be heavyweight. On the other hand, swing has much functionality that makes the use of AWT heavyweight components really less useful.
One useful reason why swing is preferred over AWT is due to its platform independence. On the other hand there are swing container classes like JApplet, JDialog, JFrame and JWindow which are direct AWT class subclasses that are platform dependent.
Posted by
cyprian.ekere
at
5:53 AM
2
comments
SWING PACKAGE DESCRIPTION:
SWING PACKAGE DESCRIPTION:
Swing components range from the very simple, e.g. JLabel, to the very complex, e.g JTable, JTree. Almost all swing components are derived from a single parent called JComponent which extends the AWT Container class. You now see why swing is called a layer on top of AWT. Top-level containers though like JFrame, JDialogue and JApplet do not inherit from JComponent but rather serve as places where any class that inherits from JComponent can paint itself. We'll explain swing components and the containment hierarchy later.
Am sure you must have realised that every class in swing that compares to an AWT equivalent is prefixed with 'J', this is because all the names have already been taken.
Posted by
cyprian.ekere
at
5:50 AM
0
comments
Labels: components, java, javax, swing
INTRODUCTION TO SWING.
INTRODUCTION TO SWING. (I had to diverge from the JLS to swing because i fell in love with it.)
Each user of an application want to use a software that not only is pleasing to the eyes but which usage is simple to discover. Back in the day, before user interfaces became so glorified, computers were horrible mammoths reserved for just scientists. Today, a youth in a garage can devise glorious graphical functionalities on the internet using ajax and flex and likewise make an application speak with user interfaces, one of them being the java user interface which is not left out in the conference.
Before the swing revolution, the designers of the java language created a set of classes called the abstract window toolkit (AWT) used for creating user interfaces, painting graphics and rendering images on computer screens and other devices. But the AWT had platform compatibility problems that make it frustrating and not up to par with its competition in the user interface space. So back to the drawing board went the designers and they came out with swing, a set of revolutionary user interfaces that along with the java component reusability feature of beans is comparable to the visual modeling capabilities of VB.
Swing is incorporated into the java foundation class or JFC which comprises of AWT, Swing, Accessibility, Java 2D, and Drag and Drop.
Swing is built on top of AWT and the naming of its classes follows the AWT. These two libraries are one the two important libraries any java programmer will never do without.
The swing classes are in the javax.swing package of the api and according to the api, this package provides a set of lightweight components that to the maximum degree possible, work on all platforms.
Posted by
cyprian.ekere
at
5:44 AM
0
comments


