Swing effects
This presentation is the property of its rightful owner.
Sponsored Links
1 / 29

Swing Effects PowerPoint PPT Presentation


  • 78 Views
  • Uploaded on
  • Presentation posted in: General

Swing Effects. Kirill Grouchnikov, Amdocs Desktop Matters Conference San Jose, March 8-9 2007. What is this about?. Show two sample effects on buttons Show how this can be achieved with UI delegates Discuss alternative implementations. Demo. Possible ways to do this.

Download Presentation

Swing Effects

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Swing effects

Swing Effects

Kirill Grouchnikov, Amdocs

Desktop Matters Conference

San Jose, March 8-9 2007


What is this about

What is this about?

Show two sample effects on buttons

Show how this can be achieved with UI delegates

Discuss alternative implementations


Swing effects

Demo


Possible ways to do this

Possible ways to do this

Custom component – paintComponent

Custom repaint manager

Custom glass pane

Custom UI delegates


Possible ways to do this1

Possible ways to do this

Custom component – paintComponent

Custom repaint manager

Custom glass pane

Custom UI delegates (*)

* - next slides describe the UI delegates approach


How does swing paint

How does Swing paint?

UI delegates – classes responsible for painting Swing components.

The panels are painted by the PanelUI delegate (unless a panel overrides the paintComponent method).

The buttons are painted by the ButtonUI delegate (unless a button overrides the paintComponent method).


How is the button painted

How is the button painted?

JComponent

ButtonUI

paint()

paintComponent()

update()

paint()

layout text/icon

paintIcon()

paintText()

paintFocus()

paintBorder() [*]

* - this is why you should override paintComponent() and not paint() for custom painting logic.

paintChildren() [*]


Icon ghosting schematics

Icon ghosting - schematics


Icon ghosting details

Icon ghosting - details

We add the custom painting code in the following places:

ButtonUI.paintIcon – before calling super(), paint the same icon scaled up and translucent (and offset).

PanelUI.update – paint the part of the icon that animates outside the child (button) bounds.

In addition, a ChangeListener is registered on the button model, tracking changes to the rollover state.


What to keep in mind

What to keep in mind?

The icon is not an Image. Call paintIcon after the Graphics has been scaled and a composite has been applied to it.

The ghost image must be centered around the original icon.

The ghost effect may “spill” from the immediate parent and overlay sibling components.


Buttonui code part i

ButtonUI code (part I)

protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect) {

Graphics2D graphics = (Graphics2D) g.create();

FadeTrackerfadeTracker = FadeTracker.getInstance();

AbstractButton b = (AbstractButton) c;

if ((ButtonBackgroundDelegate.getKind(b) == ButtonTitleKind.NONE)

&& fadeTracker.isTracked(c, null,

FadeKind.GHOSTING_ICON_ROLLOVER, true)) {

float fade10 = fadeTracker.getFade10(c,

FadeKind.GHOSTING_ICON_ROLLOVER);

// 0.0 --> 0.5

// 10.0 --> 0.0

floatopFactor = -0.5f * fade10 / 10.0f + 0.5f;

graphics.setComposite(TransitionLayout.getAlphaComposite(c,

opFactor));

Icon icon = SubstanceCoreUtilities.getIcon(b);

if (icon != null) {

 see the next slide

}

}

graphics.setComposite(TransitionLayout.getAlphaComposite(c));

super.paintIcon(graphics, c, iconRect);

graphics.dispose();

}

Check if the button has ghost fade animation on the icon

Get the current animation position (number between 0.0 and 10.0)

Compute the ghost image translucency (fades from 50% to 0% opacity)

Set the composite for painting the ghost icon

Call super implementation to paint the icon itself


Buttonui code part ii

ButtonUI code (part II)

double iFactor = 1.0 + fade10 / 10.0;

double iWidth = icon.getIconWidth() * iFactor;

double iHeight = icon.getIconHeight() * iFactor;

BufferedImageiImage = SubstanceCoreUtilities.getBlankImage(

(int) iWidth, (int) iHeight);

Graphics2D iGraphics = (Graphics2D) iImage.createGraphics();

iGraphics.scale(iFactor, iFactor);

icon.paintIcon(b, iGraphics, 0, 0);

iGraphics.dispose();

intdx = (int) ((iWidth - icon.getIconWidth()) / 2);

intdy = (int) ((iHeight - icon.getIconHeight()) / 2);

graphics.drawImage(iImage, iconRect.x - dx, iconRect.y - dy,

null);

Compute the scale factor and scaled dimensions

Create a transparent image

Scale its graphics

Paint the icon on the scaled graphics (creates the scaled icon)

Paint the scaled icon centered around the original icon


Eye candy

Eye candy

Icon ghosting over multiple components

Press ghosting over multiple components

Multiple icon and press ghostings


Ui delegates pros cons

UI delegates – pros & cons

(+) Minimal changes in the application code.

(+) No need for custom painting code

(+/-) Available only under the specific LAF

Can use bytecode injection to change existing third-party LAFs (possible but slightly complicated – stay tuned for more in the future)

(-) Handling “spilling” is in container delegates

(-) Custom paintComponent implementations


Other approaches

Other approaches

How to handle painting order (background, ghost icon, icon+text)?

Custom components

(+/-) Work under all LAFs (???)

(-) Can handle only painting in the component bounds

Custom repaint manager

(+/-) Work under all LAFs (???)

(-) More complicated to write and test

(-) Interfere with existing repaint manager (e.g. from SwingX)

Custom glass pane

(+/-) Work under all LAFs (???)

(+/-) Interfere with existing app glass pane (JXLayer approach)


