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: package org.netbeans.modules.vmd.game.preview;
042:
043: import java.awt.BorderLayout;
044: import java.awt.Dimension;
045: import java.awt.Font;
046: import java.awt.event.ActionEvent;
047: import java.awt.event.ActionListener;
048: import java.awt.event.ComponentEvent;
049: import java.awt.event.ComponentListener;
050: import java.beans.PropertyChangeEvent;
051: import java.beans.PropertyChangeListener;
052: import java.util.Timer;
053: import java.util.TimerTask;
054: import org.netbeans.modules.vmd.game.model.Sequence;
055: import org.netbeans.modules.vmd.game.model.SequenceListener;
056: import org.netbeans.modules.vmd.game.model.StaticTile;
057: import org.netbeans.modules.vmd.game.view.ImagePreviewComponent;
058:
059: /**
060: *
061: * @author kherink
062: */
063: public class SequencePreviewPanelSidebar extends javax.swing.JPanel
064: implements SequenceListener, ComponentListener,
065: PropertyChangeListener, ActionListener {
066:
067: public static final boolean DEBUG = false;
068:
069: private boolean isPlaying;
070: private boolean isPlayingForward = true;
071:
072: private int sequenceIndex;
073:
074: private Sequence sequence;
075: private Timer timer;
076:
077: private ImagePreviewComponent imagePreview;
078:
079: public SequencePreviewPanelSidebar(Sequence sequence) {
080: this .imagePreview = new ImagePreviewComponent(false, true,
081: false);
082: this .initComponents();
083: this .addComponentListener(this );
084:
085: this .setSequence(sequence);
086: }
087:
088: private Dimension getFrameSize() {
089: if (this .sequence == null)
090: return new Dimension(10, 10);
091: return this .sequence.getFrameSize();
092: }
093:
094: /**
095: * Method used to show that this preview is for a "special" sequence (e.g. the default sequence in a container).
096: * Currently only makes the name label use bold text.
097: */
098: public void setImportant(boolean isImportant) {
099: if (isImportant) {
100: this .labelName.setFont(this .labelName.getFont().deriveFont(
101: Font.BOLD));
102: } else {
103: this .labelName.setFont(this .labelName.getFont().deriveFont(
104: Font.PLAIN));
105: }
106: }
107:
108: public void setSequence(Sequence sequence) {
109: if (this .sequence == null) {
110: } else {
111: this .sequence.removeSequenceListener(this );
112: this .sequence.removePropertyChangeListener(this );
113: this .timer.cancel();
114: int max = sequence.getFrameCount() - 1;
115: }
116: this .sequence = sequence;
117: this .labelName.setText(this .sequence.getName());
118:
119: this .spinnerPanel.add(new SequenceTimeSpinner(this .sequence),
120: BorderLayout.CENTER);
121:
122: this .timer = new Timer();
123: StaticTile frame = this .sequence.getFrame(0);
124: this .imagePreview.setPreviewable(frame);
125: this .sequence.addSequenceListener(this );
126: this .timer.schedule(new AnimationTimerTask(), 0, this .sequence
127: .getFrameMs());
128: this .sequence.addPropertyChangeListener(this );
129: }
130:
131: public void requestPreviewFrame(int frameIndex) {
132: if (!this .isPlaying
133: && this .sequence.getFrame(frameIndex) != null)
134: this .imagePreview.setPreviewable(this .sequence
135: .getFrame(frameIndex));
136: }
137:
138: /** This method is called from within the constructor to
139: * initialize the form.
140: * WARNING: Do NOT modify this code. The content of this method is
141: * always regenerated by the Form Editor.
142: */
143: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
144: private void initComponents() {
145: jPanel1 = new javax.swing.JPanel();
146: buttonPause = new javax.swing.JButton();
147: buttonDirection = new javax.swing.JButton();
148: panelSequenceAnimatedPreview = new javax.swing.JPanel();
149: jPanel2 = new javax.swing.JPanel();
150: labelName = new javax.swing.JLabel();
151: spinnerPanel = new javax.swing.JPanel();
152:
153: setBackground(new java.awt.Color(255, 255, 255));
154: jPanel1.setBackground(new java.awt.Color(255, 255, 255));
155: buttonPause.setText(">");
156: this .buttonPause.addActionListener(this );
157:
158: buttonDirection.setText("<>");
159: this .buttonDirection.addActionListener(this );
160:
161: panelSequenceAnimatedPreview
162: .setLayout(new java.awt.BorderLayout(10, 10));
163:
164: panelSequenceAnimatedPreview.setBackground(new java.awt.Color(
165: 255, 255, 255));
166: panelSequenceAnimatedPreview
167: .setMinimumSize(this .getFrameSize());
168: this .panelSequenceAnimatedPreview.add(this .imagePreview);
169:
170: org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(
171: jPanel1);
172: jPanel1.setLayout(jPanel1Layout);
173: jPanel1Layout
174: .setHorizontalGroup(jPanel1Layout
175: .createParallelGroup(
176: org.jdesktop.layout.GroupLayout.LEADING)
177: .add(
178: jPanel1Layout
179: .createSequentialGroup()
180: .addContainerGap()
181: .add(
182: jPanel1Layout
183: .createParallelGroup(
184: org.jdesktop.layout.GroupLayout.LEADING,
185: false)
186: .add(
187: buttonDirection,
188: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
189: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
190: Short.MAX_VALUE)
191: .add(
192: buttonPause,
193: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
194: 69,
195: Short.MAX_VALUE))
196: .add(18, 18, 18)
197: .add(
198: panelSequenceAnimatedPreview,
199: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
200: 78, Short.MAX_VALUE)));
201: jPanel1Layout
202: .setVerticalGroup(jPanel1Layout
203: .createParallelGroup(
204: org.jdesktop.layout.GroupLayout.LEADING)
205: .add(
206: jPanel1Layout
207: .createSequentialGroup()
208: .add(
209: jPanel1Layout
210: .createParallelGroup(
211: org.jdesktop.layout.GroupLayout.TRAILING)
212: .add(
213: panelSequenceAnimatedPreview,
214: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
215: 56,
216: Short.MAX_VALUE)
217: .add(
218: org.jdesktop.layout.GroupLayout.LEADING,
219: jPanel1Layout
220: .createSequentialGroup()
221: .add(
222: buttonPause)
223: .addPreferredGap(
224: org.jdesktop.layout.LayoutStyle.RELATED)
225: .add(
226: buttonDirection)))
227: .addContainerGap()));
228:
229: jPanel2.setBackground(new java.awt.Color(255, 255, 255));
230: labelName.setText("<None>");
231:
232: spinnerPanel.setLayout(new java.awt.BorderLayout());
233:
234: spinnerPanel.setBackground(new java.awt.Color(255, 255, 255));
235:
236: org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(
237: jPanel2);
238: jPanel2.setLayout(jPanel2Layout);
239: jPanel2Layout
240: .setHorizontalGroup(jPanel2Layout
241: .createParallelGroup(
242: org.jdesktop.layout.GroupLayout.LEADING)
243: .add(
244: org.jdesktop.layout.GroupLayout.TRAILING,
245: jPanel2Layout
246: .createSequentialGroup()
247: .addContainerGap()
248: .add(
249: labelName,
250: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
251: 79, Short.MAX_VALUE)
252: .addPreferredGap(
253: org.jdesktop.layout.LayoutStyle.RELATED)
254: .add(
255: spinnerPanel,
256: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
257: 74,
258: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
259: .addContainerGap()));
260: jPanel2Layout
261: .setVerticalGroup(jPanel2Layout
262: .createParallelGroup(
263: org.jdesktop.layout.GroupLayout.LEADING)
264: .add(
265: org.jdesktop.layout.GroupLayout.TRAILING,
266: jPanel2Layout
267: .createSequentialGroup()
268: .addContainerGap()
269: .add(
270: jPanel2Layout
271: .createParallelGroup(
272: org.jdesktop.layout.GroupLayout.LEADING)
273: .add(labelName)
274: .add(
275: spinnerPanel,
276: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
277: 15,
278: Short.MAX_VALUE))
279: .add(12, 12, 12)));
280:
281: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
282: this );
283: this .setLayout(layout);
284: layout.setHorizontalGroup(layout.createParallelGroup(
285: org.jdesktop.layout.GroupLayout.LEADING).add(
286: layout.createSequentialGroup().add(jPanel1,
287: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
288: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
289: Short.MAX_VALUE).addContainerGap()).add(
290: jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
291: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
292: Short.MAX_VALUE));
293: layout
294: .setVerticalGroup(layout
295: .createParallelGroup(
296: org.jdesktop.layout.GroupLayout.LEADING)
297: .add(
298: layout
299: .createSequentialGroup()
300: .add(
301: jPanel2,
302: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
303: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
304: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
305: .addPreferredGap(
306: org.jdesktop.layout.LayoutStyle.RELATED)
307: .add(
308: jPanel1,
309: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
310: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
311: Short.MAX_VALUE)
312: .addContainerGap()));
313: }// </editor-fold>//GEN-END:initComponents
314:
315: // Variables declaration - do not modify//GEN-BEGIN:variables
316: private javax.swing.JButton buttonDirection;
317: private javax.swing.JButton buttonPause;
318: public javax.swing.JPanel jPanel1;
319: public javax.swing.JPanel jPanel2;
320: public javax.swing.JLabel labelName;
321: private javax.swing.JPanel panelSequenceAnimatedPreview;
322: public javax.swing.JPanel spinnerPanel;
323:
324: // End of variables declaration//GEN-END:variables
325:
326: private void sequenceChanged() {
327: this .setSequence(this .sequence);
328: }
329:
330: private void switchPlayDirection() {
331: this .isPlayingForward = !this .isPlayingForward;
332: this .setPlaying(true);
333: }
334:
335: private void setPlaying(boolean play) {
336: if (play) {
337: if (this .isPlayingForward)
338: this .buttonPause.setText(">||");
339: else {
340: this .buttonPause.setText("||<");
341: }
342: } else {
343: if (this .isPlayingForward) {
344: this .buttonPause.setText(">");
345: } else {
346: this .buttonPause.setText("<");
347: }
348: }
349: this .isPlaying = play;
350: }
351:
352: private void incrementSequenceIndex() {
353: int index = this .sequenceIndex + 1;
354: if (index >= this .sequence.getFrameCount()) {
355: this .sequenceIndex = 0;
356: } else {
357: this .sequenceIndex = index;
358: }
359: }
360:
361: private void decrementSequenceIndex() {
362: int index = this .sequenceIndex - 1;
363: if (index < 0) {
364: this .sequenceIndex = this .sequence.getFrameCount() - 1;
365: } else {
366: this .sequenceIndex = index;
367: }
368: }
369:
370: private void currentFrameChanged() {
371: //this.slider.setValue(this.sequenceIndex);
372: }
373:
374: private class AnimationTimerTask extends TimerTask {
375: public void run() {
376: if (!SequencePreviewPanelSidebar.this .isPlaying
377: || !SequencePreviewPanelSidebar.this .isShowing())
378: return;
379: SequencePreviewPanelSidebar.this
380: .setCurrentFrameIndex(SequencePreviewPanelSidebar.this .sequenceIndex);
381: SequencePreviewPanelSidebar.this .currentFrameChanged();
382: if (SequencePreviewPanelSidebar.this .isPlayingForward) {
383: SequencePreviewPanelSidebar.this
384: .incrementSequenceIndex();
385: } else {
386: SequencePreviewPanelSidebar.this
387: .decrementSequenceIndex();
388: }
389: // System.out.println(System.nanoTime());
390: }
391: }
392:
393: private void setCurrentFrameIndex(int frameIndex) {
394: StaticTile frame = null;
395: do {
396: try {
397: frame = SequencePreviewPanelSidebar.this .sequence
398: .getFrame(frameIndex);
399: } catch (Exception e) {
400: //e.printStackTrace();
401: frameIndex--;
402: }
403: } while (frame == null);
404: this .sequenceIndex = frameIndex;
405: this .imagePreview.setPreviewable(frame);
406: }
407:
408: //PropertyChangeListener-------------------------------------------------------------
409: //Listen for changes in frame delay
410: public void propertyChange(PropertyChangeEvent evt) {
411: if (evt.getSource() == this .sequence) {
412: if (evt.getPropertyName()
413: .equals(Sequence.PROPERTY_FRAME_MS)) {
414: this .timer.cancel();
415: this .timer = new Timer();
416: this .timer.schedule(new AnimationTimerTask(), 0,
417: this .sequence.getFrameMs());
418: }
419: if (evt.getPropertyName().equals(Sequence.PROPERTY_NAME)) {
420: this .labelName.setText(this .sequence.getName());
421: }
422: }
423: }
424:
425: //ComponentListener-------------------------------------------------------------------
426: public void componentShown(ComponentEvent e) {
427: }
428:
429: public void componentHidden(ComponentEvent e) {
430: }
431:
432: public void componentResized(ComponentEvent e) {
433: if (DEBUG)
434: System.out.println("SequenceAnimatedPreview Resized..."); // NOI18N
435: //TODO : here i will recalculate cached images
436: }
437:
438: public void componentMoved(ComponentEvent e) {
439: }
440:
441: //ActionListener----------------------------------------------------------------------
442: public void actionPerformed(ActionEvent e) {
443: if (e.getSource() == this .buttonDirection) {
444: this .switchPlayDirection();
445: } else {
446: this .setPlaying(!this .isPlaying);
447: }
448: }
449:
450: //SequenceListener
451: public void frameAdded(Sequence sequence, int index) {
452: this .sequenceChanged();
453: }
454:
455: public void frameRemoved(Sequence sequence, int index) {
456: this .sequenceChanged();
457: }
458:
459: public void framesChanged(Sequence sequence) {
460: this .sequenceChanged();
461: }
462:
463: public void frameModified(Sequence sequence, int index) {
464: //TODO : here i would recache the modified frame image i think
465: }
466: }
|