extending swing: creating your own components · jtable cellrenderer public class weekcellrenderer...

65
Extending Swing: Creating Your Own Components Elie Levy, IT Consultant TS-4982

Upload: others

Post on 30-Jul-2020

20 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

Extending Swing:Creating Your Own Components

Elie Levy, IT Consultant

TS-4982

Page 2: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 2

Learn a process you can follow to create any GUI component using Swing in one hour!

Page 3: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 3

“Example isn't another way to teach, it is the only way to teach”

Albert Einstein

Page 4: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 4

Agenda

Recipe for creating custom components

Apply the Recipe: Case 1 - Composing Existing Components

Apply the Recipe: Case 2 - Start from Scratch

Page 5: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 5

Recipe for Creating a Custom Component

Base for the Component• Compose Existing Components• Start from Scratch

Split the problem into smaller pieces, or objects

For each of the parts:• Identify States and how to paint them• Define Transitions and Animate them when Appropriate

Page 6: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 6

Agenda

Recipe for creating custom components

Apply the Recipe: Case 1 - Composing Existing Components

Apply the Recipe: Case 2 - Starting from Scratch

Page 7: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 7

Custom Component Demo:

Composing Existing Components

Page 8: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 8

Let’s Apply Our Recipe

Base for the Component• We can Reuse the JTable functionality

Split the problem into smaller pieces, or objects:• The JTable is painted using CellRenderers• We can create a CalendarCellRenderer

Page 9: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 9

Using the JTable

Table Header

Page 10: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 10

TableColumnModel model = calendarTable.getColumnModel();TableColumn col = model.getColumn(0);

// The HeaderCellRenderer is an implementation of// the TableCellRenderer interface

col.setHeaderRenderer(new HeaderCellRenderer());

Customizing the JTable Header

Page 11: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 11

Using the JTableEach Cell Has a Renderer: CalendarCellRenderer

Page 12: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 12

JTable CellRenderer

public class WeekCellRenderer extends JPanel implements TableCellRenderer

// get a component that paints the contents of the// cell. Note that this component is NOT added to the// table. It is used only for painting its contents.public Component

getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {

this.activities = (Activity[]) value;this.row = row;this.col = col;this.isSelected = isSelected;return this;

}}

Page 13: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 13

Let’s Apply Our Recipe (Cont.)

Base for the Component• We can Reuse the JTable functionality

Split the problem into smaller pieces, or objects:• CalendarCell

For each of the parts:• Identify States and How to Paint them• Define Transitions and Animate them when Appropriate

Page 14: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 14

We need to paint the Activities for the Day

Activity

Page 15: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 15

Identify States and How to Paint Them:CalendarCellRenderer - Case 1

Activity Starts inCell

Activity FinishesAfter the Cell Boundaries

Page 16: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 16

Identify States and How to Paint Them: CalendarCellRenderer - Case 2

Activity StartsBefore the CellBoundaries

Activity FinishesAfter the Cell Boundaries

Page 17: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 17

Identify States and How to Paint Them: CalendarCellRenderer - Case 3

Activity StartsBefore the CellBoundaries

Activity FinishesBefore Cell Boundaries

Page 18: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 18

Identify States and How to Paint Them: CalendarCellRenderer - Case 4

Activity StartsAfter the CellBoundaries

Activity FinishesBefore Cell Boundaries

Page 19: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 19

Identify States and How to Paint Them: CalendarCellRenderer - Case 5

First ColumnDisplays the TimeCellRenderer

Page 20: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 20

StatePainterpaint();

StatePainter1paint() { ….}

StatePainter2paint() { ….}

StatePainter3paint() { ….}

StatePainter4paint() { ….}

State Design Pattern

Page 21: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 21

State Design Pattern

public interface ActivityStatePainter { public void paint(Graphics g, Activity activity);

}

public class WeekCellRenderer extends JComponent {private ActivityStatePainter statePainter[];

public ActivityStatePainter getStatePainter(Activity a) {// we do a set of if statements to determine// the state painter, and return the one

}}

