001/* An AWT and Swing implementation of the the ImageDisplayInterface 002 that displays a Black and White image on the screen using the Picture class. 003 004 @Copyright (c) 1998-2014 The Regents of the University of California. 005 All rights reserved. 006 007 Permission is hereby granted, without written agreement and without 008 license or royalty fees, to use, copy, modify, and distribute this 009 software and its documentation for any purpose, provided that the 010 above copyright notice and the following two paragraphs appear in all 011 copies of this software. 012 013 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 014 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 015 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 016 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 017 SUCH DAMAGE. 018 019 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 020 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 021 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 022 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 023 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 024 ENHANCEMENTS, OR MODIFICATIONS. 025 026 PT_COPYRIGHT_VERSION 2 027 COPYRIGHTENDKEY 028 */ 029package ptolemy.domains.sdf.lib.vq; 030 031import java.awt.Container; 032import java.awt.Image; 033import java.awt.image.ColorModel; 034import java.awt.image.MemoryImageSource; 035 036import javax.swing.JFrame; 037import javax.swing.SwingUtilities; 038 039import ptolemy.data.AWTImageToken; 040import ptolemy.data.IntMatrixToken; 041import ptolemy.data.Token; 042import ptolemy.kernel.util.IllegalActionException; 043import ptolemy.kernel.util.InternalErrorException; 044import ptolemy.media.Picture; 045 046/////////////////////////////////////////////////////////////////// 047////ImageDisplayJavaSE 048 049/** 050<p> 051ImageDisplayJavaSE is the implementation of the ImageDisplayInterface that uses AWT and Swing 052classes.</p> 053 054@author Jianwu Wang, Based on code by James Yeh, Edward A. Lee 055@version $Id$ 056@since Ptolemy II 10.0 057@Pt.ProposedRating 058@Pt.AcceptedRating 059 */ 060 061public class ImageDisplayJavaSE 062 extends ptolemy.actor.lib.image.ImageDisplayJavaSE 063 implements ptolemy.domains.sdf.lib.vq.ImageDisplayInterface { 064 065 /////////////////////////////////////////////////////////////////// 066 //// public methods //// 067 068 /** Display the specified token. This must be called in the Swing 069 * event thread. 070 * @param in The token to display 071 */ 072 @Override 073 public void display(final Token in) { 074 // Display probably to be done in the Swing event thread. 075 Runnable doDisplay = new Runnable() { 076 @Override 077 public void run() { 078 _display(in); 079 } 080 }; 081 082 SwingUtilities.invokeLater(doDisplay); 083 } 084 085 /////////////////////////////////////////////////////////////////// 086 //// private methods //// 087 088 /** Convert an IntMatrixToken to a Packed RGB Image. 089 * @param token An IntMatrixToken defining the black and white image. 090 * @return A packed RGB array of integers 091 */ 092 private int[] _convertBWImageToPackedRGBImage(IntMatrixToken token) { 093 int[][] frame = token.intMatrix(); 094 int xSize = token.getColumnCount(); 095 int ySize = token.getRowCount(); 096 097 int[] RGBbuffer = new int[xSize * ySize]; 098 099 // convert the B/W image to a packed RGB image. This includes 100 // flipping the image upside down. (When it is drawn, it gets 101 // drawn from bottom up). 102 int i; 103 104 // convert the B/W image to a packed RGB image. This includes 105 // flipping the image upside down. (When it is drawn, it gets 106 // drawn from bottom up). 107 int j; 108 109 // convert the B/W image to a packed RGB image. This includes 110 // flipping the image upside down. (When it is drawn, it gets 111 // drawn from bottom up). 112 int index = 0; 113 114 for (j = ySize - 1; j >= 0; j--) { 115 for (i = 0; i < xSize; i++, index++) { 116 RGBbuffer[index] = 255 << 24 | (frame[j][i] & 255) << 16 117 | (frame[j][i] & 255) << 8 | frame[j][i] & 255; 118 } 119 } 120 121 return RGBbuffer; 122 } 123 124 /** Display the specified token. This must be called in the Swing 125 * event thread. 126 * @param in The token to display. 127 */ 128 private void _display(Token in) { 129 // FIXME: lots of code duplication with parent and 130 // with ptolemy/actor/lib/image/ImageTableau.java 131 // We could try to refactor this, but it would get tricky 132 int xSize = ((IntMatrixToken) in).getColumnCount(); 133 int ySize = ((IntMatrixToken) in).getRowCount(); 134 135 if (_imageWindowFrame != null) { 136 // We have a frame already, so just create an AWTImageToken 137 // and tell the effigy about it. 138 MemoryImageSource imageSource = new MemoryImageSource(xSize, ySize, 139 ColorModel.getRGBdefault(), 140 _convertBWImageToPackedRGBImage((IntMatrixToken) in), 0, 141 xSize); 142 imageSource.setAnimated(true); 143 144 // Sadly, we can't easily create an image without some sort 145 // of graphical context here. This is a huge shortcoming of 146 // awt. Just because I'm operating on images, I should not 147 // need a frame. 148 Image image = _imageWindowFrame.getContentPane() 149 .createImage(imageSource); 150 151 AWTImageToken token = new AWTImageToken(image); 152 153 try { 154 _effigy.setImage(token); 155 } catch (IllegalActionException e) { 156 throw new InternalErrorException(e); 157 } 158 } else if (_picture != null) { 159 // If the size has changed, have to recreate the Picture object. 160 if (_oldXSize != xSize || _oldYSize != ySize) { 161 _oldXSize = xSize; 162 _oldYSize = ySize; 163 164 Container container = _picture.getParent(); 165 166 container.remove(_picture); 167 168 _picture = new Picture(xSize, ySize); 169 170 //_picture.setImage(image); 171 _picture.setImage( 172 _convertBWImageToPackedRGBImage((IntMatrixToken) in)); 173 _picture.setBackground(null); 174 container.add("Center", _picture); 175 container.validate(); 176 container.invalidate(); 177 container.repaint(); 178 container.doLayout(); 179 180 Container c = container.getParent(); 181 182 while (c.getParent() != null) { 183 c.invalidate(); 184 c.validate(); 185 c = c.getParent(); 186 187 if (c instanceof JFrame) { 188 ((JFrame) c).pack(); 189 } 190 } 191 } else { 192 // The _imageWindowFrame is null, the size has not changed, set the image. 193 _picture.setImage( 194 _convertBWImageToPackedRGBImage((IntMatrixToken) in)); 195 _picture.displayImage(); 196 _picture.repaint(); 197 } 198 } 199 } 200 201}