001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.vmd.game.preview;
043:
044: import java.awt.BorderLayout;
045: import java.awt.Color;
046: import java.awt.Dimension;
047: import java.awt.Font;
048: import java.awt.event.ActionEvent;
049: import java.awt.event.ActionListener;
050: import java.awt.event.ComponentEvent;
051: import java.awt.event.ComponentListener;
052: import java.beans.PropertyChangeEvent;
053: import java.beans.PropertyChangeListener;
054: import java.util.List;
055: import java.util.Timer;
056: import java.util.TimerTask;
057: import javax.swing.Action;
058: import javax.swing.DefaultComboBoxModel;
059: import org.netbeans.modules.vmd.game.model.Sequence;
060: import org.netbeans.modules.vmd.game.model.SequenceContainer;
061: import org.netbeans.modules.vmd.game.model.SequenceListener;
062: import org.netbeans.modules.vmd.game.model.StaticTile;
063: import org.netbeans.modules.vmd.game.view.ColorConstants;
064: import org.netbeans.modules.vmd.game.view.ImagePreviewComponent;
065:
066: /**
067: *
068: * @author karel herink
069: */
070: public class SequencePreviewPanel extends javax.swing.JPanel implements
071: SequenceListener, ComponentListener, PropertyChangeListener,
072: ActionListener {
073:
074: public static final boolean DEBUG = false;
075:
076: public static final Color COLOR_BORDER_PLAIN = ColorConstants.COLOR_OUTLINE_PLAIN;
077: public static final Color COLOR_BORDER_SELECTED = ColorConstants.COLOR_OUTLINE_SELECTED;
078:
079: public static final Color COLOR_TEXT_PLAIN = ColorConstants.COLOR_OUTLINE_SELECTED;
080: public static final Color COLOR_TEXT_SELECTED = ColorConstants.COLOR_OUTLINE_SELECTED;
081:
082: private boolean isPlaying = false;
083: private boolean isPlayingForward = true;
084:
085: private int sequenceIndex;
086: private DefaultComboBoxModel actionsModel = new DefaultComboBoxModel();
087:
088: private SequenceContainer sequenceContainer;
089: private Sequence sequence;
090: private Timer timer;
091:
092: private ImagePreviewComponent imagePreview;
093:
094: public SequencePreviewPanel(Sequence sequence) {
095: this .initComponents();
096: this .sequenceContainer = sequenceContainer;
097: this .imagePreview = new ImagePreviewComponent(true, true, true);
098: this .panelSequenceAnimatedPreview.add(this .imagePreview,
099: BorderLayout.CENTER);
100: this .addComponentListener(this );
101: this .setSequence(sequence);
102: this .updateActions();
103: this .buttonPlayForward.addActionListener(this );
104: this .buttonPlayBackward.addActionListener(this );
105: this .buttonPause.addActionListener(this );
106:
107: buttonPlayBackward.setBackground(buttonPlayBackward.getParent()
108: .getBackground());
109: buttonPause.setBackground(buttonPause.getParent()
110: .getBackground());
111: buttonPlayForward.setBackground(buttonPlayForward.getParent()
112: .getBackground());
113:
114: this .buttonPause.setEnabled(this .isPlaying);
115: }
116:
117: public void setSequenceContainer(SequenceContainer sequenceContainer) {
118: this .sequenceContainer = sequenceContainer;
119: this .updateActions();
120: }
121:
122: private Dimension getFrameSize() {
123: if (this .sequence == null)
124: return new Dimension(10, 10);
125: return this .sequence.getFrameSize();
126: }
127:
128: public void setSelected(boolean selected) {
129: if (selected) {
130: this .labelName
131: .setForeground(ColorConstants.COLOR_TEXT_SELECTED);
132: } else {
133: this .labelName
134: .setForeground(ColorConstants.COLOR_TEXT_PLAIN);
135: }
136: }
137:
138: //ActionListener----------------------------------------------------------------------
139: public void actionPerformed(ActionEvent e) {
140: if (e.getSource() == this .buttonPlayForward) {
141: this .isPlaying = true;
142: this .isPlayingForward = true;
143: } else if (e.getSource() == this .buttonPlayBackward) {
144: this .isPlaying = true;
145: this .isPlayingForward = false;
146: } else if (e.getSource() == this .buttonPause) {
147: this .isPlaying = false;
148: }
149: this .buttonPause.setEnabled(this .isPlaying);
150: this .buttonPlayForward.setEnabled(!this .isPlayingForward
151: || !this .isPlaying);
152: this .buttonPlayBackward.setEnabled(this .isPlayingForward
153: || !this .isPlaying);
154: }
155:
156: /**
157: * Method used to show that this preview is for a "special" sequence (e.g. the default sequence in a container).
158: * Currently only makes the name label use bold text.
159: */
160: public void setImportant(boolean isImportant) {
161: if (isImportant) {
162: this .labelName.setFont(this .labelName.getFont().deriveFont(
163: Font.BOLD));
164: } else {
165: this .labelName.setFont(this .labelName.getFont().deriveFont(
166: Font.PLAIN));
167: }
168: this .updateActions();
169: }
170:
171: private void updateActions() {
172: this .actionsModel.removeAllElements();
173: List<Action> actions;
174: if (this .sequenceContainer != null) {
175: actions = this .sequenceContainer
176: .getActionsForSequence(this .sequence);
177: } else {
178: actions = this .sequence.getActions();
179: }
180: for (Action action : actions) {
181: this .actionsModel.addElement(action);
182: }
183: }
184:
185: public void setSequence(Sequence sequence) {
186: if (this .sequence == null) {
187: } else {
188: this .sequence.removeSequenceListener(this );
189: this .sequence.removePropertyChangeListener(this );
190: this .timer.cancel();
191: int max = sequence.getFrameCount() - 1;
192: }
193: this .sequence = sequence;
194: this .labelName.setText(this .sequence.getName());
195: this .labelName.setToolTipText(this .sequence.getName());
196:
197: this .panelSpinner.add(new SequenceTimeSpinner(this .sequence),
198: BorderLayout.CENTER);
199: this .panelSpinner.revalidate();
200:
201: this .timer = new Timer();
202: StaticTile frame = this .sequence.getFrame(0);
203: this .imagePreview.setPreviewable(frame);
204: this .sequence.addSequenceListener(this );
205: this .timer.schedule(new AnimationTimerTask(), 0, this .sequence
206: .getFrameMs());
207: this .sequence.addPropertyChangeListener(this );
208: }
209:
210: public void requestPreviewFrame(int frameIndex) {
211: if (!this .isPlaying
212: && this .sequence.getFrame(frameIndex) != null)
213: this .imagePreview.setPreviewable(this .sequence
214: .getFrame(frameIndex));
215: }
216:
217: private void sequenceChanged() {
218: this .setSequence(this .sequence);
219: }
220:
221: private void incrementSequenceIndex() {
222: int index = this .sequenceIndex + 1;
223: if (index >= this .sequence.getFrameCount()) {
224: this .sequenceIndex = 0;
225: } else {
226: this .sequenceIndex = index;
227: }
228: }
229:
230: private void decrementSequenceIndex() {
231: int index = this .sequenceIndex - 1;
232: if (index < 0) {
233: this .sequenceIndex = this .sequence.getFrameCount() - 1;
234: } else {
235: this .sequenceIndex = index;
236: }
237: }
238:
239: private void currentFrameChanged() {
240: //this.slider.setValue(this.sequenceIndex);
241: }
242:
243: private class AnimationTimerTask extends TimerTask {
244: public void run() {
245: if (!SequencePreviewPanel.this .isPlaying
246: || !SequencePreviewPanel.this .isShowing())
247: return;
248: SequencePreviewPanel.this
249: .setCurrentFrameIndex(SequencePreviewPanel.this .sequenceIndex);
250: SequencePreviewPanel.this .currentFrameChanged();
251: if (SequencePreviewPanel.this .isPlayingForward) {
252: SequencePreviewPanel.this .incrementSequenceIndex();
253: } else {
254: SequencePreviewPanel.this .decrementSequenceIndex();
255: }
256: }
257: }
258:
259: private void setCurrentFrameIndex(int frameIndex) {
260: StaticTile frame = null;
261: do {
262: try {
263: frame = SequencePreviewPanel.this .sequence
264: .getFrame(frameIndex);
265: } catch (Exception e) {
266: //e.printStackTrace();
267: frameIndex--;
268: }
269: } while (frame == null);
270: this .sequenceIndex = frameIndex;
271: this .imagePreview.setPreviewable(frame);
272: }
273:
274: //PropertyChangeListener-------------------------------------------------------------
275: //Listen for changes in frame delay
276: public void propertyChange(PropertyChangeEvent evt) {
277: if (evt.getSource() == this .sequence) {
278: if (evt.getPropertyName()
279: .equals(Sequence.PROPERTY_FRAME_MS)) {
280: this .timer.cancel();
281: this .timer = new Timer();
282: this .timer.schedule(new AnimationTimerTask(), 0,
283: this .sequence.getFrameMs());
284: }
285: if (evt.getPropertyName().equals(Sequence.PROPERTY_NAME)) {
286: this .labelName.setText(this .sequence.getName());
287: }
288: }
289: }
290:
291: //ComponentListener-------------------------------------------------------------------
292: public void componentShown(ComponentEvent e) {
293: }
294:
295: public void componentHidden(ComponentEvent e) {
296: }
297:
298: public void componentResized(ComponentEvent e) {
299: if (DEBUG)
300: System.out.println("SequenceAnimatedPreview Resized..."); // NOI18N
301: //TODO : here i will recalculate cached images
302: }
303:
304: public void componentMoved(ComponentEvent e) {
305: }
306:
307: //SequenceListener
308: public void frameAdded(Sequence sequence, int index) {
309: this .sequenceChanged();
310: }
311:
312: public void frameRemoved(Sequence sequence, int index) {
313: this .sequenceChanged();
314: }
315:
316: public void framesChanged(Sequence sequence) {
317: this .sequenceChanged();
318: }
319:
320: public void frameModified(Sequence sequence, int index) {
321: //TODO : here i would recache the modified frame image i think
322: }
323:
324: /** This method is called from within the constructor to
325: * initialize the form.
326: * WARNING: Do NOT modify this code. The content of this method is
327: * always regenerated by the Form Editor.
328: */
329: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
330: private void initComponents() {
331:
332: jPanel5 = new javax.swing.JPanel();
333: jPanel2 = new javax.swing.JPanel();
334: jPanel3 = new javax.swing.JPanel();
335: labelName = new javax.swing.JLabel();
336: jPanel4 = new javax.swing.JPanel();
337: buttonPlayBackward = new javax.swing.JButton();
338: buttonPause = new javax.swing.JButton();
339: buttonPlayForward = new javax.swing.JButton();
340: jPanel6 = new javax.swing.JPanel();
341: jPanel7 = new javax.swing.JPanel();
342: panelSequenceAnimatedPreview = new javax.swing.JPanel();
343: jPanel8 = new javax.swing.JPanel();
344: panelSpinner = new javax.swing.JPanel();
345:
346: setBorder(new javax.swing.border.LineBorder(COLOR_BORDER_PLAIN,
347: 2, true));
348:
349: jPanel5.setMinimumSize(new java.awt.Dimension(300, 126));
350: jPanel5.setLayout(new java.awt.GridLayout());
351:
352: jPanel2.setLayout(new java.awt.BorderLayout());
353:
354: labelName.setFont(new java.awt.Font("Dialog", 1, 14));
355: labelName.setForeground(ColorConstants.COLOR_TEXT_PLAIN);
356: labelName
357: .setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
358: labelName.setText("<NONE>");
359:
360: org.jdesktop.layout.GroupLayout jPanel3Layout = new org.jdesktop.layout.GroupLayout(
361: jPanel3);
362: jPanel3.setLayout(jPanel3Layout);
363: jPanel3Layout
364: .setHorizontalGroup(jPanel3Layout.createParallelGroup(
365: org.jdesktop.layout.GroupLayout.LEADING).add(
366: labelName,
367: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
368: 130,
369: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE));
370: jPanel3Layout
371: .setVerticalGroup(jPanel3Layout.createParallelGroup(
372: org.jdesktop.layout.GroupLayout.LEADING).add(
373: labelName,
374: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
375: 106,
376: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE));
377:
378: jPanel2.add(jPanel3, java.awt.BorderLayout.CENTER);
379:
380: jPanel4.setMaximumSize(new java.awt.Dimension(174, 34));
381: jPanel4.setLayout(new java.awt.GridLayout(1, 0));
382:
383: buttonPlayBackward
384: .setIcon(new javax.swing.ImageIcon(
385: getClass()
386: .getResource(
387: "/org/netbeans/modules/vmd/game/editor/sequece/resources/playrev.png"))); // NOI18N
388: jPanel4.add(buttonPlayBackward);
389:
390: buttonPause
391: .setIcon(new javax.swing.ImageIcon(
392: getClass()
393: .getResource(
394: "/org/netbeans/modules/vmd/game/editor/sequece/resources/pause.gif"))); // NOI18N
395: jPanel4.add(buttonPause);
396:
397: buttonPlayForward
398: .setIcon(new javax.swing.ImageIcon(
399: getClass()
400: .getResource(
401: "/org/netbeans/modules/vmd/game/editor/sequece/resources/play.png"))); // NOI18N
402: jPanel4.add(buttonPlayForward);
403:
404: jPanel2.add(jPanel4, java.awt.BorderLayout.PAGE_END);
405:
406: jPanel5.add(jPanel2);
407:
408: jPanel6.setLayout(new java.awt.BorderLayout());
409:
410: jPanel7.setLayout(new java.awt.GridBagLayout());
411:
412: panelSequenceAnimatedPreview.setBackground(new java.awt.Color(
413: 255, 255, 255));
414: panelSequenceAnimatedPreview
415: .setBorder(javax.swing.BorderFactory
416: .createLineBorder(ColorConstants.COLOR_OUTLINE_PLAIN));
417: panelSequenceAnimatedPreview
418: .setMaximumSize(new java.awt.Dimension(80, 80));
419: panelSequenceAnimatedPreview
420: .setMinimumSize(new java.awt.Dimension(80, 80));
421: panelSequenceAnimatedPreview
422: .setPreferredSize(new java.awt.Dimension(80, 80));
423: panelSequenceAnimatedPreview
424: .setLayout(new java.awt.BorderLayout());
425: jPanel7.add(panelSequenceAnimatedPreview,
426: new java.awt.GridBagConstraints());
427:
428: jPanel6.add(jPanel7, java.awt.BorderLayout.CENTER);
429:
430: jPanel8.setMaximumSize(new java.awt.Dimension(174, 44));
431: jPanel8.setMinimumSize(new java.awt.Dimension(174, 44));
432:
433: panelSpinner.setBackground(new java.awt.Color(255, 255, 255));
434: panelSpinner.setMaximumSize(new java.awt.Dimension(100, 20));
435: panelSpinner.setMinimumSize(new java.awt.Dimension(100, 20));
436: panelSpinner.setPreferredSize(new java.awt.Dimension(100, 20));
437: panelSpinner.setLayout(new java.awt.BorderLayout());
438:
439: org.jdesktop.layout.GroupLayout jPanel8Layout = new org.jdesktop.layout.GroupLayout(
440: jPanel8);
441: jPanel8.setLayout(jPanel8Layout);
442: jPanel8Layout
443: .setHorizontalGroup(jPanel8Layout
444: .createParallelGroup(
445: org.jdesktop.layout.GroupLayout.LEADING)
446: .add(
447: jPanel8Layout
448: .createSequentialGroup()
449: .addContainerGap()
450: .add(
451: panelSpinner,
452: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
453: 108, Short.MAX_VALUE)
454: .addContainerGap()));
455: jPanel8Layout
456: .setVerticalGroup(jPanel8Layout
457: .createParallelGroup(
458: org.jdesktop.layout.GroupLayout.LEADING)
459: .add(
460: jPanel8Layout
461: .createSequentialGroup()
462: .add(
463: panelSpinner,
464: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
465: 20,
466: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
467: .addContainerGap(
468: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
469: Short.MAX_VALUE)));
470:
471: jPanel6.add(jPanel8, java.awt.BorderLayout.PAGE_END);
472:
473: jPanel5.add(jPanel6);
474:
475: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
476: this );
477: this .setLayout(layout);
478: layout.setHorizontalGroup(layout.createParallelGroup(
479: org.jdesktop.layout.GroupLayout.LEADING).add(jPanel5,
480: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 264,
481: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE));
482: layout.setVerticalGroup(layout.createParallelGroup(
483: org.jdesktop.layout.GroupLayout.LEADING).add(jPanel5,
484: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
485: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
486: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE));
487: }// </editor-fold>//GEN-END:initComponents
488:
489: // Variables declaration - do not modify//GEN-BEGIN:variables
490: private javax.swing.JButton buttonPause;
491: private javax.swing.JButton buttonPlayBackward;
492: private javax.swing.JButton buttonPlayForward;
493: private javax.swing.JPanel jPanel2;
494: private javax.swing.JPanel jPanel3;
495: private javax.swing.JPanel jPanel4;
496: private javax.swing.JPanel jPanel5;
497: private javax.swing.JPanel jPanel6;
498: private javax.swing.JPanel jPanel7;
499: private javax.swing.JPanel jPanel8;
500: private javax.swing.JLabel labelName;
501: private javax.swing.JPanel panelSequenceAnimatedPreview;
502: private javax.swing.JPanel panelSpinner;
503: // End of variables declaration//GEN-END:variables
504:
505: }
|