Page 22: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 22

public class WeekCellRenderer … {

@Overridepublic void paint(Graphics g, Activity a) {

// We iterate over the activities// in the model for the “day”// use the paint that corresponds to the// state we arefor (Activity activity : activities) {

painter = getStatePainter(activity);painter.paint(g,activity);

}}...

}

Page 23: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 23

Custom Component Demo:

Calendar Component Transitions

Page 24: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 24

Defining Transitions

What events are going produce a change of state?

Mouse Move Event MouseMotionListener

We need to determine on what Activity the mouse is located

Page 25: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 25

public class TableMouseListener … {public void mousePressed(MouseEvent event) {

Point p = event.getPoint();int row = table.rowAtPoint(p);int column = table.columnAtPoint(p);WeekCellRenderer tableCellRenderer =

(WeekCellRenderer) table.getCellRenderer(row, column);

Rectangle rect = table.getCellRect(row, column, true);

int x = (int) (event.getX() - rect.getX());int y = (int) (event.getY() - rect.getY());Object value =

tableModel.getValueAt(row, column);tableCellRenderer.selectActivityAt(value,x,y,

row,column);table.repaint();

}}

This codegoes in a methodthat returns astructure with:value,x,y,row,column

Page 26: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 26

public class TableMouseListener … {public void mouseDragged(MouseEvent event) {

// We use the same logic as the previous// slidegetValueXYRowColumn(event);tableCellRenderer.mouseDraggingAt(value,x,y,

row,column);table.repaint();

}}

Page 27: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 27

public class WeekCellRenderer … {public void mouseDraggingAt(…,int row,…) {

int selectedHourFrom = selectedActivity.getFromHour();

if (row+1!=selectedHourFrom) { selectedActivity.setFromHour(row+1);}

}}

Page 28: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 28

Agenda

Recipe for creating custom components

Apply the Recipe: Case 1 - Composing Existing Components

Apply the Recipe: Case 2 - Starting from Scratch

Page 29: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 29

Custom Component Demo:

Starting from Scratch

Page 30: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 30

Introduction to Java Components

Container

Page 31: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 31

Component Container

Introduction to Java Components

Page 32: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 32

Component

Container

Container.add(Component)

Introduction to Java Components

Page 33: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 33

Component

Container

LayoutManager { component.setBounds(..)}

(x,y) width

height

Introduction to Java Components

Page 34: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 34

ContainerComponent 1

Component 2LayoutManager

Graphics

paint()

paint()

Introduction to Java Components

Page 35: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 35

The Secret Recipe to Component Creation

Base for the Component• JPanel: Good for painting in-bounds• GlassPane: Going beyond component boundaries

Page 36: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 36

Base for the Component

Going beyond the component boundaries

Page 37: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 37

The Secret Recipe to Component Creation

Split the problem into smaller pieces, or objects:• The Bar• The Icons

For each of the parts:• Identify States and how to paint them• Define Transitions and Animate them when Appropriate

Base for the Component• JPanel: Good for painting in-bounds• GlassPane: Going beyond component boundaries

Page 38: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 38

Identify States

There are 4 states for an Icon:

Observation: The state of an Icon depends on the location of the mouse

2 3 4 3 2 1 1 1 1 1

Page 39: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 39

public class IconOnBar {// find an appropriate way of representing the stateprivate int state;

private BufferedImage image;public BufferedImage getResizedIcon() { … }

public Dimension calculateCurrentSize() {return new Dimension(image.getWidth()*state,

image.getHeight()*state);}

}

IconOnBar: Work in progress...

Page 40: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 40

There are also 4 states for the bar:

Identify States

Page 41: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 41

public class DockBar {// find an appropriate way of representing the stateprivate int currentWidth;public int calculateCurrentWidth() {

int currentWidth = 0;for (IconOnBar iconOnBar : iconsOnBar) {

Dimension iconSize = iconOnBar.calculateCurrentSize();

currentWidth += iconSize.getWidth() + SPACE;}return currentWidth;

}}

