an det skrivna Java-programmet. Denna kommer till viss del beh¨ova skrivas om f¨or att kunna hantera bildbehandlingens input.
Det kan ocks˚a konstateras att skriftliga programmeringsspr˚ak ger st¨orre friheter ¨an grafiska d˚a utvecklaren ges st¨orre m¨ojlighet att manipulera detaljer i koden. Detta gav exempelvis m¨ojligheten att l˚ata programmet sj¨alv r¨akna ut flera parametrar i bilderna ist¨allet f¨or att anv¨andaren manuellt m˚aste skriva in dem och riskera fel-aktiga v¨arden. Ett exempel p˚a detta ¨ar att LV-koden kr¨aver en input av antalet projektioner och kulor i respektive projektion, medan den ¨oversatta Java-koden kan r¨akna ut detta p˚a egen hand.
5.5 Graphical User Interface
Gr¨anssnittet f¨or LV-koden ¨ar r¨origt och sv˚art att anv¨anda utan att f¨orst f¨orst˚a den bakomliggande koden. En av anledningarna till detta ¨ar att programmet har m˚anga parametrar som anv¨andaren sj¨alv m˚aste st¨alla in, samt att interfacet in-neh˚aller m˚anga detaljer och v¨arden som ¨ar irrelevanta f¨or anv¨andaren.
D˚a kalibrering beh¨over ske med j¨amna mellanrum ¨ar det f¨ordelaktigt om anv¨andaren p˚a egen hand kan sk¨ota s˚a stora delar av kalibreringen som m¨ojligt, utan att beh¨ova ta in en extern part.
5.6 Framtiden
I skrivande stund kan Java-programmet enbart k¨oras fram till att banorna f¨or kulor-na visas. F¨or att f¨ardigst¨alla detta m˚aste fr¨amst de nuvarande fungerande delarna kopplas ihop med matematiken som ber¨aknar slant, skew och tilt.
5.6 Framtiden 5 DISKUSSION
Java-koden inneh˚aller ¨aven ett antal buggar som det inte fanns tid f¨or att ta bort. Exempel p˚a dessa ¨ar:
• Koden g˚ar inte att exekvera om bilden inte ¨ar i ”liggande” l¨age och inte har dimensionerna 2048*1024 pixlar. Detta m˚aste d˚a korrigeras i koden. D˚a filerna ¨
ar i formatet .bin, som enbart best˚ar av en array, ¨ar det en om¨ojlighet att l˚ata programmet sj¨alv ber¨akna storleken p˚a bilderna. F¨or att l¨osa detta beh¨ovs en ruta d¨ar anv¨andaren sj¨alv f˚ar skriva in dimensionerna.
• F¨or varje g˚ang Region of interest v¨aljs sparas en vit ruta i bilden ¨aven om anv¨andaren inte ¨ar n¨ojd och ¨onskar g¨ora en ny (se Figur 10). Detta inneb¨ar att f¨or varje f¨ors¨ok blir det fler rutor och d¨armed sv˚arare och sv˚arare att skapa en bra ROI. En l¨osning ¨ar att placera en osynlig ”JFrame”¨over bilden d¨ar markeringen kan ritas och suddas ut utan att p˚averka den underliggande bilden.
Figur 10: Val av Region of interest. Den vita rutan har anv¨andaren ritat ut. Allt utanf¨or rutan behandlar inte programmet.
Det finns ¨aven andra m¨ojligheter att f¨orb¨attra programmet. Exempelvis kan koden beh¨ova e↵ektiviseras d˚a den allokerar mycket av datorns minne, vilket kan leda till att programmet kraschar om det k¨ors p˚a en ¨aldre dator. Det kan ¨aven kontrolleras huruvida kulorna p˚a vissa bilder f¨orsvinner ur bild eller korsar varandras banor och i dessa fall ta bort dessa ur ber¨akningarna. Detta skulle inneb¨ara att valet av ROI inte l¨angre ¨ar n¨odv¨andigt och att anv¨andaren enbart beh¨over v¨alja .bin-fil och trycka p˚a en knapp f¨or att f˚a resultaten.
Programmet borde ¨aven detektera huruvida de funna objekten har formen av en cirkel. Den nuvarande koden kontrollerar endast att avst˚andet fr˚an objektets topp till botten och fr˚an h¨oger till v¨anster ¨ar tillr¨ackligt stort f¨or att vara en kula (se
5.6 Framtiden 5 DISKUSSION
Appendix E). Detta betyder att artefakter av tillr¨acklig storlek och kontrast kommer att tolkas som kulor. Detta ¨ar ett av de problem som uppst˚att d˚a den simulerade datan testades med Java-koden.
6 SLUTSATS
6 Slutsats
Modifiering av Labview-koden visade sig vara r¨attningar i matematiken f¨or ber¨akning av slant och tilt samt ¨andringar f¨or bildernas filformat och pixel- till millimeterra-tion. Dock ¨ar projektet, som det ser ut nu, inte f¨ardigst¨allt. LabView-koden m˚aste valideras med STH’s mikro-CT och kan komma beh¨ova ytterliggare modifieringar efter f¨ors¨ok. D˚a den givna datan fr˚an University of Arizona samt den simulerade datan g˚ar att k¨ora i LabView med goda resultat, antyder det att inga fler stora ¨
andringar ¨ar n¨odv¨andiga f¨or att uppn˚a m˚alet.
Den hittills skrivna Java-koden fungerar n¨ast intill optimalt, med undantag f¨or ett par buggar. De matematiska delarna ¨ar ej kopplade till varandra men fungerar v¨al separat.
Att anv¨anda ett annat spr˚ak f¨or ¨overs¨attning med fler inbyggda funktioner f¨or detta ¨
andam˚al, s˚asom Python, hade varit att f¨oredra framf¨or Java d˚a arbetet med att skriva koden hade g˚att fortare.
7 Referenser
[1] D. J. Brenner and E. J. Hall, “Computed Tomography — An Increasing Source of Radiation Exposure,” New England Journal of Medicine, vol. 357, no. 22, p. 2277, Nov. 2007, accessed: 2015-05-28. [Online]. Available: http://www.nejm.org/doi/abs/10.1056/NEJMra072149
[2] L. von Smekal, M. Kachelriess, E. Stepina, and W. A. Kalender, “Geometric mi-salignment and calibration in cone-beam tomography,” Medical Physics, vol. 31, no. 12, p. 3246, Dec. 2004.
[3] J. W. Moore, “Adaptive X-ray Computed Tomography,” The University of Ari-zone, p. 45, 2011.
[4] “Flat panel sensor C7942ca-22,” accessed: 2015-05-21. [Online]. Avai-lable: http://www.hamamatsu.com/jp/en/product/alpha/F/4158/C7942CA-22/index.html
[5] L. von Smekal, M. Kachelriess, E. Stepina, and W. A. Kalender, “Geometric mi-salignment and calibration in cone-beam tomography,” Medical Physics, vol. 31, no. 12, p. 3244, Dec. 2004.
[6] ——, “Geometric misalignment and calibration in cone-beam tomography,” Me-dical Physics, vol. 31, no. 12, pp. 3242–3266, Dec. 2004.
[7] O. Corporation, “JavaTM Platform, Standard Edition 7 API Specification,” accessed: 2015-04-20. [Online]. Available: http://docs.oracle.com/javase/7/docs/api/
[8] stack exchange inc, “Stackoverflow,” accessed: 2015-04 till 2015-06. [Online]. Available: www.stackoverflow.com
[9] D. Flanagan, Java in a nutshell: a desktop quick reference, 3rd ed., ser. The Java series (O’Reilly). Beijing ;Cambridge: O’Reilly, 1999, kap. 1.2 - Key Benefits of Java, Kap. 8 - Java Development Tools (The Java Debugger).
[10] K. Arnold, J. Gosling, and D. Holmes, The Java programming language, 4th ed. Upper Saddle River, NJ: Addison-Wesley, 2006.
[11] Hamamatsu, “guava-libraries google, inc,” accessed: 2015-04-15. [Online]. Available: https://code.google.com/p/guava-libraries/
[12] C. Kvitka, “Java: Twenty Years of Innovation,” Sep. 2014, accessed: 2015-05-15. [Online]. Available: https://community.oracle.com/community/java/javas-20th-anniversary
Appendix
A Banbild
Bild av kulornas banor (Trajectory)
B Teori
Enligt Von Smekal m.fl. [6] kr¨avdes bara den diskreta fouriertransformen av k 3 givet av: Uk= 2 N N X n=1 uncos(kan), k = 0, ..., N/2 e Uk = 2 N N X n=1 unsin(kan), k = 1, ..., N/2 1 (4)
d¨ar Uk ¨ar den reella fourierkoefficienten, eUk ¨ar den komplexa fourierkoefficienten, N ¨
ar antalet projektioner, an¨ar punktens position p˚a cirkeln och un¨ar x-koordinaterna. Samma ber¨akning skedde f¨or y-koordinaterna och betecknades Vk f¨or den reella fou-rierkoefficienten och eVk f¨or den komplexa.
Ber¨akning av d-v¨arden: d20= (U1 U3)U2 ( eU3 Ue1) eU2 d21= (U1+ U3) eU2 ( eU3+ eU1)U2 d22= 1 2(U 2 3 U12+ eU32 Ue12) d00= 1 2((U0+ U2)d20+ eU2d21+ 2U1d22) d01= 1 2( eU2d20+ (U0 U2)d21+ 2 eU1d22) d02= 1 2(U1d20+ eU1d21+ U0d22) d10= 1 2((V0+ V2)d20+ eV2d21+ 2V1d22) d11= 1 2( eV2d20+ (V0 V2)d21+ 2 eV1d22) d12= 1 2(V1d20+ eV1d21+ V0d22) (5) d002= d02 d22 d 0 12= d12 d22 d020= d20 d22 d 0 21= d21 d22 (6) Ber¨akning av c-v¨arden: ✓ c00 c01 ◆ = 1 d0 202+ d0 212 ✓ d020 d021 d021 d020 ◆ " 1 2 U2 Ue2 e U2 U2 ! ✓ d020 d021 ◆ + ✓ U1 e U1 ◆# + ✓ U0/2 0 ◆ (7) ✓ c10 c11 ◆ = 1 d0202+ d0212 ✓ d020 d021 d021 d020 ◆ " 1 2 V2 Ve2 e V2 V2 ! ✓ d020 d021 ◆ + ✓ V1 e V1 ◆# + ✓ V0/2 0 ◆ Ber¨akning av A,B,C,E,F: A = c00sin⌘ + c10cos⌘ B = c01cos⌘ c11sin⌘ C = c00cos⌘ c10sin⌘ E = d002sin⌘ + d012cos⌘ F = d002cos⌘ d012sin⌘ (8)
calculateValues.java 1public class calculateValues {
2 private int sense = 1; 3
4 public calculateValues(int[][][] in, int x, int y) { 5 fullCalculation(in, x, y);
6 }
7
8 publicint[][][] shiftCoords(int[][][] in, int xSize, int ySize) { 9 int[][][] temp = new int[in.length][in[0].length][in[0][0].length]; 10 for (int i = 0; i < temp.length; i++) {
11 for (int j = 0; j < temp[0][0].length; j++) { 12 temp[i][1][j] = (ySize / 2) - in[i][1][j]; 13 temp[i][0][j] = in[i][0][j] - (xSize / 2); 14 } 15 } 16 returntemp; 17 } 18
19 publicdouble[] getSkew(double[][] cVals, int ballsize) { 20 double[] skew = new double[ballsize];
21 for (int i = 0; i < ballsize; i++) {
22 skew[i] = Math.atan(-cVals[3][i] / cVals[1][i]);
23 }
24 returnskew; 25 }
26
27 publicvoid fullCalculation(int[][][] in, int xSize, int ySize) { 28 int[][][] shifted = shiftCoords(in, xSize, ySize);
29 double[][] uComplexArray = getComplexFourierCoeffs(in[0][0].length, 30 shifted, in.length, 0);
31 double[][] uRealArray = getRealFourierCoeffs(in[0][0].length, shifted, 32 in.length, 0);
33 double[][] vComplexArray = getComplexFourierCoeffs(in[0][0].length, 34 shifted, in.length, 1);
35 double[][] vRealArray = getRealFourierCoeffs(in[0][0].length, shifted, 36 in.length, 1);
37 double[][] dValues = getDvalues(uRealArray, uComplexArray, vRealArray, 38 vComplexArray, in[0][0].length, in.length);
39 double[][] cValues = getCvalues(dValues, uRealArray, uComplexArray, 40 vRealArray, vComplexArray, in.length);
41 double[] skew = getSkew(cValues, in.length);
42 double[] Rprime = getRprime(cValues, skew, in.length); 43 double[] dx = getDx(dValues, skew, in.length); 44 double[] dz = getDz(dValues, skew, in.length); 45 doublerad = 180 / Math.PI;
46 doublemm = 0.048; 47 doublesumSkew = 0; 48 doublesumRprime = 0; 49 doublesumDx = 0; 50 doublesumDz = 0;
51 for (int i = 0; i < in.length; i++) { 52 sumSkew = sumSkew + skew[i]; 53 sumRprime = sumRprime + Rprime[i]; 54 sumDx = sumDx + dx[i];
55 sumDz = sumDz + dz[i];
56 }
57 doublefixSkew = sumSkew * rad / in.length; 58 doublefixRprime = sumRprime * mm / in.length; 59 doublefixDx = sumDx * mm / in.length; 60 doublefixDz = sumDz * mm / in.length; 61 }
62
Page 1
calculateValues.java
63 public double[] getDz(double[][] dVals, double[] skew, int ballSize) { 64 double[] dz = new double[ballSize];
65 for (int i = 0; i < ballSize; i++) {
66 dz[i] = -dVals[3][i] * Math.sin(skew[i]) - dVals[6][i]
67 * Math.cos(skew[i]);
68 }
69 return dz;
70 }
71
72 public double[] getDx(double[][] dVals, double[] skew, int ballSize) { 73 double[] dx = new double[ballSize];
74 for (int i = 0; i < ballSize; i++) {
75 dx[i] = dVals[8][i] * Math.sin(skew[i]) - dVals[5][i]
76 * Math.cos(skew[i]);
77 }
78 return dx;
79 }
80
81 public double[] getRprime(double[][] cVals, double[] skew, int ballSize) { 82 double[] Rp = new double[ballSize];
83 for (int i = 0; i < ballSize; i++) {
84 Rp[i] = cVals[1][i] * Math.cos(skew[i]) - cVals[3][i]
85 * Math.sin(skew[i]);
86 }
87 return Rp;
88 }
89
90 public double[][] getCvalues(double[][] dValues, double[][] ur, 91 double[][] uc, double[][] vr, double[][] vc, int ballSize) { 92 double[][] cValues = new double[4][ballSize];
93 for (int i = 0; i < ballSize; i++) { 94 cValues[0][i] = dValues[0][i] 95 * (0.5 * (dValues[0][i] * ur[2][i] + dValues[1][i] 96 * uc[1][i]) + ur[1][i]) 97 + dValues[1][i] 98 * (0.5 * (dValues[0][i] * uc[1][i] - dValues[1][i] 99 * ur[2][i]) + uc[0][i]) + ur[0][i] / 2; 100 cValues[1][i] = dValues[1][i] 101 * (0.5 * (dValues[0][i] * ur[2][i] + dValues[1][i] 102 * uc[1][i]) + ur[1][i]) 103 - dValues[0][i] 104 * (0.5 * (dValues[0][i] * uc[1][i] - dValues[1][i] 105 * ur[2][i]) + uc[0][i]); 106 cValues[2][i] = dValues[0][i] 107 * (0.5 * (dValues[0][i] * vr[2][i] + dValues[1][i] 108 * vc[1][i]) + vr[1][i]) 109 + dValues[1][i] 110 * (0.5 * (dValues[0][i] * vc[1][i] - dValues[1][i] 111 * vr[2][i]) + vc[0][i]) + vr[0][i] / 2; 112 ; 113 cValues[3][i] = dValues[1][i] 114 * (0.5 * (dValues[0][i] * vr[2][i] + dValues[1][i] 115 * vc[1][i]) + vr[1][i]) 116 - dValues[0][i] 117 * (0.5 * (dValues[0][i] * vc[1][i] - dValues[1][i] 118 * vr[2][i]) + vc[0][i]); 119 } 120 return cValues; 121 } 122
123 public double[][] getDvalues(double[][] ur, double[][] uc, double[][] vr, 124 double[][] vc, int imgSize, int ballSize) {
calculateValues.java 125 double dvalues[][] = new double[9][ballSize]; 126 for (int i = 0; i < ballSize; i++) {
127 // d20 128 dvalues[0][i] = (ur[1][i] - ur[3][i]) * ur[2][i] 129 - (uc[2][i] - uc[0][i]) * uc[1][i]; 130 // d21 131 dvalues[1][i] = (ur[1][i] + ur[3][i]) * uc[1][i] 132 - (uc[2][i] + uc[0][i]) * ur[2][i]; 133 // d22 134 dvalues[2][i] = 0.5 * (Math.pow(ur[3][i], 2)
135 - Math.pow(ur[1][i], 2) + Math.pow(uc[2][i], 2) + Math.pow(
136 uc[0][i], 2)); 137 // d00 138 dvalues[3][i] = 0.5 * ((ur[0][i] + ur[2][i]) * dvalues[0][i] 139 + uc[1][i] * dvalues[1][i] + 2 * ur[1][i] * dvalues[2][i]); 140 // d01 141 dvalues[4][i] = 0.5 * (uc[1][i] * dvalues[0][i] 142 + (ur[0][i] - ur[2][i]) * dvalues[1][i] + 2 * uc[0][i] 143 * dvalues[2][i]); 144 // d02 145 dvalues[5][i] = 0.5 * (ur[1][i] * dvalues[0][i] + uc[0][i] 146 * dvalues[1][i] + ur[0][i] * dvalues[2][i]); 147 // d10 148 dvalues[6][i] = 0.5 * ((vr[0][i] + vr[2][i]) * dvalues[0][i] 149 + vc[1][i] * dvalues[1][i] + 2 * vr[1][i] * dvalues[2][i]); 150 // d11 151 dvalues[7][i] = 0.5 * (vc[1][i] * dvalues[0][i] 152 + (vr[0][i] - vr[2][i]) * dvalues[1][i] + 2 * vc[0][i] 153 * dvalues[2][i]); 154 // d12 155 dvalues[8][i] = 0.5 * (vr[1][i] * dvalues[0][i] + vc[0][i] 156 * dvalues[1][i] + vr[0][i] * dvalues[2][i]); 157 } 158 return dvalues; 159 } 160
161 public double[][] getComplexFourierCoeffs(int noOfProjections, 162 int[][][] coordinateVector, int ballSize, int UorV) { 163 double[][] complexSum = new double[3][ballSize];
164 double[][] Complex1 = new double[noOfProjections][ballSize]; 165 double[][] Complex2 = new double[noOfProjections][ballSize]; 166 double[][] Complex3 = new double[noOfProjections][ballSize]; 167 double radians = Math.PI / 180;
168 double ProjectionAngle = 360 / noOfProjections; 169 for (int i = 0; i < noOfProjections; i++) { 170 for (int j = 0; j < ballSize; j++) {
171 Complex1[i][j] = Math.sin(1 * radians * ProjectionAngle * i
172 * sense);
173 Complex2[i][j] = Math.sin(2 * radians * ProjectionAngle * i
174 * sense);
175 Complex3[i][j] = Math.sin(3 * radians * ProjectionAngle * i
176 * sense);
177 }
178 }
179 for (int i = 0; i < noOfProjections; i++) { 180 for (int j = 0; j < ballSize; j++) { 181 complexSum[0][j] = complexSum[0][j]
182 + coordinateVector[j][UorV][i] * Complex1[i][j] * 2
183 / noOfProjections;
184 complexSum[1][j] = complexSum[1][j]
calculateValues.java 187 complexSum[2][j] = complexSum[2][j]
188 + coordinateVector[j][UorV][i] * Complex3[i][j] * 2
189 / noOfProjections; 190 } 191 } 192 return complexSum; 193 } 194
195 public double[][] getRealFourierCoeffs(int noOfProjections, 196 int[][][] coordinateVector, int ballSize, int UorV) { 197 double[][] realSum = new double[4][ballSize];
198 double[][] Real1 = new double[noOfProjections][ballSize]; 199 double[][] Real2 = new double[noOfProjections][ballSize]; 200 double[][] Real3 = new double[noOfProjections][ballSize]; 201 double[][] Real4 = new double[noOfProjections][ballSize]; 202 double radians = Math.PI / 180;
203 double ProjectionAngle = 360 / noOfProjections; 204 for (int i = 0; i < noOfProjections; i++) { 205 for (int j = 0; j < ballSize; j++) {
206 Real1[i][j] = Math.cos(0 * radians * ProjectionAngle * i
207 * sense);
208 Real2[i][j] = Math.cos(1 * radians * ProjectionAngle * i
209 * sense);
210 Real3[i][j] = Math.cos(2 * radians * ProjectionAngle * i
211 * sense);
212 Real4[i][j] = Math.cos(3 * radians * ProjectionAngle * i
213 * sense);
214 }
215 }
216 for (int i = 0; i < noOfProjections; i++) { 217 for (int j = 0; j < ballSize; j++) {
218 realSum[0][j] = realSum[0][j] + Real1[i][j]
219 * coordinateVector[j][UorV][i] * 2 / noOfProjections; 220 realSum[1][j] = realSum[1][j] + Real2[i][j]
221 * coordinateVector[j][UorV][i] * 2 / noOfProjections; 222 realSum[2][j] = realSum[2][j] + Real3[i][j]
223 * coordinateVector[j][UorV][i] * 2 / noOfProjections; 224 realSum[3][j] = realSum[3][j] + Real4[i][j]
225 * coordinateVector[j][UorV][i] * 2 / noOfProjections;
226 }
227 }
228 return realSum;
229 }
Controller.java 1import java.awt.image.BufferedImage; 3
4public class Controller implements Observe { 5 imageJFileChooser iJCF; 6 GUI gui; 7 ImageProcessing IP; 8 ROI roi; 9 Trajectories traj; 10 int width = 2400; 11 int height = 2400; 12 int noOfImages; 13 int noOfBalls; 14 int[][][] allCoordsArray; 15 int contrastInt = 1; 16 int mx1, mx2, my1, my2 = 0; 17
18 // CONSTRUCTOR
19 public Controller() {
20 iJCF = new imageJFileChooser();
21 try {
22 gui = new GUI(iJCF); 23 } catch (IOException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }
27 iJCF.AddObserver(this); 28 gui.AddObserver(this); 29 }
30
31 publicvoid runImageProcess() { 32 noOfBalls = 0;
33 noOfImages = roi.getNoOfImages(iJCF.getFileName()); 34 boolean firstImageRun = true;
35 String filename = iJCF.getFileName().replace("001.bin", ""); 36 String tempFilename;
37 for (int i = 1; i <= noOfImages; i++) { 38 if (firstImageRun) {
39 IP = new ImageProcessing(iJCF.getFileName(), contrastInt, mx1,
40 mx2, my1, my2);
41 allCoordsArray = new int[getNoOfBallsFromImage()][2][noOfImages]; 42 allCoordsArray[0][0][0] = IP.getCoordList().get(0).get(0); 43 allCoordsArray[0][1][0] = IP.getCoordList().get(0).get(1); 44 firstImageRun = false;
45 } else {
46 if (i < 10) {
47 tempFilename = filename + "00" + i + ".bin"; 48 } elseif (i < 100) {
49 tempFilename = filename + "0" + i + ".bin";
50 } else {
51 tempFilename = filename + i + ".bin";
52 }
53 System.out.printf("Image processed: %d\n", i); 54 gui.setNoOfImagesLabel(i);
55 IP = new ImageProcessing(tempFilename, contrastInt, mx1, mx2,
56 my1, my2);
57 new Thread() {
58 public void run() {
59 setNoOfBallsLabelView();
60 }
61 }.start();
62 // Show image in Frame
63 new Thread() {
Page 1
Controller.java
64 public void run() {
65 BufferedImage panelImage = IP.scaleBufferedImage(
66 IP.getBufferedImage(), 0.2);
67 gui.setImageToGoPanel(panelImage);
68 }
69 }.start();
70 for (int j = 0; j < IP.getCoordList().size(); j++) { 71 if (IP.getCoordList().size() <= allCoordsArray.length) {
72 // Find the closest one and put it there
73 // NOOFBALLS IS SET TO 7, MAKE SURE IT CHANGES TAKES IN
74 // A NOOFBALLS-VARIABLE
75 // Check if none of the balls in the previous image was 76 if (IP.getCoordList().size() == noOfBalls) { 77 allCoordsArray[j][0][i - 1] = IP.getCoordList() 78 .get(j).get(0); 79 allCoordsArray[j][1][i - 1] = IP.getCoordList() 80 .get(j).get(1); 81 } else { 82 System.out.printf("noOfBalls: %d\n", IP 83 .getCoordList().size());
84 intyCoord = IP.getCoordList().get(j).get(0);
85 intxCoord = IP.getCoordList().get(j).get(1);
86 if (yCoord == 0) {
87 }
88 intdist = (int) Math.sqrt(Math.pow(
89 Math.abs(yCoord
90 - allCoordsArray[0][0][i - 2]), 2)
91 + Math.pow(Math.abs(xCoord
92 - allCoordsArray[0][1][i - 2]), 2));
93 intidy = 0;
94 for (int k = 1; k < IP.getCoordList().size(); k++) {
95 int cDist = (int) Math.sqrt(Math.pow(
96 Math.abs(yCoord 97 - allCoordsArray[k][0][i - 2]), 98 2) 99 + Math.pow(Math.abs(xCoord 100 - allCoordsArray[k][1][i - 2]), 101 2)); 102 System.out
103 .printf("Distance for ball %d = %d\n",
104 k, cDist); 105 if (cDist < dist) { 106 dist = cDist; 107 idy = k; 108 } 109 }
110 System.out.printf("idy = %d\n", idy);
111 allCoordsArray[idy][0][i - 1] = IP.getCoordList()
112 .get(j).get(0);
113 allCoordsArray[idy][1][i - 1] = IP.getCoordList()
114 .get(j).get(1);
115 }
116 }
117 }
118 }
119 noOfBalls = noOfBalls + getNoOfBallsFromImage();
120 }
121 noOfBalls = noOfBalls / noOfImages; 122 // Make Trajectory
123 gui.enableTrajectoryButton();
124 calculateValues calcVal = new calculateValues(allCoordsArray, width,
Controller.java
126 traj = new Trajectories(allCoordsArray, width, height, noOfBalls);
127 }
128
129 public BufferedImage getCurrentImage() { 130 return IP.getBufferedImage();
131 }
132
133 public int getNoOfBallsFromImage() { 134 return IP.getNoOfBalls();
135 }
136
137 public void setNoOfBallsLabelView() {
138 gui.setBallLabel(getNoOfBallsFromImage());
139 }
140
141 public void setCoordLabelView() { 142 gui.setCoordLabel(IP.getCoordList());
143 }
144
145 public void setImageToContentPane() {
146 gui.setImageToContentPane(IP.getBufferedImage());
147 }
148
149 public void setDirectoryString(String directoryString) { 150 gui.setTextFieldString(directoryString);
151 }
152
153 public void setROIimgGui() {
154 }
155
156 @Override
157 public void Update() {
158 // TODO Auto-generated method stub 159 runImageProcess();
160 gui.setRunButtonText("Run Calculation");
161 }
162
163 @Override
164 public void UpdateTextFieldString(String s) { 165 // TODO Auto-generated method stub 166 gui.setTextFieldString(s);
167 }
168
169 @Override
170 public void UpdateROIimg() {
171 // TODO Auto-generated method stub
172 try {
173 roi = new ROI(iJCF.getFileName(), width, height); 174 roi.AddObserver(this);
175 roi.startROIimg();
176 gui.loadROIimgFrame(roi.getAfterPic()); 177 gui.setROIButtonText("Select ROI"); 178 gui.disposeDialog();
179 } catch (IOException e) {
180 // TODO Auto-generated catch block 181 e.printStackTrace();
182 }
183 }
184
185 @Override
Controller.java 188 contrastInt = contrast;
189 }
190
191 @Override
192 public void UpdateROIimgRotation() { 193 // TODO Auto-generated method stub 194 gui.disposeROI();
195 try {
196 roi = new ROI(iJCF.getFileName(), width, height); 197 } catch (IOException e) {
198 // TODO Auto-generated catch block 199 e.printStackTrace();
200 }
201 roi.AddObserver(this); 202 roi.startROIimgWithRotation();
203 gui.loadROIimgFrame(roi.getAfterPic()); 204 gui.setRunButtonEnabled();
205 gui.setROIButtonText("Select ROI"); 206 gui.disposeDialog();
207 }
208
209 @Override
210 public void UpdateRIO(int mx1, int mx2, int my1, int my2) { 211 // TODO Auto-generated method stub
212 this.mx1 = mx1; 213 this.mx2 = mx2; 214 this.my1 = my1; 215 this.my2 = my2;
216 }
217
218 @Override
219 public void UpdateTrajectoryFrame() { 220 // TODO Auto-generated method stub 221 traj.startTrajectory();
222 }
GUI.java 1import java.awt.BorderLayout;
36
37public class GUI implements Subject { 38 JLabel coordLabel;
39 JPanel contentPane = new JPanel(); 40 JPanel imageContentPane = new JPanel(); 41 JPanel middlePanel;
42 JTextField imageDirectoryTextField; 43 private JFrame mainFrame;
44 private JFrame contrastFrame;
45 private JPanel controlPanel = new JPanel(); 46 private JPanel goPanel = new JPanel(); 47 private JLabel ballLabel;
48 private JPanel contrastImagePanel = new JPanel(); 49 private JFrame ROIFrame;
50 private ImageIcon imageIcon; 51 private JLabel noOfImagesLabel;
52 private JPanel buttomPanel = new JPanel(); 53 JDialog dialog;
54 JPanel dialogPanel; 55 JLabel dotLoadingLabel; 56 private JLabel imageLabel;
57 private JButton runButton = new JButton("Run Calculation"); 58 private JButton ROIButton = new JButton("Select ROI"); 59 private JButton settingsButton = new JButton("Settings"); 60 private JButton trajectoryButton = new JButton("Show Trajectory"); 61 staticfinal int contrastMax = 30;
62 staticfinal int contrastMin = 0; 63 staticfinal int contrastInit = 10; 64 private int mx1, mx2, my1, my2; 65 JSlider contrastSlider; 66 imageJFileChooser iJFC;
67 private ArrayList<Observe> observers; 68
69 public GUI() { 70 }
71
72 public GUI(imageJFileChooser iJFC) throws IOException { 73 this.iJFC = iJFC;
74 observers = new ArrayList<Observe>(); 75 runButton.setForeground(Color.blue); 76 prepareGUI(); 77 showImageButtonJPanel(); 78 showDirectoryJPanel(); 79 showBallJPanel(); 80 showGoJPanel();
81 mainFrame.add(controlPanel); 82 mainFrame.add(goPanel); 83 mainFrame.add(buttomPanel); 84 mainFrame.setVisible(true); 85 }
86
87 private void prepareGUI() {
88 mainFrame = new JFrame("Detector Calibration"); 89 mainFrame.setSize(1800, 1000);
90 mainFrame.setLayout(new GridLayout(3, 1)); 91 mainFrame.addWindowListener(new WindowAdapter() { 92 publicvoid windowClosing(WindowEvent windowEvent) {
93 System.exit(0);
94 }
95 });
96 BufferedImage firstBuffered = new BufferedImage(200, 400,
Page 1
GUI.java 97 BufferedImage.TYPE_USHORT_GRAY); 98 imageIcon = new ImageIcon();
99 imageIcon.setImage(firstBuffered);
100 imageDirectoryTextField = new JTextField("No directory chosen"); 101 ballLabel = new JLabel("Number of balls: ");
102 controlPanel.setLayout(new GridLayout(1, 3)); 103 goPanel.setLayout(new GridLayout(1, 3)); 104 buttomPanel.setLayout(new GridLayout(1, 3)); 105 JPanel rightButtomPanel = new JPanel();
106 rightButtomPanel.setLayout(new GridLayout(5, 2)); 107 runButton.setEnabled(false);
108 trajectoryButton.setEnabled(false);
109 ROIButton.addActionListener(new ActionListener() {
110 @Override
111 public void actionPerformed(ActionEvent e) {
112 if (imageDirectoryTextField.getText().contains(".bin")) { 113 ROIButton.setText("Loading ROI");
114 new Thread() {
115 public void run() {
116 dialog = new JDialog();
117 dialogPanel = new JPanel();
118 JPanel dialogPanel2 = new JPanel(); 119 dialog.setLayout(new GridLayout(2, 1));
120 dialog.add(dialogPanel);
121 dialog.add(dialogPanel2);
122 dialog.setUndecorated(true);
123 dotLoadingLabel = new JLabel("");
124 Dimension screenSize = Toolkit.getDefaultToolkit()
125 .getScreenSize();
126 Double dwidth = screenSize.getWidth(); 127 Double dheight = screenSize.getHeight();
128 intwidth = dwidth.intValue();
129 intheight = dheight.intValue();
130 dialog.setPreferredSize(new Dimension(400, 200)); 131 dialog.setBounds(width / 2 - 200, height / 2 - 100,
132 dialog.getWidth(), dialog.getHeight());
133 dialog.pack();
134 JLabel loadingLabel = new JLabel("Loading ROI");
135 loadingLabel.setFont(loadingLabel.getFont()
136 .deriveFont(30.0f));
137 dotLoadingLabel.setFont(loadingLabel.getFont()
138 .deriveFont(30.0f));
139 dialogPanel.add(loadingLabel);
140 dialogPanel2.add(dotLoadingLabel);
141 dialog.setVisible(true);
142 Timer timer = new Timer();
143 timer.schedule(new UpdateLoadingROILabel(), 0, 500);
144 }
145 }.start();
146 new Thread() {
147 public void run() {
148 NotifyObserversROIimg();
149 }
150 }.start();
151 } else {
152 final JFrame exceptionFrame = new JFrame(); 153 JButton exitButton = new JButton("OK");
154 exceptionFrame.getContentPane().setLayout(
155 new GridLayout(2, 1));
156 exceptionFrame
157 .getContentPane()
GUI.java
159 "Please choose the first file. Ends with 001.bin")); 160 exceptionFrame.getContentPane().add(exitButton);
161 exceptionFrame.setBounds(mainFrame.getWidth() / 2 - 150, 162 mainFrame.getHeight() / 2 - 50, 300, 100);
163 exceptionFrame.setVisible(true);
164 exitButton.addActionListener(new ActionListener() {
165 @Override
166 public void actionPerformed(ActionEvent e) {
167 exceptionFrame.dispose(); 168 } 169 }); 170 } 171 } 172 });
173 runButton.addActionListener(new ActionListener() {
174 @Override
175 public void actionPerformed(ActionEvent e) {
176 if (imageDirectoryTextField.getText().contains(".bin")) { 177 runButton.setText("Running...");
178 new Thread() {
179 public void run() {
180 NotifyObservers();
181 }
182 }.start();
183 } else {
184 final JFrame exceptionFrame = new JFrame(); 185 JButton exitButton = new JButton("OK");
186 exceptionFrame.getContentPane().setLayout(
187 new GridLayout(2, 1));
188 exceptionFrame
189 .getContentPane()
190 .add(new JLabel(
191 "Please choose the first file. Ends with 001.bin")); 192 exceptionFrame.getContentPane().add(exitButton);
193 exceptionFrame.setBounds(mainFrame.getWidth() / 2 - 150, 194 mainFrame.getHeight() / 2 - 50, 300, 100);
195 exceptionFrame.setVisible(true);
196 exitButton.addActionListener(new ActionListener() {
197 @Override
198 public void actionPerformed(ActionEvent e) {
199 // TODO Auto-generated method stub
200 exceptionFrame.dispose();
201 }
202 });
203 }
204 runButton.setText("Run Calculation");
205 }
206 });
207 settingsButton.addActionListener(new ActionListener() {
208 @Override
209 public void actionPerformed(ActionEvent e) { 210 // TODO Auto-generated method stub 211 JFrame settingsFrame = new JFrame();
212 settingsFrame.getContentPane().setLayout(new GridLayout(2, 1)); 213 contrastSlider = new JSlider(JSlider.HORIZONTAL, contrastMin,
214 contrastMax, contrastInit);
215 contrastSlider.addChangeListener(new ChangeListener() {
216 @Override
217 public void stateChanged(ChangeEvent e) { 218 if (contrastSlider.getValueIsAdjusting()) {
GUI.java
221 }
222 });
223 contrastSlider.setMajorTickSpacing(10); 224 contrastSlider.setMinorTickSpacing(1); 225 contrastSlider.setPaintTicks(true); 226 contrastSlider.setPaintLabels(true);
227 contrastImagePanel.setPreferredSize(new Dimension(2000, 2000)); 228 contrastImagePanel.setVisible(true);
229 contrastFrame = new JFrame("Settings");
230 contrastFrame.getContentPane().setLayout(new GridLayout(3, 1)); 231 contrastFrame.add(contrastSlider);
232 contrastFrame.add(contrastImagePanel); 233 contrastFrame.pack();
234 contrastFrame.setVisible(true);
235 }
236 });
237 trajectoryButton.addActionListener(new ActionListener() {
238 @Override
239 public void actionPerformed(ActionEvent e) { 240 NotiifyObserverShowTrajectory();
241 }
242 });
243 noOfImagesLabel = new JLabel("Images Processed: "); 244 imageLabel = new JLabel();
245 Border border = BorderFactory.createLineBorder(Color.darkGray, 5); 246 JPanel imagePanel = new JPanel();
247 JPanel insideImagePanel = new JPanel(); 248 insideImagePanel.setLayout(new BorderLayout()); 249 imagePanel.setLayout(new GridLayout(1, 4)); 250 imagePanel.add(new JPanel());
251 imagePanel.add(new JPanel()); 252 imagePanel.add(new JPanel()); 253 imagePanel.add(insideImagePanel);
254 insideImagePanel.add(noOfImagesLabel, BorderLayout.NORTH); 255 insideImagePanel.add(imageLabel, BorderLayout.CENTER); 256 imageLabel.setBorder(border);
257 goPanel.add(imagePanel); 258 buttomPanel.add(new JPanel()); 259 buttomPanel.add(new JPanel()); 260 buttomPanel.add(rightButtomPanel); 261 rightButtomPanel.add(trajectoryButton); 262 rightButtomPanel.add(new JPanel()); 263 rightButtomPanel.add(new JPanel()); 264 rightButtomPanel.add(new JPanel()); 265 rightButtomPanel.add(new JPanel()); 266 rightButtomPanel.add(new JPanel());
267 }
268
269 public void updateContrastFrame(BufferedImage bI) {
270 contrastFrame.getContentPane().add(new JLabel(new ImageIcon(bI))); 271 contrastImagePanel.add(new JLabel(new ImageIcon(bI)));
272 }
273
274 private void showBallJPanel() { 275 JPanel panel = new JPanel(); 276 panel.setLayout(new FlowLayout()); 277 panel.add(ballLabel);
278 controlPanel.add(panel);
279 }
280
281 private void showImageButtonJPanel() { 282 JPanel panel = new JPanel();
GUI.java 283 panel.setLayout(new FlowLayout()); 284 panel.add(iJFC, FlowLayout.LEFT); 285 controlPanel.add(panel);
286 }
287
288 private void showDirectoryJPanel() { 289
290 JPanel panel = new JPanel(); 291 panel.setLayout(new FlowLayout());
292 imageDirectoryTextField.setPreferredSize(new Dimension(400, 30)); 293 panel.add(imageDirectoryTextField, FlowLayout.LEFT);
294 controlPanel.add(panel);
295 }
296
297 private void showGoJPanel() { 298 middlePanel = new JPanel();
299 middlePanel.setLayout(new FlowLayout()); 300 middlePanel.add(runButton);
301 middlePanel.add(ROIButton); 302 middlePanel.add(settingsButton); 303 goPanel.add(middlePanel);
304 }
305
306 public void loadROIimgFrame(BufferedImage ROIImage) { 307 final Graphics2D g2d = ROIImage.createGraphics(); 308 ROIFrame = new JFrame();
309 JButton okButton = new JButton("OK"); 310 JButton cancelButton = new JButton("Cancel");
311 JButton rotateButton = new JButton("Rotate Clockwise"); 312 final JLabel xAxisLabel = new JLabel("X:");
313 final JLabel yAxisLabel = new JLabel("Y:"); 314 final JLabel xAxisLabel2 = new JLabel("X:"); 315 final JLabel yAxisLabel2 = new JLabel("Y:");
316 rotateButton.addActionListener(new ActionListener() {
317 @Override
318 public void actionPerformed(ActionEvent e) {
319 new Thread() {
320 public void run() {
321 dialog = new JDialog();
322 dialogPanel = new JPanel(); 323 JPanel dialogPanel2 = new JPanel(); 324 dialog.setLayout(new GridLayout(2, 1));
325 dialog.add(dialogPanel);
326 dialog.add(dialogPanel2); 327 dialog.setUndecorated(true); 328 dotLoadingLabel = new JLabel("");
329 Dimension screenSize = Toolkit.getDefaultToolkit()
330 .getScreenSize();
331 Double dwidth = screenSize.getWidth(); 332 Double dheight = screenSize.getHeight();
333 int width = dwidth.intValue();
334 int height = dheight.intValue();
335 dialog.setPreferredSize(new Dimension(400, 200)); 336 dialog.setBounds(width / 2 - 200, height / 2 - 100, 337 dialog.getWidth(), dialog.getHeight());
338 dialog.pack();
339 JLabel loadingLabel = new JLabel("Loading new Image"); 340 loadingLabel.setFont(loadingLabel.getFont().deriveFont(
341 30.0f));
342 dotLoadingLabel.setFont(loadingLabel.getFont()
GUI.java
345 dialogPanel2.add(dotLoadingLabel);
346 dialog.setVisible(true);
347 // Set timer for loading dialog box
348 Timer timer = new Timer();
349 timer.schedule(new UpdateLoadingROILabel(), 0, 500);
350 }
351 }.start();
352 new Thread() {
353 public void run() {
354 NotifyObserverRotate();
355 }
356 }.start();
357 }
358 });
359 cancelButton.addActionListener(new ActionListener() {
360 @Override
361 public void actionPerformed(ActionEvent e) { 362 // TODO Auto-generated method stub 363 System.out.println("Cancel"); 364 ROIFrame.dispose();
365 }
366 });
367 final JLabel test = new JLabel(new ImageIcon(ROIImage)); 368 JScrollPane scrollPane = new JScrollPane(test);
369 scrollPane
370 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
371 scrollPane
372 .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 373 Dimension preferredSize;
374 if (ROIImage.getWidth() <= 1500 && ROIImage.getHeight() <= 700) { 375 preferredSize = new Dimension(ROIImage.getWidth(),
376 ROIImage.getHeight());
377 } else if (ROIImage.getWidth() <= 1500 && ROIImage.getHeight() > 700) { 378 preferredSize = new Dimension(ROIImage.getWidth(), 700);
379 } else if (ROIImage.getWidth() > 1500 && ROIImage.getHeight() <= 700) { 380 preferredSize = new Dimension(1500, ROIImage.getHeight());
381 } else {
382 preferredSize = new Dimension(1500, 700);
383 }
384 scrollPane.setPreferredSize(preferredSize); 385 scrollPane.setMaximumSize(preferredSize); 386 test.addMouseListener(new MouseAdapter() { 387 private Boolean clicked = false; 388
389 @Override
390 public void mousePressed(MouseEvent e) { 391 if (clicked == false) {
392 mx1 = e.getX();
393 my1 = e.getY();
394 xAxisLabel.setText("X: " + mx1); 395 yAxisLabel.setText("Y: " + my1); 396 System.out.println(mx1 + ", " + my1);
397 clicked = true;
398 } else if (clicked == true) {
399 mx2 = e.getX();
400 my2 = e.getY();
401 System.out.println(mx2 + ", " + my2);
402 clicked = false;
403 g2d.drawLine(mx1, my1, mx1, my2); 404 g2d.drawLine(mx1, my1, mx2, my1); 405 g2d.drawLine(mx2, my2, mx1, my2); 406 g2d.drawLine(mx2, my2, mx2, my1);
GUI.java
407 g2d.setColor(Color.BLACK);
408 test.paint(g2d);
409 xAxisLabel2.setText("X: " + mx2); 410 yAxisLabel2.setText("Y: " + my2);
411 }
412 ROIFrame.repaint();
413 }
414
415 @Override
416 public void mouseReleased(MouseEvent e) {
417 }
418
419 });
420
421 okButton.addActionListener(new ActionListener() { 422
423 @Override
424 public void actionPerformed(ActionEvent e) { 425 // TODO Auto-generated method stub 426 System.out.println("OK");
427 NotifyObserverROI();
428 System.out.println(mx1 + ", " + my1 + " and " + mx2 + ", "
429 + my2); 430 ROIFrame.dispose(); 431 setRunButtonEnabled(); 432 } 433 }); 434
435 JPanel rightPanel = new JPanel(new GridLayout(20, 1)); 436
437 rightPanel.add(new JLabel("First Coordinates:")); 438 rightPanel.add(xAxisLabel);
439 rightPanel.add(yAxisLabel);
440 rightPanel.add(new JLabel("Second Coordinates:")); 441 rightPanel.add(xAxisLabel2);
442 rightPanel.add(yAxisLabel2); 443 rightPanel.add(new JPanel()); 444 rightPanel.add(new JPanel()); 445 rightPanel.add(new JPanel()); 446 rightPanel.add(new JPanel()); 447 rightPanel.add(new JPanel()); 448 rightPanel.add(new JPanel()); 449 rightPanel.add(new JPanel()); 450 rightPanel.add(new JPanel()); 451 rightPanel.add(new JPanel()); 452 rightPanel.add(new JPanel()); 453 rightPanel.add(new JPanel()); 454 rightPanel.add(rotateButton); 455 rightPanel.add(okButton); 456 rightPanel.add(cancelButton); 457
458 ROIFrame.getContentPane().add(rightPanel, BorderLayout.EAST); 459 ROIFrame.getContentPane().add(scrollPane, BorderLayout.CENTER); 460 ROIFrame.setResizable(false);
461 ROIFrame.pack();
462 ROIFrame.setVisible(true); 463
464 }
465
466 public void setImageToGoPanel(BufferedImage image) { 467
GUI.java
469 System.out.printf("Width: %d\nHeight: %d\n\n", image.getWidth(),
470 image.getHeight());
471
472 }
473
474 public void setBallLabel(int noOfBalls) {
475 String ballString = String.valueOf(noOfBalls); 476 ballLabel.setText("Number of Balls: " + ballString); 477
478 }
479
480 // Is this supposed to be in this class?
481 private String convertIntegerListToString(List<List<Integer>> list) { 482 int[][] tempToStringArray = new int[list.size()][2];
483 String outputString = "<html>"; 484 int ballInt = 0;
485
486 for (int i = 0; i < list.size(); i++) {
487 tempToStringArray[i][0] = list.get(i).get(0); 488 tempToStringArray[i][1] = list.get(i).get(1);
489 ballInt++;
490
491 outputString += "Ball " + ballInt + ":<br>x:" 492 + tempToStringArray[i][0] + "<br>y: " 493 + tempToStringArray[i][1] + "<br><br> "; 494 } 495 outputString += "</html>"; 496 ballInt = 0; 497 498 return outputString; 499 } 500
501 public void setImageToContentPane(BufferedImage image) { 502
503 // System.out.println("FRAME");
504 BufferedImage scaledImage = new BufferedImage(image.getWidth(), 505 image.getHeight(), BufferedImage.TYPE_INT_ARGB); 506 AffineTransform at = new AffineTransform();
507 at.scale(0.4, 0.4);
508 at.translate(image.getWidth() * 0.5, image.getHeight() * 0.5); 509 // at.rotate(Math.PI/2);
510 at.translate(-image.getWidth() * 0.5, -image.getHeight() * 0.5); 511 AffineTransformOp scaleOp = new AffineTransformOp(at,
512 AffineTransformOp.TYPE_BILINEAR); 513 scaledImage = scaleOp.filter(image, scaledImage); 514 setImageToGoPanel(scaledImage);
515 }
516
517 public void setCoordLabel(List<List<Integer>> ballCoordArray) { 518
519 coordLabel.setText(convertIntegerListToString(ballCoordArray)); 520 coordLabel.setBounds(20, 20, 50, 550);
521 controlPanel.add(coordLabel); 522
523 }
524
525 public void setTextFieldString(String directoryString) { 526 imageDirectoryTextField.setText(directoryString);
527 }
528
529 public void setRunButtonEnabled() { 530 runButton.setEnabled(true);
GUI.java
531 }
532
533 public void openImageInFrame(BufferedImage image) { 534 JScrollPane scrollPane = new JScrollPane(new JLabel( 535 new ImageIcon(image)));
536 scrollPane
537 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
538 scrollPane
539 .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 540
541 JButton contrastButton = new JButton("Cancel"); 542
543 contrastButton.addActionListener(new ActionListener() { 544
545 @Override
546 public void actionPerformed(ActionEvent e) { 547 // TODO Auto-generated method stub 548
549 }
550 });
551
552 JFrame frame = new JFrame();
553 frame.getContentPane().setLayout(new GridLayout(1, 2)); 554 frame.getContentPane().add(scrollPane);
555 frame.pack();
556 frame.setVisible(true); 557
558 }
559
560 public void setROIButtonText(String text) { 561
562 ROIButton.setText(text);
563 }
564
565 public void setRunButtonText(String text) { 566
567 runButton.setText(text);
568 }
569
570 public void disposeROI() { 571 ROIFrame.dispose();
572 }
573
574 public void setNoOfImagesLabel(int noOfImages) {
575 noOfImagesLabel.setText("Images processed: " + noOfImages);
576 }
577
578 public void disposeDialog() { 579 dialog.dispose();
580 }
581
582 public void enableTrajectoryButton() { 583 trajectoryButton.setEnabled(true);
584 }
585
586 // OBSERVERS 587
588 @Override
589 public void AddObserver(Observe o) { 590 // TODO Auto-generated method stub 591 observers.add(o);
GUI.java 593
594 @Override
595 public void RemoveObserver(Observe o) { 596 // TODO Auto-generated method stub 597 observers.remove(o);
598 }
599
600 @Override
601 public void NotifyObservers() { 602 // TODO Auto-generated method stub
603 for (int i = 0; i < observers.size(); i++) { 604 observers.get(i).Update();
605 }
606
607 }
608
609 @Override
610 public void NotifyObserversTextField() { 611 // TODO Auto-generated method stub 612
613 }
614
615 @Override
616 public void NotifyObserversROIimg() { 617 // TODO Auto-generated method stub
618 for (int i = 0; i < observers.size(); i++) { 619 observers.get(i).UpdateROIimg();
620 }
621 }
622
623 @Override
624 public void NotifyObserversContrast(int contrast) { 625 // TODO Auto-generated method stub
626 for (int i = 0; i < observers.size(); i++) { 627 observers.get(i).UpdateContrast(contrast);
628 }
629 }
630
631 @Override
632 public void NotifyObserverRotate() { 633 // TODO Auto-generated method stub
634 for (int i = 0; i < observers.size(); i++) { 635 observers.get(i).UpdateROIimgRotation();
636 }
637
638 }
639
640 @Override
641 public void NotifyObserverROI() { 642 // TODO Auto-generated method stub
643 for (int i = 0; i < observers.size(); i++) { 644 observers.get(i).UpdateRIO(mx1, mx2, my1, my2);
645 }
646 }
647
648 // Subclasses
649 class UpdateLoadingROILabel extends TimerTask { 650 public void run() {
651 if (dotLoadingLabel.getText() == "") { 652 dotLoadingLabel.setText(".");
653 } else if (dotLoadingLabel.getText() == ".") { 654 dotLoadingLabel.setText("..");
GUI.java