logging in or signing up RomainsPowerPoint Teodora Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINTLite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 428 Category: Entertainment License: All Rights Reserved Like it (1) Dislike it (0) Added: January 09, 2008 This Presentation is Public Favorites: 0 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Swing and Java2D in Action: Swing and Java2D in Action Romain Guy Swing Team Sun MicrosystemsAgenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherAgenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherWhy 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 accelerationJava2D 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 furtherGlass 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?DEMOInfinite Progress Panel: DEMO Infinite Progress PanelGlass 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=7Agenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherAnimation: 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 libraryDEMODrop in Motion: DEMO Drop in MotionAnimation 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 / durationAnimation 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 changesDEMODrop in Motion, Equation: DEMO Drop in Motion, EquationAnimation 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 ThursdayAgenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherDEMOPhoto Collage: DEMO Photo CollagePhoto 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 methodDEMOPhoto 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 furtherFX: 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 You do not have the permission to view this presentation. In order to view it, please contact the author of the presentation.
RomainsPowerPoint Teodora Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINTLite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 428 Category: Entertainment License: All Rights Reserved Like it (1) Dislike it (0) Added: January 09, 2008 This Presentation is Public Favorites: 0 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Swing and Java2D in Action: Swing and Java2D in Action Romain Guy Swing Team Sun MicrosystemsAgenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherAgenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherWhy 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 accelerationJava2D 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 furtherGlass 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?DEMOInfinite Progress Panel: DEMO Infinite Progress PanelGlass 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=7Agenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherAnimation: 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 libraryDEMODrop in Motion: DEMO Drop in MotionAnimation 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 / durationAnimation 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 changesDEMODrop in Motion, Equation: DEMO Drop in Motion, EquationAnimation 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 ThursdayAgenda: Agenda Introduction Glass pane magic Animation Photo Collage Combining animations and glass pane magic Performance tips Going furtherDEMOPhoto Collage: DEMO Photo CollagePhoto 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 methodDEMOPhoto 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 furtherFX: 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