DockBar: Work in progress...

Page 42: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 42

Defining Transitions

What events are going produce a change of state?

So far, In the Dock Bar?

Mouse Move Event MouseMotionListener

We need to determine on what Icon the mouse is located

Page 43: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 43

public void mouseMoved(MouseEvent e) {...for (IconOnBar iconOnBar : iconsOnBar) {

Rectangle iconRect = iconOnBar.calculateCurrentRect();

if ((!iconOnBar.equals(glass.getLastMouseOver())&& (iconRect.contains(e.getPoint())) {

iconOnBar.mouseEntered();glass.setLastMouseOver(iconOnBar);return;

}}...

}

Page 44: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 44

How does the painting happens?

public class DockBarGlassPane extends JPanel { public void paintComponent(Graphics g) {

paintBar(g);paintIcons(g);

}

public void paintBar(Graphics g) {int width = bar.getCurrentWidth();// we generate the bar image (in a few slides)// using the current width// then its just:g.drawImage(barImage,x,y,width,height);

}...

}

Page 45: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 45

How does the painting happens? (Cont.)

public class DockBarGlassPane extends JPanel { ...public void paintIcons(Graphics g) {

for (IconOnBar iconOnBar : iconsOnBar) {Rectangle = iconOnBar.getCurrentRect();

// we generate the icon image (in a few slides)// using the current width// then its just:

g.drawImage(iconImage,x,y,width,height);}...

}

Page 46: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 46

How do we make the transition continuous?

Answer: Animations!

Page 47: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 47

My First Animations...

Page 48: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 48

We will use the Timing Framework:

https://timingframework.dev.java.net/

Page 49: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 49

Timing Framework

Animations based on “Time”• State changes based on time

Not a sequence of steps

Takes care of different environments and machines

How does it do it?

• It calls back with the progress of the animation

Page 50: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 50

Making Smooth Transitions:Timing Framework in Action

public void startTransition() {transitionAnimator =

PropertySetter.createAnimator(400, glass, “progress”, 0f, 1f);

transitionAnimator.setAcceleration(0.3f);transitionAnimator.setDeceleration(0.2f);transitionAnimator.start();

}public void setProgress(float progress) {

this.progress = progress;repaint();

}

Page 51: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 51

Making Smooth Transitions

public class IconOnBar {// we keep track of the previous stateprivate int oldState;private int currentState;// Because all the painting code looks at this// method for the size, no more changes are necessarypublic Dimension calculateCurrentSize() {

float progress = dock.getTransitionProgress();float proportion = oldState +

(currentState - oldState)*progressint w = width * proportion;int h = height * proportion;return new Dimension(w,h);

}

}

Page 52: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 52

Painting the Icons on the Bar

We have reflectionin the bar

We paint a Labelfor the Icon when theMouse is over it

Simple paintingof the imageusing the “current size”

Page 53: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 53

Painting the Icons on the Bar (Cont.)

public class IconOnBar {private BufferedImage icon;private BufferedImage mirror;

public IconOnBar(String label, BufferedImage icon) {

this.label = label;this.icon = icon;ReflectionRenderer renderer =

new ReflectionRenderer();mirror = renderer.createReflection(icon);

}}

Page 54: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 54

Painting the Icons on the Bar (Cont.)public void paintComponent(Graphics g) {

…g.setColor(Color.BLACK);g.drawStrasding(iconOnBar.getLabel(),

labelX + 1, labelY + 1);g.drawString(iconOnBar.getLabel(),

labelX - 1, labelY - 1);g.drawString(iconOnBar.getLabel(),

labelX - 1, labelY + 1);g.drawString(iconOnBar.getLabel(),

labelX + 1, labelY);g.drawString(iconOnBar.getLabel(),

labelX, labelY - 1);g.drawString(iconOnBar.getLabel(),

labelX, labelY + 1);g.setColor(Color.white);g.drawString(iconOnBar.getLabel(), labelX, labelY);

}}

Page 55: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 55

Painting the Bar:

2px

+

Java 2D Shape withAntialias RoundCorners

AlphaComposite SrcAtop

Gradient Paint forFilling the Background

Page 56: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 56

Painting the Bar: Gradient

// We create a gradient image of only 2 pixels heightBufferedImage gradientImage =

new BufferedImage(width, 2, BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = gradientImage.createGraphics();Point2D start = new Point2D.Double(15, 0);Point2D end = new Point2D.Double(width, 0);float fractions[] = new float[] { 0f, 0.5f, 1 };LinearGradientPaint paint =

new LinearGradientPaint(start, end,fractions, colors);

g2d.setPaint(paint);g2d.fillRect(0, 0, width, 2);g2d.dispose();

Page 57: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 57

Painting the Bar

// We create a Shape with Round CornersShape rpolygon = new RoundShape(polygon, 5);// All image with zero alphag2d.setComposite(AlphaComposite.Clear);g2d.fillRect(0, 0, width, dockBar.getHeight());// Render our shape into the imageg2d.setComposite(AlphaComposite.Src);g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);g2d.setColor(Color.WHITE);g2d.fill(rpolygon);// fill the shape with the gradientg2d.setComposite(AlphaComposite.SrcAtop);g2d.drawImage(gradientImage, 0, 0, width,

dockBar.getHeight(),null);

Page 58: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 58

Custom Component Demo:

Bouncing Effect

Page 59: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 59

Bouncing Physics Equation

Did you believe that?

Page 60: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 60

Identify States: Bouncing

public class IconOnBar {// New State Information:private float bouncingProgress;public Rectange calculateCurrentRect() {

…y = regularY - bouncingProgress*height;…

}

public Rectangle calculateMirrorRect() {…y = regularY + bouncingProgress*height;…

}}

