001: /*
002: * $Header: /cvs/j3dfly/J3dEditor/src/org/jdesktop/j3dedit/scenegrapheditor/nodeeditors/panels/TexturePanel.java,v 1.1 2005/04/20 22:21:11 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is the Java 3D(tm) Scene Graph Editor.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dedit.scenegrapheditor.nodeeditors.panels;
019:
020: import javax.media.j3d.*;
021: import com.sun.j3d.utils.image.TextureLoader;
022: import java.awt.image.BufferedImage;
023: import java.awt.Graphics;
024: import java.awt.Dimension;
025: import java.awt.Cursor;
026: import java.io.File;
027: import org.jdesktop.j3dedit.scenegraph.SGNodeComponent;
028: import org.jdesktop.j3dedit.scenegraph.SGAppearance;
029: import org.jdesktop.j3dedit.scenegraph.SGTexture;
030: import org.jdesktop.j3dedit.scenegraph.SGTextureAttributes;
031:
032: import org.jdesktop.j3dedit.scenegrapheditor.nodeeditors.NodeComponentEditorPanel;
033: import org.jdesktop.j3dedit.scenegrapheditor.WindowManager;
034: import org.jdesktop.j3dfly.utils.loadercontrol.ExampleFileFilter;
035: import org.jdesktop.j3dedit.scenegrapheditor.nodeeditors.SGObjectExtraData;
036:
037: /**
038: * A Simple Texture editor panel. This panel allows users to create a Texture
039: * and will automatically create an associated TextureAttribute is required in
040: * the appearance.
041: *
042: * TODO - Add ability to remove the Texture object
043: *
044: * TODO - When textures are created a single Appearance is assumed, this is OK,
045: * but we need to plan more carefully when we remove the textures.
046: * The SGNodeComponent tracks a list of nodes[components] which Reference
047: * another node component.
048: *
049: * TODO - Handle Multi Textures
050: *
051: * @author Paul Byrne
052: * @version $Id: TexturePanel.java,v 1.1 2005/04/20 22:21:11 paulby Exp $
053: */
054: public class TexturePanel extends NodeComponentEditorPanel {
055:
056: private boolean origTextureEnabled;
057: private Texture origTexture;
058:
059: private TextureAttributesPanel textureAttributesPanel;
060:
061: private TextureLoader textureLoader;
062: private java.net.URL imageURL;
063: private TextureImagePanel imagePanel;
064: private boolean doingSetControls = false;
065: private ExampleFileFilter fileFilter = new ExampleFileFilter(
066: new String[] { "gif", "jpg" }, "Texture Images");
067: private java.awt.CardLayout cardLayout;
068:
069: public TexturePanel() {
070: super ();
071: initComponents();
072: imagePanel = new TextureImagePanel();
073: texturePreview.getViewport().add(imagePanel);
074: cardLayout = (java.awt.CardLayout) getLayout();
075:
076: }
077:
078: protected void setTextureAttributesPanel(
079: TextureAttributesPanel panel) {
080: textureAttributesPanel = panel;
081: }
082:
083: public void setReadOnly(boolean readOnly) {
084: this .readOnly = readOnly;
085:
086: createTextureB.setEnabled(!readOnly);
087: textureEnabledCB.setEnabled(!readOnly);
088: loadImageB.setEnabled(!readOnly);
089: }
090:
091: /** This method is called from within the constructor to
092: * initialize the form.
093: * WARNING: Do NOT modify this code. The content of this method is
094: * always regenerated by the FormEditor.
095: */
096: private void initComponents() {//GEN-BEGIN:initComponents
097: java.awt.GridBagConstraints gridBagConstraints;
098:
099: normalPanel = new javax.swing.JPanel();
100: jPanel1 = new javax.swing.JPanel();
101: loadImageB = new javax.swing.JButton();
102: texturePreview = new javax.swing.JScrollPane();
103: textureEnabledCB = new javax.swing.JCheckBox();
104: ncCommonP = new org.jdesktop.j3dedit.scenegrapheditor.nodeeditors.panels.CommonNodeComponentPanel();
105: jLabel2 = new javax.swing.JLabel();
106: mipmapLevelsTF = new javax.swing.JTextField();
107: nullPanel = new javax.swing.JPanel();
108: jPanel2 = new javax.swing.JPanel();
109: jLabel1 = new javax.swing.JLabel();
110: createTextureB = new javax.swing.JButton();
111:
112: setLayout(new java.awt.CardLayout());
113:
114: jPanel1.setLayout(new java.awt.GridBagLayout());
115:
116: loadImageB.setText("Load Image");
117: loadImageB
118: .addActionListener(new java.awt.event.ActionListener() {
119: public void actionPerformed(
120: java.awt.event.ActionEvent evt) {
121: loadImageBActionPerformed(evt);
122: }
123: });
124:
125: gridBagConstraints = new java.awt.GridBagConstraints();
126: gridBagConstraints.gridx = 0;
127: gridBagConstraints.gridy = 1;
128: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
129: jPanel1.add(loadImageB, gridBagConstraints);
130:
131: texturePreview.setMinimumSize(new java.awt.Dimension(50, 50));
132: texturePreview
133: .setPreferredSize(new java.awt.Dimension(100, 100));
134: gridBagConstraints = new java.awt.GridBagConstraints();
135: gridBagConstraints.gridx = 1;
136: gridBagConstraints.gridy = 1;
137: gridBagConstraints.gridheight = 2;
138: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
139: jPanel1.add(texturePreview, gridBagConstraints);
140:
141: textureEnabledCB.setText("Texture Enabled");
142: textureEnabledCB
143: .addActionListener(new java.awt.event.ActionListener() {
144: public void actionPerformed(
145: java.awt.event.ActionEvent evt) {
146: textureEnabledCBActionPerformed(evt);
147: }
148: });
149:
150: gridBagConstraints = new java.awt.GridBagConstraints();
151: gridBagConstraints.gridx = 0;
152: gridBagConstraints.gridy = 2;
153: jPanel1.add(textureEnabledCB, gridBagConstraints);
154:
155: gridBagConstraints = new java.awt.GridBagConstraints();
156: gridBagConstraints.gridx = 0;
157: gridBagConstraints.gridy = 0;
158: gridBagConstraints.gridwidth = 2;
159: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
160: jPanel1.add(ncCommonP, gridBagConstraints);
161:
162: jLabel2.setText("Mipmap levels");
163: gridBagConstraints = new java.awt.GridBagConstraints();
164: gridBagConstraints.gridx = 0;
165: gridBagConstraints.gridy = 3;
166: gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
167: gridBagConstraints.insets = new java.awt.Insets(8, 0, 0, 4);
168: jPanel1.add(jLabel2, gridBagConstraints);
169:
170: mipmapLevelsTF.setColumns(3);
171: mipmapLevelsTF.setEditable(false);
172: gridBagConstraints = new java.awt.GridBagConstraints();
173: gridBagConstraints.gridx = 1;
174: gridBagConstraints.gridy = 3;
175: gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
176: jPanel1.add(mipmapLevelsTF, gridBagConstraints);
177:
178: normalPanel.add(jPanel1);
179:
180: add(normalPanel, "card4");
181:
182: jLabel1.setFont(new java.awt.Font("Dialog", 1, 14));
183: jLabel1.setText("Texture is Null");
184: jPanel2.add(jLabel1);
185:
186: createTextureB.setText("Create Texture");
187: createTextureB
188: .setToolTipText("Create a Texture Object, with a default image");
189: createTextureB
190: .addActionListener(new java.awt.event.ActionListener() {
191: public void actionPerformed(
192: java.awt.event.ActionEvent evt) {
193: createTextureBActionPerformed(evt);
194: }
195: });
196:
197: jPanel2.add(createTextureB);
198:
199: nullPanel.add(jPanel2);
200:
201: add(nullPanel, "card5");
202:
203: }//GEN-END:initComponents
204:
205: private void createTextureBActionPerformed(
206: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createTextureBActionPerformed
207: // Add your handling code here:
208: Texture texture = new Texture2D(Texture.BASE_LEVEL,
209: Texture.RGB, 2, 2);
210: texture.setImage(0, new ImageComponent2D(
211: ImageComponent2D.FORMAT_RGB, new BufferedImage(2, 2,
212: BufferedImage.TYPE_INT_RGB)));
213: texture.setEnable(false);
214: node = new SGTexture(texture, nodeParent.getContext());
215: setReadWriteCapabilityBits((NodeComponent) node.getJ3dNode());
216:
217: if (((Appearance) getParentJ3dNodeComponent())
218: .getTextureAttributes() == null) {
219: TextureAttributes attr = new TextureAttributes();
220: textureAttributesPanel.setEditorCapabilities(attr);
221: SGTextureAttributes sgAttr = new SGTextureAttributes(attr,
222: nodeParent.getContext());
223: ((Appearance) getParentJ3dNodeComponent())
224: .setTextureAttributes(attr);
225: ((SGAppearance) nodeParent).setSGTextureAttributes(sgAttr);
226: textureAttributesPanel.startEdit(sgAttr, nodeParent,
227: parentEditor);
228: textureAttributesPanel.setControls(); // Ensure we can call resetChanges
229: }
230:
231: setControls();
232: ((Appearance) getParentJ3dNodeComponent()).setTexture(texture);
233: ((SGAppearance) nodeParent).setSGTexture((SGTexture) node);
234: setUpdateRequired(true);
235: ncCommonP.startEdit(node);
236: }//GEN-LAST:event_createTextureBActionPerformed
237:
238: private void textureEnabledCBActionPerformed(
239: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_textureEnabledCBActionPerformed
240: // Add your handling code here:
241: if (doingSetControls)
242: return;
243:
244: setUpdateRequired(true);
245:
246: ((Texture) node.getJ3dNode()).setEnable(textureEnabledCB
247: .isSelected());
248: }//GEN-LAST:event_textureEnabledCBActionPerformed
249:
250: private void loadImageBActionPerformed(
251: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadImageBActionPerformed
252: // Add your handling code here:
253: File file = WindowManager.getManager().chooseOpenFile(
254: "Load Texture", fileFilter);
255: if (file == null)
256: return;
257:
258: //imageFilename = WindowManager.getManager().getRelativePath( file );
259: try {
260: imageURL = file.toURL();
261: } catch (java.net.MalformedURLException e) {
262: org.jdesktop.j3dfly.utils.gui.ErrorManager
263: .getDefault()
264: .notify(
265: e,
266: org.jdesktop.j3dfly.utils.gui.ErrorHandler.EXCEPTION);
267: imageURL = null;
268: }
269: loadTexture(file);
270: setUpdateRequired(true);
271:
272: Texture texture = textureLoader.getTexture();
273: texture.setCapability(Texture.ALLOW_ENABLE_READ);
274: texture.setCapability(Texture.ALLOW_ENABLE_WRITE);
275: texture.setCapability(Texture.ALLOW_IMAGE_READ);
276: texture.getImage(0).setCapability(
277: ImageComponent.ALLOW_IMAGE_READ);
278: texture.getImage(0).setCapability(
279: ImageComponent.ALLOW_FORMAT_READ);
280: texture.getImage(0).setCapability(
281: ImageComponent.ALLOW_SIZE_READ);
282:
283: origTexture = (Texture) node.getJ3dNode();
284: node = new SGTexture(texture, nodeParent.getContext());
285: ((Appearance) getParentJ3dNodeComponent()).setTexture(texture);
286: ((SGAppearance) nodeParent).setSGTexture((SGTexture) node);
287: }//GEN-LAST:event_loadImageBActionPerformed
288:
289: /**
290: * Set the GUI controls to represent node
291: * Store the state of the node so any subsequent changes
292: * can be reset
293: */
294: protected void setControls() {
295: if (node == null || node.getJ3dNode() == null) {
296: cardLayout.last(this );
297: } else {
298: processSGObjectExtraData(node.getSGObjectExtraData());
299: cardLayout.first(this );
300: doingSetControls = true;
301:
302: origTexture = (Texture) node.getJ3dNode();
303:
304: if (origTexture == null) {
305: textureEnabledCB.setSelected(false);
306: origTextureEnabled = false;
307: imagePanel.setImage(null);
308: } else {
309: origTextureEnabled = origTexture.getEnable();
310: textureEnabledCB.setSelected(origTextureEnabled);
311: ImageComponent imageComp = origTexture.getImage(0);
312: if (imageComp instanceof ImageComponent2D)
313: imagePanel.setImage(((ImageComponent2D) imageComp)
314: .getImage());
315: else
316: imagePanel.setImage(null);
317: }
318: mipmapLevelsTF.setText(new Integer(origTexture
319: .numMipMapLevels()).toString());
320: doingSetControls = false;
321: }
322: }
323:
324: /**
325: * Permanently apply the changes to the node
326: */
327: public void applyChanges() {
328: setControls();
329: setUpdateRequired(false);
330: }
331:
332: /**
333: * Reset the changes to the state when setControls or applyChanges
334: * was last called
335: */
336: public void resetChanges() {
337: if (origTexture != null)
338: origTexture.setEnable(origTextureEnabled);
339:
340: node = new SGTexture(origTexture, nodeParent.getContext());
341: ((SGAppearance) nodeParent).setSGTexture((SGTexture) node);
342: ((Appearance) getParentJ3dNodeComponent())
343: .setTexture(origTexture);
344:
345: if (origTexture != null)
346: origTexture.setEnable(origTextureEnabled);
347:
348: setControls();
349: }
350:
351: /**
352: * Set capability bits for read-only operations on this
353: * Nodes properties
354: */
355: protected void setReadCapabilityBits(NodeComponent node) {
356: if (node == null || node.isLive())
357: return;
358:
359: node.setCapability(Texture.ALLOW_IMAGE_READ);
360: node.setCapability(Texture.ALLOW_ENABLE_READ);
361: ImageComponent imC = ((Texture) node).getImage(0);
362: imC.setCapability(ImageComponent.ALLOW_IMAGE_READ);
363: imC.setCapability(ImageComponent.ALLOW_FORMAT_READ);
364: imC.setCapability(ImageComponent.ALLOW_SIZE_READ);
365: }
366:
367: /**
368: * Set capability bits for full read/write access to this
369: * nodes properties
370: */
371: protected void setReadWriteCapabilityBits(NodeComponent node) {
372:
373: if (node == null || node.isLive())
374: return;
375:
376: //t.setCapability( Texture.ALLOW_IMAGE_WRITE );
377: node.setCapability(Texture.ALLOW_ENABLE_WRITE);
378: node.setCapability(Texture.ALLOW_IMAGE_READ);
379: node.setCapability(Texture.ALLOW_ENABLE_READ);
380: node.setCapability(Texture.ALLOW_MIPMAP_MODE_READ);
381: node.setCapability(Texture.ALLOW_SIZE_READ);
382:
383: // TODO Deal with other ImageComponents in Texture
384: ImageComponent imC = ((Texture) node).getImage(0);
385:
386: // imC is sometime Live - looks like a Java3D API bug
387: // or perhaps the imC is shared ?
388: if (imC.isLive())
389: System.out.println("ERROR - ImageComponent is still Live");
390: else {
391: imC.setCapability(ImageComponent.ALLOW_IMAGE_READ);
392: imC.setCapability(ImageComponent.ALLOW_FORMAT_READ);
393: imC.setCapability(ImageComponent.ALLOW_SIZE_READ);
394: }
395: }
396:
397: /**
398: * Returns the extra state information from the current editor which
399: * is not stored in the scenegraph. If ret is null a new NodeState object
400: * is created and returned otherwise ret is updated and returned
401: *
402: * For transformGroup the structure will contain the list of
403: * transformations.
404: */
405: protected SGObjectExtraData updateSGObjectExtraData(
406: SGObjectExtraData ret) {
407: super .updateSGObjectExtraData(ret);
408:
409: if (ret == null)
410: ret = new TextureExtraData();
411: ((TextureExtraData) ret).setImageURL(imageURL);
412:
413: System.out.println("Storing URL " + imageURL);
414:
415: return ret;
416: }
417:
418: /**
419: * Process the extra data for the node, updating the GUI appropriately
420: */
421: protected void processSGObjectExtraData(SGObjectExtraData state) {
422:
423: System.out.println("processSGObjectExtraData " + state);
424:
425: if (state == null)
426: return;
427:
428: imageURL = ((TextureExtraData) state).getImageURL();
429:
430: System.out.println("Texture FIlename " + imageURL);
431: }
432:
433: private void loadTexture(File file) {
434:
435: setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
436: textureLoader = new TextureLoader(file.getAbsolutePath(), this );
437: BufferedImage image = textureLoader.getImage().getImage();
438:
439: imagePanel.setImage(image);
440: texturePreview.getViewport().setViewSize(
441: imagePanel.getPreferredSize());
442: texturePreview.invalidate();
443: textureEnabledCB.setSelected(true);
444: setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
445: }
446:
447: /**
448: * Get the CommonNodeComponentPanel
449: */
450: protected org.jdesktop.j3dedit.scenegrapheditor.nodeeditors.panels.CommonNodeComponentPanel getCommonNCPanel() {
451: return ncCommonP;
452: }
453:
454: // Variables declaration - do not modify//GEN-BEGIN:variables
455: private javax.swing.JPanel nullPanel;
456: private javax.swing.JPanel jPanel2;
457: private javax.swing.JPanel jPanel1;
458: private javax.swing.JScrollPane texturePreview;
459: private javax.swing.JButton createTextureB;
460: private javax.swing.JPanel normalPanel;
461: private org.jdesktop.j3dedit.scenegrapheditor.nodeeditors.panels.CommonNodeComponentPanel ncCommonP;
462: private javax.swing.JButton loadImageB;
463: private javax.swing.JTextField mipmapLevelsTF;
464: private javax.swing.JLabel jLabel2;
465: private javax.swing.JLabel jLabel1;
466: private javax.swing.JCheckBox textureEnabledCB;
467:
468: // End of variables declaration//GEN-END:variables
469:
470: /**
471: * Simply draws an image in the panel
472: */
473: class TextureImagePanel extends javax.swing.JPanel {
474:
475: BufferedImage image = null;
476:
477: public void paintComponent(Graphics g) {
478: super .paintComponent(g);
479: if (image != null)
480: g.drawImage(image, 0, 0, java.awt.Color.white, this );
481: }
482:
483: public void setImage(BufferedImage image) {
484: this .image = image;
485: }
486:
487: public BufferedImage getImage() {
488: return image;
489: }
490:
491: public Dimension getMinimumSize() {
492: if (image == null)
493: return new Dimension(50, 50);
494: else
495: return new Dimension(image.getWidth(), image
496: .getHeight());
497: }
498:
499: public Dimension getPreferredSize() {
500: return getMinimumSize();
501: }
502:
503: }
504: }
|