RomainsPowerPoint

Uploaded from authorPOINTLite
Views:
 
Category: Entertainment
     
 

Presentation Description

No description available.

Comments

Presentation Transcript

Swing and Java2D in Action: 

Swing and Java2D in Action Romain Guy Swing Team Sun Microsystems

Agenda: 

Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going further

Agenda: 

Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going further

Why Should I Even Bother?: 

Why Should I Even Bother? Better user experience Eye candy sells... ...and brings better ergonomics Professional polish Ask yourself: "Why am I using JGoodies?" It's a lot of fun It's not that hard I mean it!

The Sky is the Limit: 

The Sky is the Limit Swing toolkit Highly flexible Every component can be customized Built on top Java2D Java2D Comprehensive, high quality drawing API Extensible architecture Device abstraction Painting can occur on screen, on a printer, in a PDF... Hardware acceleration

Java2D Rocks: 

Java2D Rocks Olden days Graphics class g.fillRect(x, y, width, height) g.drawLine(x1, y1, x2, y2) Graphics2D Object Oriented g2.draw(Shape), g2.fill(Shape) A Shape is a Rectangle2D, Ellipse2D, Line2D… Advanced features Painters, composites, strokes…

Agenda: 

Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going further

Glass Pane Magic: 

Glass Pane Magic Applications perform tasks of unknown duration Possible solutions Show the hourglass cursor Use an indeterminate JProgressBar (damn Cylon!) Disable components They work and they're not pretty The solution of the modern man Use the glass pane Use a circular shape (after all, Apple does it)

Glass Pane Magic: 

Glass Pane Magic What is the glass pane?

DEMO Infinite Progress Panel: 

DEMO Infinite Progress Panel

Glass Pane Magic: 