Page 61: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 61

Defining the Transition

// These are the different heights the icon will bounce tofloat heights[] = new int[] { 3f, 2f, 1f, 0.5f };for (int i=0;i<4;++i) {

animator[i] = PropertySetter.createAnimator(400, this, ”progress", 0f, heights[i]);animator[i].setRepeatCount(2); animator[i].setRepeatBehavior(RepeatBehavior.REVERSE);// To make it feel realistic we use gravityanimator[i].setAceleration(0.98f);

}// We make every animator start after the previous finishedfor (int i=1;i<4;++i)

TimingTrigger.addTrigger(animator[i-1], animator[i], TimingTriggerEvent.STOP);

Page 62: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 62

Custom Component Demo:

Everything Fits Together

Page 63: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 63

Summary

Base for the Component• Compose Existing Components• Start from Scratch

Split the problem into smaller pieces, or objects

For each of the parts:• Identify States and how to paint them• Define Transitions and Animate them when Appropriate

Page 64: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 64

For More Information

Interesting Sessions:• Extreme GUI Makeover: Swing Meets FXCross-references to other

sessions (TS-6656 @ 13:30 -14:30) Christopher Campbell, and Shannon Hickey

• Nimbus: The New Face of Swing (TS-6096 @10:50 AM -11:50 AM) Richard Bair, Jasper Potts

• Extreme GUI Makeover: In the Real World (TS-6656 @ 1:30 PM -2:30 PM) Christopher Campbell

• Filthy-Rich Clients: Filthier, Richer, Clientier (TS-6611 @ 4:10 PM -5:10 PM) Romain Guy, Chet Haase

My Blog:• http://weblogs.java.net/blog/elevy/

Page 65: Extending Swing: Creating Your Own Components · JTable CellRenderer public class WeekCellRenderer extends JPanel implements TableCellRenderer // get a component that paints the contents

2008 JavaOneSM Conference | java.sun.com/javaone | 65

Elie Levy, IT Consultant

TS-4982