Java tutorial
// From Romain Guy's Weblog romain.guy@mac.com // import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Paint; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.net.URL; import java.util.HashMap; import javax.media.j3d.Alpha; import javax.media.j3d.Appearance; import javax.media.j3d.Background; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.ImageComponent2D; import javax.media.j3d.PolygonAttributes; import javax.media.j3d.RotationInterpolator; import javax.media.j3d.Shape3D; import javax.media.j3d.Texture; import javax.media.j3d.Texture2D; import javax.media.j3d.TextureAttributes; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.media.j3d.View; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import com.sun.j3d.utils.image.TextureLoader; import com.sun.j3d.utils.universe.SimpleUniverse; public class BooksDemo extends JFrame { private static final int CANVAS3D_WIDTH = 400; private static final int CANVAS3D_HEIGHT = 400; private boolean front = true; private JPanel xpanel = new JPanel(); private Canvas3D c3d; private RotationInterpolator rotator1; private Alpha rotor1Alpha; private com.sun.j3d.utils.geometry.Box book; private HashMap textures = new HashMap(6); public BooksDemo() { super("AmazonPick"); JButton cover1 = UIHelper.createButton("", "cover1_small_button", true); cover1.addActionListener(new CoverSwitcher("cover1")); JButton cover2 = UIHelper.createButton("", "cover2_small_button", true); cover2.addActionListener(new CoverSwitcher("cover2")); JButton cover3 = UIHelper.createButton("", "cover3_small_button", true); cover3.addActionListener(new CoverSwitcher("cover3")); JPanel buttons = new JPanel(); buttons.add(cover1); buttons.add(cover2); buttons.add(cover3); buttons.setOpaque(false); c3d = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); c3d.setSize(CANVAS3D_WIDTH, CANVAS3D_HEIGHT); xpanel.add(c3d); xpanel.setOpaque(false); this.setContentPane(new GradientPanel()); this.getContentPane().setLayout(new BorderLayout()); this.getContentPane().add(xpanel, BorderLayout.CENTER); this.getContentPane().add(buttons, BorderLayout.SOUTH); this.pack(); this.setResizable(false); this.setDefaultCloseOperation(EXIT_ON_CLOSE); UIHelper.centerOnScreen(this); } private boolean isBookShowingFront() { return front; } private void rotateBook() { if (!isBookShowingFront()) { rotator1.setMinimumAngle((float) Math.PI * 1.0f); rotator1.setMaximumAngle(0.0f); } else { rotator1.setMinimumAngle(0.0f); rotator1.setMaximumAngle((float) Math.PI * 1.0f); } front = !front; rotor1Alpha.setStartTime(System.currentTimeMillis()); } private class CoverSwitcher implements ActionListener { private String coverName; CoverSwitcher(String coverName) { this.coverName = coverName; } public void actionPerformed(ActionEvent evt) { book.getShape(isBookShowingFront() ? book.BACK : book.FRONT) .setAppearance((Appearance) textures.get(coverName)); rotateBook(); } } public void createScene() { BufferedImage image = new BufferedImage(xpanel.getWidth(), xpanel.getHeight(), BufferedImage.TYPE_INT_RGB); getContentPane().paint(image.getGraphics()); BufferedImage subImage = new BufferedImage(CANVAS3D_WIDTH, CANVAS3D_HEIGHT, BufferedImage.TYPE_INT_RGB); ((Graphics2D) subImage.getGraphics()).drawImage(image, null, -c3d.getX(), -c3d.getY()); Background bg = new Background(new ImageComponent2D(ImageComponent2D.FORMAT_RGB, subImage)); BoundingSphere bounds = new BoundingSphere(); bounds.setRadius(100.0); bg.setApplicationBounds(bounds); BranchGroup objRoot = new BranchGroup(); objRoot.addChild(bg); TransformGroup objTg = new TransformGroup(); objTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); Transform3D yAxis = new Transform3D(); rotor1Alpha = new Alpha(1, 400); rotator1 = new RotationInterpolator(rotor1Alpha, objTg, yAxis, (float) Math.PI * 1.0f, (float) Math.PI * 2.0f); rotator1.setSchedulingBounds(bounds); textures.put("pages_top", createTexture("pages_top.jpg")); textures.put("pages", createTexture("amazon.jpg")); textures.put("amazon", createTexture("amazon.jpg")); textures.put("cover1", createTexture("cover1.jpg")); textures.put("cover2", createTexture("cover2.jpg")); textures.put("cover3", createTexture("cover3.jpg")); book = new com.sun.j3d.utils.geometry.Box(0.5f, 0.7f, 0.15f, com.sun.j3d.utils.geometry.Box.GENERATE_TEXTURE_COORDS, new Appearance()); book.getShape(book.TOP).setAppearance((Appearance) textures.get("pages_top")); book.getShape(book.RIGHT).setAppearance((Appearance) textures.get("pages")); book.getShape(book.LEFT).setAppearance((Appearance) textures.get("amazon")); book.getShape(book.FRONT).setAppearance((Appearance) textures.get("cover1")); book.getShape(book.BACK).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); book.getShape(book.FRONT).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); // book.getShape(book.LEFT).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); // book.getShape(book.RIGHT).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); objTg.addChild(book); objTg.addChild(rotator1); Transform3D spin = new Transform3D(); Transform3D tempspin = new Transform3D(); spin.rotX(Math.PI / 8.0d); tempspin.rotY(Math.PI / 7.0d); spin.mul(tempspin); TransformGroup objTrans = new TransformGroup(spin); objTrans.addChild(objTg); objRoot.addChild(objTrans); SimpleUniverse u = new SimpleUniverse(c3d); u.getViewingPlatform().setNominalViewingTransform(); u.addBranchGraph(objRoot); View view = u.getViewer().getView(); view.setSceneAntialiasingEnable(true); } private Appearance createTexture(String fileName) { Image sourceImage = UIHelper.readImage(fileName); if (sourceImage == null) System.out.println("Image could not be loaded from " + fileName); TextureLoader loader = new TextureLoader(sourceImage, this); ImageComponent2D image = loader.getImage(); if (image == null) System.out.println("Texture could not be loaded from " + fileName); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, image.getWidth(), image.getHeight()); texture.setImage(0, image); texture.setEnable(true); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); Appearance appearance = new Appearance(); PolygonAttributes polyAttributes = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0f); appearance.setPolygonAttributes(polyAttributes); appearance.setTexture(texture); TextureAttributes textureAttributes = new TextureAttributes(); appearance.setTextureAttributes(textureAttributes); return appearance; } private static class GradientPanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); if (!isOpaque()) { return; } int width = getWidth(); int height = getHeight(); Graphics2D g2 = (Graphics2D) g; Paint storedPaint = g2.getPaint(); g2.setPaint(new GradientPaint(0, 0, Color.WHITE, width, height, new Color(200, 200, 200))); g2.fillRect(0, 0, width, height); g2.setPaint(storedPaint); } } public static void main(String argv[]) { final BooksDemo xframe = new BooksDemo(); xframe.setVisible(true); SwingUtilities.invokeLater(new Runnable() { public void run() { xframe.createScene(); } }); } } final class UIHelper { public static JButton createButton(String text) { JButton button = new JButton(text); button.setFocusPainted(true); button.setBorderPainted(true); button.setContentAreaFilled(true); return button; } public static JButton createButton(String text, String icon) { return createButton(text, icon, false); } public static JButton createButton(String text, String icon, boolean flat) { ImageIcon iconNormal = readImageIcon(icon + ".png"); ImageIcon iconHighlight = readImageIcon(icon + "_highlight.png"); ImageIcon iconPressed = readImageIcon(icon + "_pressed.png"); JButton button = new JButton(text, iconNormal); button.setFocusPainted(!flat); button.setBorderPainted(!flat); button.setContentAreaFilled(!flat); if (iconHighlight != null) { button.setRolloverEnabled(true); button.setRolloverIcon(iconHighlight); } if (iconPressed != null) button.setPressedIcon(iconPressed); return button; } public static void centerOnScreen(Component component) { Dimension paneSize = component.getSize(); Dimension screenSize = component.getToolkit().getScreenSize(); component.setLocation((screenSize.width - paneSize.width) / 2, (screenSize.height - paneSize.height) / 2); } public static ImageIcon readImageIcon(String fileName) { Image image = readImage(fileName); if (image == null) return null; return new ImageIcon(image); } public static Image readImage(String fileName) { URL url = UIHelper.class.getResource("images/" + fileName); if (url == null) return null; return java.awt.Toolkit.getDefaultToolkit().getImage(url); } }