Glass Pane Magic First, create your own glass pane Extends JComponent, JPanel... And setOpaque()? public class InfiniteProgressPanel extends JComponent { @Override protected void paintComponent(Graphics g) { g.setColor(new Color(255, 255, 255, alphaLevel)); g.fillRect(0, 0, getWidth(), getHeight()); // paint the rest } }

Glass Pane Magic: 

Glass Pane Magic Then, block the input Focus can be requested only when visible public class InfiniteProgressPanel extends JComponent { public void setVisible(boolean visible) { if (visible) { setFocusTraversalKeysEnabled(false); addMouseListener(new MouseAdapter() { }); addMouseMotionListener(new MouseMotionAdapter() { }); addKeyListener(new MouseAdapter() { }); super.setVisible(true); requestFocusInWindow(); } else { // undo } } }

Glass Pane Magic: 

Glass Pane Magic Finally, install your glass pane Remember, a glass pane is invisible when installed http://swingfx.dev.java.net public WootDemo extends JFrame implements ActionListener { public WootDemo() { super("w00t"); setGlassPane(new InfiniteProgressPanel()); } public void actionPerformed(ActionEvent evt) { getGlassPane().setVisible(true); } }

More Glass Pane Magic: 

More Glass Pane Magic http://www.jroller.com/page/gfx/Archives Jon Lipsky: http://blog.elevenworks.com/?p=7

Agenda: 

Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going further

Animation: 

Animation Why are animations useful? The GUI appears more responsive Better visual feedback about what's going on Transitions are more realistic How to create animations? javax.swing.Timer Chet's Timing Framework Karsten's JGoodies Animation library

DEMO Drop in Motion: 

DEMO Drop in Motion

Animation Timer: 

Animation Timer Create a timer This one runs at 60 fps Create the handler private void startAnimation() { Timer animation = new Timer(1000 / 60, new Animation()); animation.start(); } private class Animation implements ActionListener { public void actionPerformed(ActionEvent evt) { } }

Animation Handler: 

Animation Handler Timing is not guaranteed Timer resolution is platform dependent Massive CPU usage can affect the timer Do not play one animation frame per event received Know where you are in time f(elapsed time) -> [0, 1] Very often, one cycle, no repeat f(elapsed time) = elapsed time / duration

Animation Handler: 

Animation Handler private long start; private boolean isInitialized; private Animation() { isInitialized = false; } public void actionPerformed(ActionEvent e) { if (!isInitialized) { start = System.currentTimeMillis(); isInitialized = true; } long elapsed = System.currentTimeMillis() - start; if (elapsed > DELAY_ANIMATION) { ((Timer) e.getSource()).stop(); } else { double time = (double) elapsed / (double) DELAY_ANIMATION; // ... repaint(); } }

Animation Behavior: 

Animation Behavior The time value does not work well for movement We need our position in space g(f(elapsed time)) -> [0, 1] Now we can draw Icon is resized Shadow is resized Shadow's distance changes Shadow's opacity changes

DEMO Drop in Motion, Equation: 

DEMO Drop in Motion, Equation

Animation Behavior: 

Animation Behavior To draw with our cool equation private void drawItem(Graphics2D g2) { double position = equation.compute(time); float alpha = 1.0f - (0.5f * (float) position); Composite old = g2.getComposite(); Composite c = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha); g2.setComposite(c); // draw shadow first g2.setComposite(old); int width = (int) (image.getWidth() / 2 * (1.0 + position)); int height = (int) (image.getHeight() / 2 * (1.0 + position)); g2.drawImage(image, dropX, dropY, width, height, null); }

Animation Timer Drawbacks: 

Animation Timer Drawbacks A lot of boilerplate Complex animations are difficult Many cycles Back and forth Repeat Chet's Timing Framework Handles everything for you JGoodies Animation Makes simple animations easy Go see him on Thursday

Agenda: 

Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going further

DEMO Photo Collage: 

DEMO Photo Collage

Photo Collage Drag and Drop: 

Photo Collage Drag and Drop Everything is done on the glass pane A non opaque JPanel The glass pane must Draw a specific picture At a given position Drag source and drop targets Set the picture with glassPane.setImage() Set the position with glassPane.setPosition()

Photo Collage Drag and Drop: 

Photo Collage Drag and Drop Performance issues can be tricky Call to repaint() is expensive public void setPoint(Point location) { this.oldLocation = this.location; this.location = location; } public Rectangle getRepaintRect() { int x = location.getX(); int y = location.getY(); int x2 = oldLocation.getX(); int y2 = oldLocation.getY(); Rectangle oldPic = new Rectangle(x2, y2, width, height); return new Rectangle(x, y, width, height).union(oldPic); }

Photo Collage Drag and Drop: 

Photo Collage Drag and Drop On mouse move, call repaint(Rectangle) public void dragMouseMoved(DragSourceDragEvent dsde) { JRootPane root = SwingUtilities.getRootPane(this); GhostGlassPane glassPane = (GhostGlassPane) root.getGlassPane(); Point p = (Point) dsde.getLocation().clone(); SwingUtilities.convertPointFromScreen(p, glassPane); glassPane.setPoint(p); glassPane.repaint(glassPane.getRepaintRect()); }

Photo Collage Performance Tips: 

Photo Collage Performance Tips Use compatible images JPEG pictures might not be compatible Performance increased by a factor of 20 public static BufferedImage createCompatibleImage(BufferedImage image) { GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice d = e.getDefaultScreenDevice(); GraphicsConfiguration c = d.getDefaultConfiguration(); BufferedImage compatibleImage = c.createCompatibleImage(image.getWidth(), image.getHeight()); Graphics g = compatibleImage.getGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); return compatibleImage; }

Photo Collage Performance Tips: 

Photo Collage Performance Tips Never call getScaledInstance(), use drawImage() Software vs Hardware Control the rendering quality double ratio = (double) image.getWidth() / (double) image.getHeight(); int width = ITEM_WIDTH; int height = (int) (width / ratio); g2.drawImage(image, x, y, width, height, null); g2.setRenderingHint(RenderingHint.KEY_INTERPOLATION, RenderingHint.VALUE_INTERPOLATION_BILINEAR);

Photo Collage Image Tip: 

Photo Collage Image Tip Bilinear and bicubic resizing are not perfect When scaling down more than half the size Proceed step by step Technique similar to mipmapping in games Resizing demo One uses drawImage() and bilinear interpolation One uses a custom resize method

DEMO Photo Collage, Resizing : 

DEMO Photo Collage, Resizing

Photo Collage Image Tip: 

Photo Collage Image Tip public static BufferedImage createThumbnail(BufferedImage image, int thumbWidth) { int width = image.getWidth(); float ratio = (float) width / (float) image.getHeight(); BufferedImage thumb = image; do { width /= 2; // ... BufferedImage temp = new BufferedImage(width, (int) (width / ratio), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = temp.createGraphics(); g2.setRenderingHint(...); g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null); g2.dispose(); thumb = temp; } while (width != thumbWidth); return thumb; }

Photo Collage Image Tip: 

Photo Collage Image Tip It is not slower! Well, not that much ~= 15ms vs ~= 5ms for 640x480 You can cache the result Much faster than getScaledInstance() Looks better than a simple drawImage()

Agenda: 

Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going further

FX: Going Further: 

FX: Going Further Extreme GUI Makeover, JavaOne 2005 TS-3605 http://developers.sun.com/learning/javaoneonline/ Jon Lipsky's blog http://blog.elevenworks.com/ Romain Guy's blogs http://jroller.com/page/gfx http://weblogs.java.net/blog/gfx Chet’s timing framework http://timingframework.dev.java.net