001 /* EVolve - an Extensible Software Visualization Framework 002 * Copyright (C) 2001-2002 Qin Wang 003 * 004 * This library is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU Library General Public 006 * License as published by the Free Software Foundation; either 007 * version 2 of the License, or (at your option) any later version. 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Library General Public License for more details. 013 * 014 * You should have received a copy of the GNU Library General Public 015 * License along with this library; if not, write to the 016 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 017 * Boston, MA 02111-1307, USA. 018 */ 019 020 /* 021 * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/ 022 */ 023 024 package EVolve.visualization; 025 026 import java.awt.Color; 027 import java.awt.Graphics2D; 028 import java.awt.image.BufferedImage; 029 import java.util.ArrayList; 030 import java.util.HashMap; 031 import java.util.Iterator; 032 033 import EVolve.exceptions.NoDataPlotException; 034 035 /** 036 * Automatic expanding image. 037 */ 038 public class AutoImage implements Cloneable{ 039 protected short[][] image; // the image 040 protected int w, h; // width and height of the content 041 protected int wMax, hMax; // width and height of the image 042 protected int imageWidth, imageHeight; 043 044 protected HashMap object2Int,Int2Object; 045 046 private ArrayList phases; 047 private Color gray; 048 049 /** 050 * Creates an auto-image. 051 */ 052 public AutoImage() { 053 w = 0; 054 h = 0; 055 wMax = 200; 056 hMax = 200; 057 image = new short[wMax][hMax]; 058 for (int i = 0; i < wMax; i++) { 059 for (int j = 0; j < hMax; j++) { 060 image[i][j] = 0; 061 } 062 } 063 object2Int = new HashMap(); 064 Int2Object = new HashMap(); 065 object2Int.put(null,new Integer(0)); 066 Int2Object.put(new Integer(0),null); 067 gray = new Color(234,234,234); 068 } 069 070 /** 071 * Sets the color of a pixel. 072 * 073 * @param x position on X-axis 074 * @param y position on Y-axis 075 * @param color the color 076 */ 077 public void setColor(int x, int y, Object color) { 078 if ((x >= wMax) || (y >= hMax)) { 079 while (x >= wMax) { 080 wMax += 200; 081 } 082 while (y >= hMax) { 083 hMax += 200; 084 } 085 086 short[][] newImage = new short[wMax][hMax]; 087 for (int i = 0; i < wMax; i++) { 088 for (int j = 0; j < hMax; j++) { 089 newImage[i][j] = 0; 090 } 091 } 092 for (int i = 0; i < w; i++) { 093 for (int j = 0; j < h; j++) { 094 newImage[i][j] = image[i][j]; 095 } 096 } 097 image = newImage; 098 } 099 100 if (object2Int.containsKey(color)) { 101 image[x][y] = ((Integer)object2Int.get(color)).shortValue(); 102 } else { 103 short size = (short)object2Int.size(); 104 object2Int.put(color,new Integer(size)); 105 Int2Object.put(new Integer(size),color); 106 image[x][y] = size; 107 } 108 109 if (x >= w) { 110 w = x + 1; 111 } 112 if (y >= h) { 113 h = y + 1; 114 } 115 } 116 117 /** 118 * Gets the color of a pixel. 119 * 120 * @param x position on X-axis 121 * @param y position on Y-axis 122 * @return the color 123 */ 124 public Object getColor(int x, int y) { 125 if ((image!=null) && ((x < 0) || (y < 0) || (x >= image.length) || (y >= image[0].length))) { 126 return null; 127 } else { 128 int index = image[x][y]; 129 return Int2Object.get(new Integer(index)); 130 } 131 } 132 133 public Object getSortedColor(ReferenceDimension xAxis, ReferenceDimension yAxis,int x,int y) { 134 int xMappedId,yMappedId; 135 xMappedId = (xAxis == null) ? x : xAxis.getOriginMappedId(x); 136 yMappedId = (yAxis == null) ? y : yAxis.getOriginMappedId(y); 137 138 if ((xMappedId >= wMax) || (yMappedId >= hMax) || (xMappedId < 0) || (yMappedId < 0)) 139 return null; 140 else { 141 int index = image[xMappedId][yMappedId]; 142 if (index == 0) 143 return null; 144 else 145 return (Color)Int2Object.get(new Integer(index)); 146 } 147 } 148 149 /** 150 * Gets the buffered-image. 151 * 152 * @return buffered-image 153 */ 154 public BufferedImage getImage() throws NoDataPlotException { 155 156 if (w*h == 0) throw new NoDataPlotException(); 157 158 BufferedImage returnVal = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 159 Graphics2D g2 = (Graphics2D)returnVal.getGraphics(); 160 161 g2.setColor(Color.white); 162 g2.fillRect(0, 0, w, h); 163 164 if ((phases != null)&&(phases.size()!=0)) { 165 int lastX = 0; 166 167 for (int i=0; i<phases.size(); i++) { 168 int phaseEnd = ((Integer)phases.get(i)).intValue(); 169 170 if ((phaseEnd <= 0)||(phaseEnd>=w)) continue; 171 172 g2.setColor(i%2 == 0 ? gray : Color.white); 173 g2.fillRect(lastX,0,phaseEnd,h); 174 lastX = phaseEnd; 175 } 176 g2.setColor(phases.size()%2 == 0 ? gray : Color.white); 177 g2.fillRect(lastX,0,w,h); 178 } 179 180 for (int i = 0; i < w; i++) { 181 for (int j = 0; j < h; j++) { 182 if (image[i][j] != 0) { 183 returnVal.setRGB(i, j, ((Color)Int2Object.get(new Integer(image[i][j]))).getRGB()); 184 } 185 } 186 } 187 188 return returnVal; 189 } 190 191 /** 192 * Sorts the image. 193 * 194 * @param xAxis dimension that represents the X-axis, null if doesn't need to be sorted 195 * @param yAxis dimension that represents the Y-axis, null if doesn't need to be sorted 196 * @return sorted image 197 */ 198 public AutoImage getSortedImage(ReferenceDimension xAxis, ReferenceDimension yAxis) { 199 AutoImage returnVal = new AutoImage(); 200 for (int i = 0; i < w; i++) { 201 for (int j = 0; j < h; j++) { 202 int x, y; 203 if (xAxis == null) { 204 x = i; 205 } else { 206 x = xAxis.getSortedIndex(i); 207 } 208 if (yAxis == null) { 209 y = j; 210 } else { 211 y = yAxis.getSortedIndex(j); 212 } 213 if ((x != -1) && (y != -1)) { 214 returnVal.setColor(x, y, Int2Object.get(new Integer(image[i][j]))); 215 } 216 } 217 } 218 return returnVal; 219 } 220 221 public int getDimension(int dim) { 222 if (dim == -1) return image.length; 223 224 return image[dim].length; 225 } 226 227 public int getW() { 228 return w; 229 } 230 231 public int getH() { 232 return h; 233 } 234 235 public void setImageSize(int width, int height) { 236 imageWidth = w; 237 imageHeight = h; 238 } 239 240 public short[][] getImageDataArray() { 241 return image; 242 } 243 244 public void setPhases(ArrayList phases) { 245 this.phases = phases; 246 } 247 248 public Object clone() { 249 AutoImage o = null; 250 try { 251 o = (AutoImage)super.clone(); 252 } catch (CloneNotSupportedException e) { 253 e.printStackTrace(); 254 return o; 255 } 256 257 o.Int2Object = new HashMap(); 258 o.object2Int = new HashMap(); 259 o.object2Int.put(null,new Integer(0)); 260 o.Int2Object.put(new Integer(0),null); 261 o.image = new short[image.length][]; 262 for (int i=0; i<image.length; i++) { 263 o.image[i] = new short[image[i].length]; 264 for (int j=0; j<image[i].length; j++) { 265 o.image[i][j] = image[i][j]; 266 } 267 } 268 Iterator it = object2Int.keySet().iterator(); 269 while (it.hasNext()) { 270 Object key = it.next(); 271 o.object2Int.put(key, object2Int.get(key)); 272 } 273 it = Int2Object.keySet().iterator(); 274 while (it.hasNext()) { 275 Object key = it.next(); 276 o.Int2Object.put(key, Int2Object.get(key)); 277 } 278 return o; 279 } 280 }