Swing effects

Demo


Additional information

Additional information

Kirill’s blog

http://weblogs.java.net/blog/kirillcool

Alex’s blog

http://weblogs.java.net/blog/alexfromsun

Substance LAF project

https://substance.dev.java.net

Laf-Widget project

https://laf-widget.dev.java.net


Swing effects

Q&A

[email protected]


Icon ghosting animation

Icon ghosting animation


Container ui code part i

Container UI code (part I)

@Override

public void update(Graphics g, JComponent c) {

// Paint regular container stuff. In most cases -

// background (fill, gradient, watermark)

// Paint ghost images of the animated overlapping

// components

GhostPaintingUtils.paintGhostImages(c, g);

}


Container ui code part ii

Container UI code (part II)

public static void paintGhostImages(Component mainComponent, Graphics g) {

Graphics2D graphics = (Graphics2D) g.create();

Rectangle panelRect = mainComponent.getBounds();

panelRect.setLocation(mainComponent.getLocationOnScreen());

if (FadeConfigurationManager.getInstance().fadeAllowed(

FadeKind.GHOSTING_ICON_ROLLOVER, mainComponent)) {

Set<Component> animComps = FadeTracker.getInstance()

.getAllComponentsByFadeKind(

FadeKind.GHOSTING_ICON_ROLLOVER);

for (Component comp : animComps) {

// see next slide

}

}

graphics.dispose();

}

Work on disposable graphics context

Compute screen bounds of the container

Check if the icon ghosting animations are allowed

Get all components under icon ghosting animations

For each such component, do code on next slide


Container ui code part iii

Container UI code (part III)

Rectangle compRect = comp.getBounds();

compRect.setLocation(comp.getLocationOnScreen());

intdx = compRect.x - panelRect.x;

intdy = compRect.y - panelRect.y;

compRect.x -= compRect.width / 2;

compRect.y -= compRect.height / 2;

compRect.width *= 2;

compRect.height *= 2;

if (panelRect.intersects(compRect)) {

// see next slide

}

Compute offsets between screen bounds

The icon ghosting can take an area twice as large as the component screen bounds

Check if container screen bounds and extended screen bounds of the animated component intersect

Compute screen bounds of animated component


Container ui code part iv

Container UI code (part IV)

float fade10 = FadeTracker.getInstance().getFade10(comp,

null, FadeKind.GHOSTING_ICON_ROLLOVER);

// 0.0 --> 0.5, 10.0 --> 0.0

float opFactor = 0.5f * (1.0f - fade10 / 10.0f);

graphics.setComposite(TransitionLayout.getAlphaComposite(mainComponent, opFactor));

Icon icon = null;

Rectangle iconRect = null;

if (comp instanceofAbstractButton) {

AbstractButton button = (AbstractButton) comp;

icon = SubstanceCoreUtilities.getIcon(button, false);

iconRect = (Rectangle)button.getClientProperty(SubstanceButtonUI.ICON_RECT);

}

if ((icon != null) && (iconRect != null)) {

// see next slide

}

Compute the ghost image translucency (fades from 50% to 0% opacity)

Get the current animation position

Set the composite for painting the ghost icon

Get the icon and the icon rectangle


Container ui code part v

Container UI code (part V)

double iFactor = 1.0 + fade10 / 10.0;

double iWidth = icon.getIconWidth() * iFactor;

double iHeight = icon.getIconHeight() * iFactor;

BufferedImageiImage = SubstanceCoreUtilities.getBlankImage((int) iWidth, (int) iHeight);

Graphics2D iGraphics = (Graphics2D) iImage.createGraphics();

iGraphics.scale(iFactor, iFactor);

icon.paintIcon(comp, iGraphics, 0, 0);

iGraphics.dispose();

dx -= (int) ((iWidth - icon.getIconWidth()) / 2);

dy -= (int) ((iHeight - icon.getIconHeight()) / 2);

graphics.drawImage(iImage, dx + iconRect.x, dy + iconRect.y, null);

Compute the scale factor and scaled dimensions

Create a transparent image

Scale its graphics

Paint the icon on the scaled graphics (creates the scaled icon)

Paint the scaled icon centered around the original icon (note the computation of icon offsets)


Press ghosting animation

Press ghosting animation


Button press ghosting

Button press ghosting


What to keep in mind1

What to keep in mind?

The ghost image must be centered around the button image.

The ghost effect may “spill” from the immediate parent and overlay sibling components.


Container ui code partial

Container UI code (partial)

doubleiFactor = 1.0 + fade10 / 10.0;

doubleiWidth = bounds.width * iFactor;

doubleiHeight = bounds.height * iFactor;

BufferedImageiImage = SubstanceCoreUtilities.getBlankImage(

(int) iWidth, (int) iHeight);

Graphics2D iGraphics = (Graphics2D)iImage.createGraphics();

iGraphics.scale(iFactor, iFactor);

comp.paint(iGraphics);

iGraphics.dispose();

dx -= (int) ((iWidth - bounds.width) / 2);

dy -= (int) ((iHeight - bounds.height) / 2);

graphics.drawImage(iImage, bounds.x - dx, bounds.y - dy, null);

Paint the scaled component centered around the original component (note the computation of component offsets)

Compute the scale factor and scaled dimensions

Create a transparent image

Scale its graphics

Paint the component on the scaled graphics (creates the scaled component)


Some corner cases

Some corner cases

Not paint too much (trigger repaint only of the affected area)

Handle change in showing / visibility during the animation

Account for large button / icons (start from lower alpha)

Cache animating child image for reuse during painting in the same animation cycle on different containers


  • Login