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.j2me.cdc.project.semc;
043:
044: import java.awt.Color;
045: import java.awt.Dimension;
046: import java.awt.Image;
047: import java.awt.image.BufferedImage;
048: import java.beans.PropertyChangeEvent;
049: import java.beans.PropertyChangeListener;
050: import java.io.BufferedInputStream;
051: import java.io.ByteArrayOutputStream;
052: import java.io.File;
053: import java.io.FileInputStream;
054: import java.io.IOException;
055: import java.io.InputStream;
056: import java.util.ArrayList;
057: import java.util.Iterator;
058: import java.util.List;
059: import java.util.StringTokenizer;
060: import javax.imageio.ImageIO;
061: import javax.imageio.ImageReader;
062: import javax.imageio.ImageWriter;
063: import javax.imageio.stream.ImageInputStream;
064: import javax.swing.Icon;
065: import javax.swing.ImageIcon;
066: import javax.swing.JFileChooser;
067: import javax.swing.JLabel;
068: import javax.swing.JPanel;
069: import javax.swing.SwingUtilities;
070: import javax.swing.UIManager;
071: import org.openide.util.NbBundle;
072:
073: /**
074: *
075: * @author Manowar, suchys
076: */
077: public class MBMThumbnailAccessory extends JPanel implements
078: PropertyChangeListener {
079:
080: private static final int ICON_MAX_WIDTH = 64;
081:
082: private Icon[] thumbnails;
083: private JLabel[] labels;
084: private File file;
085: private String tmpDir;
086: private JFileChooser fc;
087: private String bmconvLocation;
088:
089: private int iconCount;
090:
091: public MBMThumbnailAccessory(JFileChooser fc, File sdkLocation) {
092: this .fc = fc;
093:
094: initComponents();
095:
096: labels = new JLabel[6];
097: labels[0] = label1;
098: labels[1] = label2;
099: labels[2] = label3;
100: labels[3] = label4;
101: labels[4] = label5;
102: labels[5] = label6;
103: int width = 5;//TODO SwingUtilities.computeStringWidth(Toolkit.getDefaultToolkit().getFontMetrics(UIManager.getFont(label1.getFont())), "2");
104: Dimension d = new Dimension(64 + width, 64);
105: for (int i = 0; i < labels.length; i++) {
106: labels[i].setPreferredSize(d);
107: }
108: tmpDir = System.getProperty("java.io.tmpdir"); //NOI18N
109:
110: iconNumLabel
111: .setText(NbBundle.getMessage(
112: MBMThumbnailAccessory.class,
113: "LBL_ThumbnailsInfo", "0")); //NOI18N
114:
115: StringBuffer str = new StringBuffer();
116: if (sdkLocation != null && sdkLocation.exists()) {
117: str.append(sdkLocation.getAbsolutePath());
118: str.append(File.separatorChar);
119: str.append("epoc32"); //NOI18N
120: str.append(File.separatorChar);
121: str.append("tools"); //NOI18N
122: str.append(File.separatorChar);
123: }
124: str.append("bmconv"); //NOI18N
125: bmconvLocation = str.toString();
126: }
127:
128: private void loadImages() {
129: if (file == null || thumbnails == null
130: || !file.getPath().toLowerCase().endsWith(".mbm")) { //NOI18N
131: thumbnails = null;
132: return;
133: }
134:
135: boolean error = false;
136: try {
137: List thumbs = new ArrayList();
138: thumbs.add(bmconvLocation);
139: thumbs.add("/u"); //NOI18N
140: thumbs.add(file.getPath());
141: for (int i = 0; i < thumbnails.length; i++) {
142: StringBuffer sb = new StringBuffer();
143: sb.append(tmpDir);
144: sb.append(File.separatorChar);
145: sb.append(i);
146: sb.append(".bmp"); //NOI18N
147: thumbs.add(sb.toString());
148: }
149: Process p = Runtime.getRuntime().exec(
150: (String[]) thumbs.toArray(new String[0])); //NOI18N
151: StringBuffer sout = new StringBuffer();
152: StringBuffer serr = new StringBuffer();
153: IOThread out = new IOThread(p.getInputStream(), sout);
154: out.join();
155: IOThread err = new IOThread(p.getInputStream(), serr);
156: err.join();
157: if (p.waitFor() == 0) {
158: ImageIcon tmpIcon = null;
159: for (int i = 0; i < thumbnails.length; i++) {
160: File bmpFile = new File(tmpDir + File.separatorChar
161: + i + ".bmp"); //NOI18N
162: bmpFile.deleteOnExit();
163:
164: Iterator itImageReaders = ImageIO
165: .getImageReadersByFormatName("bmp"); //NOI18N
166: ImageReader reader = null;
167: if (itImageReaders.hasNext()) {
168: reader = (ImageReader) itImageReaders.next();
169: ImageInputStream iis = ImageIO
170: .createImageInputStream(new BufferedInputStream(
171: new FileInputStream(bmpFile)));
172: reader.setInput(iis);
173: BufferedImage bi = reader.read(0);
174: Iterator itImageWriters = ImageIO
175: .getImageWritersByFormatName("png"); //NOI18N
176: ImageWriter writer = null;
177: if (itImageWriters.hasNext())
178: writer = (ImageWriter) itImageWriters
179: .next();
180: ByteArrayOutputStream baos = new ByteArrayOutputStream();
181: writer.setOutput(ImageIO
182: .createImageOutputStream(baos));
183: writer.write(bi);
184: reader.dispose();
185: writer.dispose();
186: iis.close();
187:
188: tmpIcon = new ImageIcon(baos.toByteArray());
189:
190: if (tmpIcon != null) {
191: if (tmpIcon.getIconWidth() > ICON_MAX_WIDTH) {
192: thumbnails[i] = new ImageIcon(tmpIcon
193: .getImage().getScaledInstance(
194: ICON_MAX_WIDTH, -1,
195: Image.SCALE_DEFAULT));
196: } else {
197: thumbnails[i] = tmpIcon;
198: }
199: labels[i].setText(String.valueOf(i + 1));
200: labels[i].setIcon(thumbnails[i]);
201: }
202: } else {
203: iconNumLabel.setText(NbBundle.getMessage(
204: MBMThumbnailAccessory.class,
205: "ERR_NotAvailable14")); //NOI18N
206: }
207: }
208: } else {
209: error = true;
210: }
211: } catch (IOException ex) {
212: error = true;
213: ;
214: } catch (InterruptedException ex) {
215: error = true;
216: } finally {
217: if (error) {
218: Color nbErrorForeground = UIManager
219: .getColor("nb.errorForeground"); //NOI18N
220: if (nbErrorForeground == null) {
221: nbErrorForeground = new Color(255, 0, 0);
222: }
223: textArea.setForeground(nbErrorForeground);
224: textArea.setText(NbBundle.getMessage(
225: MBMThumbnailAccessory.class,
226: "ERR_BmpconvNotExists")); //NOI18N
227: textArea.setCaretPosition(0);
228: }
229: }
230: }
231:
232: private void getImageInfo() {
233: if (file == null
234: || !file.getPath().toLowerCase().endsWith(".mbm")) { //NOI18N
235: thumbnails = null;
236: return;
237: }
238: boolean error = false;
239: try {
240: Process p = Runtime.getRuntime()
241: .exec(
242: new String[] { bmconvLocation, "/v",
243: file.getPath() }); //NOI18N
244: StringBuffer sout = new StringBuffer();
245: StringBuffer serr = new StringBuffer();
246: IOThread out = new IOThread(p.getInputStream(), sout);
247: out.join();
248: IOThread err = new IOThread(p.getInputStream(), serr);
249: err.join();
250: p.waitFor();
251: int exitValue = p.exitValue();
252: if (exitValue == 0) {
253: String text = sout.toString();
254: int i = text.indexOf("Bitmap"); //NOI18N
255: if (i > 0) {
256: Color foreground = UIManager
257: .getColor("TextArea.foreground"); //NOI18N
258: if (foreground == null) {
259: foreground = Color.BLACK;
260: }
261: textArea.setForeground(foreground);
262: textArea.setText(text.substring(i).trim());
263: textArea.setCaretPosition(0);
264: }
265:
266: StringTokenizer st = new StringTokenizer(sout
267: .toString(), "\n", false); //NOI18N
268: int c = 0;
269: while (st.hasMoreTokens()) {
270: String s = st.nextToken();
271: if (s.startsWith("Bitmap")) { //NOI18N
272: c++;
273: }
274: }
275: iconNumLabel.setText(NbBundle.getMessage(
276: MBMThumbnailAccessory.class,
277: "LBL_ThumbnailsInfo", String.valueOf(c)));
278: iconCount = c;
279: if (c > 0) {
280: if (c > 6) {
281: c = 6;
282: }
283: thumbnails = new Icon[c];
284: }
285: } else {
286: }
287: } catch (IOException ex) {
288: error = true;
289: ;
290: } catch (InterruptedException ex) {
291: error = true;
292: } finally {
293: if (error) {
294: Color nbErrorForeground = UIManager
295: .getColor("nb.errorForeground"); //NOI18N
296: if (nbErrorForeground == null) {
297: nbErrorForeground = new Color(255, 0, 0);
298: }
299: textArea.setForeground(nbErrorForeground);
300: textArea.setText(NbBundle.getMessage(
301: MBMThumbnailAccessory.class,
302: "ERR_BmpconvNotExists")); //NOI18N
303: textArea.setCaretPosition(0);
304: }
305: }
306: }
307:
308: public void propertyChange(PropertyChangeEvent e) {
309: boolean update = false;
310: String prop = e.getPropertyName();
311:
312: if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
313: file = null;
314: update = true;
315: } else if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY
316: .equals(prop)) {
317: file = (File) e.getNewValue();
318: update = true;
319: }
320:
321: if (update) {
322: thumbnails = null;
323: clean();
324: if (isShowing()) {
325: getImageInfo();
326: loadImages();
327: }
328: }
329: }
330:
331: private void clean() {
332: iconCount = 0;
333: for (int i = 0; i < labels.length; i++) {
334: labels[i].setText(" "); //NOI18N
335: labels[i].setIcon(null);
336: }
337:
338: iconNumLabel
339: .setText(NbBundle.getMessage(
340: MBMThumbnailAccessory.class,
341: "LBL_ThumbnailsInfo", "0")); //NOI18N
342: textArea.setText(""); //NOI18N
343: }
344:
345: /**
346: * Notifies this component that it no longer has a parent component.
347: * When this method is invoked, any <code>KeyboardAction</code>s
348: * set up in the the chain of parent components are removed.
349: *
350: *
351: * @see #registerKeyboardAction
352: */
353: public void removeNotify() {
354: fc.removePropertyChangeListener(this );
355: super .removeNotify();
356: }
357:
358: /**
359: * Notifies this component that it now has a parent component.
360: * When this method is invoked, the chain of parent components is
361: * set up with <code>KeyboardAction</code> event listeners.
362: *
363: *
364: * @see #registerKeyboardAction
365: */
366: public void addNotify() {
367: super .addNotify();
368: fc.addPropertyChangeListener(this );
369: SwingUtilities.invokeLater(new Runnable() {
370: public void run() {
371: thumbnails = null;
372: file = fc.getSelectedFile();
373: clean();
374: getImageInfo();
375: loadImages();
376: }
377: });
378: }
379:
380: public int getIconCount() {
381: return iconCount;
382: }
383:
384: /** This method is called from within the constructor to
385: * initialize the form.
386: * WARNING: Do NOT modify this code. The content of this method is
387: * always regenerated by the Form Editor.
388: */
389: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
390: private void initComponents() {
391:
392: jScrollPane1 = new javax.swing.JScrollPane();
393: textArea = new javax.swing.JTextArea();
394: label1 = new javax.swing.JLabel();
395: label2 = new javax.swing.JLabel();
396: label3 = new javax.swing.JLabel();
397: label4 = new javax.swing.JLabel();
398: label5 = new javax.swing.JLabel();
399: label6 = new javax.swing.JLabel();
400: iconNumLabel = new javax.swing.JLabel();
401: jLabel2 = new javax.swing.JLabel();
402:
403: setPreferredSize(new java.awt.Dimension(400, 250));
404:
405: textArea.setColumns(20);
406: textArea.setEditable(false);
407: textArea.setRows(5);
408: jScrollPane1.setViewportView(textArea);
409:
410: label1.setText(" ");
411:
412: label2.setText(" ");
413:
414: label3.setText(" ");
415:
416: label4.setText(" ");
417:
418: label5.setText(" ");
419:
420: label6.setText(" ");
421:
422: iconNumLabel.setText(" ");
423:
424: org.openide.awt.Mnemonics.setLocalizedText(jLabel2,
425: org.openide.util.NbBundle.getMessage(
426: MBMThumbnailAccessory.class, "LBL_MBMDetails")); // NOI18N
427:
428: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
429: this );
430: this .setLayout(layout);
431: layout
432: .setHorizontalGroup(layout
433: .createParallelGroup(
434: org.jdesktop.layout.GroupLayout.LEADING)
435: .add(
436: layout
437: .createSequentialGroup()
438: .addContainerGap()
439: .add(
440: layout
441: .createParallelGroup(
442: org.jdesktop.layout.GroupLayout.LEADING)
443: .add(
444: layout
445: .createSequentialGroup()
446: .add(
447: jScrollPane1,
448: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
449: 382,
450: Short.MAX_VALUE)
451: .addContainerGap())
452: .add(
453: layout
454: .createSequentialGroup()
455: .add(
456: jLabel2)
457: .addContainerGap(
458: 332,
459: Short.MAX_VALUE))
460: .add(
461: layout
462: .createSequentialGroup()
463: .add(
464: layout
465: .createParallelGroup(
466: org.jdesktop.layout.GroupLayout.LEADING)
467: .add(
468: layout
469: .createSequentialGroup()
470: .add(
471: label1)
472: .addPreferredGap(
473: org.jdesktop.layout.LayoutStyle.RELATED)
474: .add(
475: label2)
476: .addPreferredGap(
477: org.jdesktop.layout.LayoutStyle.RELATED)
478: .add(
479: label3)
480: .addPreferredGap(
481: org.jdesktop.layout.LayoutStyle.RELATED)
482: .add(
483: label4)
484: .addPreferredGap(
485: org.jdesktop.layout.LayoutStyle.RELATED)
486: .add(
487: label5)
488: .addPreferredGap(
489: org.jdesktop.layout.LayoutStyle.RELATED)
490: .add(
491: label6))
492: .add(
493: iconNumLabel))
494: .add(
495: 344,
496: 344,
497: 344)))));
498: layout
499: .setVerticalGroup(layout
500: .createParallelGroup(
501: org.jdesktop.layout.GroupLayout.LEADING)
502: .add(
503: layout
504: .createSequentialGroup()
505: .add(iconNumLabel)
506: .addPreferredGap(
507: org.jdesktop.layout.LayoutStyle.RELATED)
508: .add(
509: layout
510: .createParallelGroup(
511: org.jdesktop.layout.GroupLayout.BASELINE)
512: .add(label1)
513: .add(label2)
514: .add(label3)
515: .add(label4)
516: .add(label5)
517: .add(label6))
518: .addPreferredGap(
519: org.jdesktop.layout.LayoutStyle.RELATED)
520: .add(jLabel2)
521: .addPreferredGap(
522: org.jdesktop.layout.LayoutStyle.RELATED)
523: .add(
524: jScrollPane1,
525: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
526: 190, Short.MAX_VALUE)));
527: }// </editor-fold>//GEN-END:initComponents
528:
529: // Variables declaration - do not modify//GEN-BEGIN:variables
530: private javax.swing.JLabel iconNumLabel;
531: private javax.swing.JLabel jLabel2;
532: private javax.swing.JScrollPane jScrollPane1;
533: private javax.swing.JLabel label1;
534: private javax.swing.JLabel label2;
535: private javax.swing.JLabel label3;
536: private javax.swing.JLabel label4;
537: private javax.swing.JLabel label5;
538: private javax.swing.JLabel label6;
539: private javax.swing.JTextArea textArea;
540:
541: // End of variables declaration//GEN-END:variables
542:
543: static class IOThread extends Thread {
544: private BufferedInputStream bis;
545: private StringBuffer sb;
546:
547: IOThread(InputStream is, StringBuffer sb) {
548: bis = new BufferedInputStream(is, 2048);
549: this .sb = sb;
550: start();
551: }
552:
553: public void run() {
554: try {
555: int i;
556: while ((i = bis.read()) != 1) {
557: if (i == -1)
558: break;
559: if (sb != null) {
560: sb.append((char) i);
561: }
562: }
563: } catch (IOException ioEx) {
564: ///ioEx.printStackTrace();
565: }
566: try {
567: bis.close();
568: } catch (IOException ex) {
569: ex.printStackTrace();
570: }
571: }
572: }
573: }
|