Plug-in CT MD, a typical plug-in program

From MIPAV
Jump to: navigation, search

PlugInCT_MD is a typical example of a plug-in program. It consists of three files:

PlugInCT_MD.java-Provides an interface to MIPAV and the plug-in program.
PlugInDialogCT_MD.java-Invokes the dialog to get user-supplied parameters.
PlugInAlgorithmCT_MD.java-Implements the algorithm.
PlugInCT_MD.java

The file in Figure 23 provides an interface between MIPAV and PlugInCT_MD.

PlugInDialogCT_MD.java

The PlugInDialogCT_MD.java file invokes a dialog box to obtain user-supplied data. Refer to Figure 24.

PlugInAlgorithmCT_MD.java

Figure 25 shows the content of PlugInAlgorithmCT_MD.java.

PlugInDialogImageVOIDisplay.java

Figure 26 shows a sample code for a self-contained frame plug-in.

Note: For readability purposes, keywords in all code reproduced in this chapter appear in bold, and comments appear in green type
Figure 23. PlugInCT_MD.java

PlugInCT_MD.java
1 import plugins.PlugInDialogCT_MT; //associated class file
2 import gov.nih.mipav.plugins.*; //needed to load PlugInAlgorithm / PlugInView /
3 //PlugInFile interface
4 import gov.nih.mipav.view.*;
5 import gov.nih.mipav.model.structures.*;
6
7 import java.awt.*;
8
9 /**
10 * This is a simple plugin for the University of Maryland to simple segment an
11 * imagebased on CT Hounsfield units.
12 *
13 * @see PlugInAlgorithm
14 */
15
16 //This is an Algorithm type of PlugIn, and therefore must implement PlugInAlgorithm
17 //Implementing the PlugInAlgorithm requires this class to implement the run method
18 //with the correct parameters
19 public class PlugInCT_MD implements PlugInAlgorithm {
20
21 /**
22 * Defines body of run method, which was declared in the interface.
23 * @param UI User Interface
24 * @param parentFrame ParentFrame
25 * @param image Current ModelImage--this is an image already loaded into
26 * MIPAV. Can be null.
27 */
28 public void run (ViewUserInterface UI, Frame parentFrame, ModelImage image){
29
30 if (parentFrame instanceof ViewJFrameImage)
31 new PlugInDialogCT_MD (parentFrame,image);
32
33 else
34 MipavUtil.displayError ("PlugIn CT_MD only runs on an image frame.");
35 }
36 }
37 }

{| border="1" cellpadding="5" |+
Figure 328. PlugInDialogCT_MD.javaÂ
|- |
PlugInDialogCT_MD.java
1 import gov.nih.mipav.view.*;
2 import gov.nih.mipav.view.dialogs.*;
3 import gov.nih.mipav.model.structures.*;
4 import gov.nih.mipav.model.algorithms.*;
5
6 import java.awt.event.*;
7 import java.awt.*;
8 import java.util.*;
9
10 import javax.swing.*;
11
12
13 /**
14 *
15 * JDialogBase class.
16 *
17 * Note:
18 *
19 * @version July 12, 2002
20 * @author
21 * @see JDialogBase
22 * @see JDialogMedian
23 * @see AlgorithmInterface
24 *
25 * $Logfile: /mipav/src/plugins/PlugInDialogCT_MD.java $
26 * $Revision: 6 $
27 * $Date: 8/05/04 5:44p $
28 *
29 */
30 public class PlugInDialogCT_MD extends JDialogBase implements AlgorithmInterface {
31
32 private PlugInAlgorithmCT_MD ctSegAlgo = null;
33 private ModelImage image; // source image
34 private ModelImage resultImage = null; // result image
35 private ViewUserInterface userInterface;
36
37 private String titles[];
38
39 private float correctionVal;
40 private JTextField fatLValTF;
41 private JTextField fatHValTF;
42 private JTextField ldmLValTF;
43 private JTextField ldmHValTF;
44 private JTextField hdmLValTF;
45 private JTextField hdmHValTF;
46
47 private int fatLVal;
48 private int fatHVal;
49 private int ldmLVal;
50 private int ldmHVal;
51 private int hdmLVal;
52 private int hdmHVal;
53
|- |
54 /**
55 * Creates new dialog for Median filtering using a plugin.
56 * @param parent Parent frame.
57 * @param im Source image.
58 */
59
60 public PlugInDialogCT_MD(Frame theParentFrame, ModelImage im) {
61 super(theParentFrame, true);
62 if (im.getType() == ModelImage.BOOLEAN || im.isColorImage()) {
63 MipavUtil.displayError("Source Image must NOT be Boolean or Color");
64 dispose();
65 return;
66 }
67 image = im;
68 userInterface = ((ViewJFrameBase)(parentFrame)).getUserInterface();
69 init();
70 }
71
72 /**
73 * Used primarily for the script to store variables and run the algorithm. No
74 * actual dialog will appear but the set up info and result image will be stored
75 * here.
76 * @param UI The user interface, needed to create the image frame.
77 * @param im Source image.
78 */
79 public PlugInDialogCT_MD(ViewUserInterface UI, ModelImage im) {
80 super();
81 userInterface = UI;
82 if (im.getType() == ModelImage.BOOLEAN || im.isColorImage()) {
83 MipavUtil.displayError("Source Image must NOT be Boolean or Color");
84 dispose();
85 return;
86 }
87
88 image = im;
89 }
90
91 /**
92 * Sets up the GUI (panels, buttons, etc) and displays it on the screen.
93 */
94 private void init(){
95
96 setForeground(Color.black);
97 setTitle("CT_segmentation");
98
99 JPanel inputPanel = new JPanel(new GridLayout(3, 3));
100 inputPanel.setForeground(Color.black);
101 inputPanel.setBorder(buildTitledBorder("Input parameters"));
102
103 JLabel labelFat = new JLabel("Fat thresholds: ");
104 labelFat.setForeground(Color.black);
105 labelFat.setFont(serif12);
106 inputPanel.add(labelFat);
107
Â
|- |
108 fatLValTF = new JTextField();
109 fatLValTF.setText("-190");
110 fatLValTF.setFont(serif12);
111 inputPanel.add(fatLValTF);
112
113 fatHValTF = new JTextField();
114 fatHValTF.setText("-30");
115 fatHValTF.setFont(serif12);
116 inputPanel.add(fatHValTF);
117
118 JLabel labelLDM = new JLabel("Low density muscle thresholds: ");
119 labelLDM.setForeground(Color.black);
120 labelLDM.setFont(serif12);
121 inputPanel.add(labelLDM);
122
123 ldmLValTF = new JTextField();
124 ldmLValTF.setText("0");
125 ldmLValTF.setFont(serif12);
126 inputPanel.add(ldmLValTF);
127
128 ldmHValTF = new JTextField();
129 ldmHValTF.setText("30");
130 ldmHValTF.setFont(serif12);
131 inputPanel.add(ldmHValTF);
132
133 JLabel labelHDM = new JLabel("High density muscle thresholds: ");
134 labelHDM.setForeground(Color.black);
135 labelHDM.setFont(serif12);
136 inputPanel.add(labelHDM);
137
138 hdmLValTF = new JTextField();
139 hdmLValTF.setText("31");
140 hdmLValTF.setFont(serif12);
141 inputPanel.add(hdmLValTF);
142
143 hdmHValTF = new JTextField();
144 hdmHValTF.setText("100");
145 hdmHValTF.setFont(serif12);
146 inputPanel.add(hdmHValTF);
147
148 getContentPane().add(inputPanel, BorderLayout.CENTER);
149
150 // Build the Panel that holds the OK and CANCEL Buttons
151 JPanel OKCancelPanel = new JPanel();
152
153 // size and place the OK button
154 buildOKButton();
155 OKCancelPanel.add(OKButton, BorderLayout.WEST);
156 // size and place the CANCEL button
157 buildCancelButton();
158 OKCancelPanel.add(cancelButton, BorderLayout.EAST);
159 getContentPane().add(OKCancelPanel, BorderLayout.SOUTH);
Â
|- |
160 pack();
161 setVisible(true);
162 setResizable(false);
163 System.gc();
164
165 } // end init()
166
167 /**
168 * Accessor that returns the image.
169 * @return The result image.
170 */
171 public ModelImage getResultImage() {return resultImage;}
172
173
174
175 /**
176 * Accessor that sets the correction value
177 * @param num Value to set iterations to (should be between 1 and 20).
178 */
179 public void setCorrectionValue(float num) {correctionVal = num;}
180
181 //************************************************************************
182 //************************** Event Processing ****************************
183 //************************************************************************
184
185 /**
186 * Closes dialog box when the OK button is pressed and calls the algorithm.
187 * @param event Event that triggers function.
188 */
189 public void actionPerformed(ActionEvent event) {
190 String command = event.getActionCommand();
191
192 if (command.equals("OK")) {
193 if (setVariables()) {
194 callAlgorithm();
195 }
196 }
197 else if (command.equals("Script")) {
198 callAlgorithm();
199 }
200 else if (command.equals("Cancel")) {
201 dispose();
202 }
203 }
204
205 //************************************************************************
206 //************************** Algorithm Events ****************************
207 //************************************************************************
208
209 /**
210 * This method is required if the AlgorithmPerformed interface is implemented.
211 * It is called by the algorithm when it has completed or failed to to complete,
212 * so that the dialog can be display the result image and/or clean up.
213 * @param algorithm Algorithm that caused the event.
214 */
215 public void algorithmPerformed(AlgorithmBase algorithm) {
Â
|- |
216 ViewJFrameImage imageFrame = null;
217 if ( algorithm instanceof PlugInAlgorithmCT_MD) {
218 image.clearMask();
219 if(ctSegAlgo.isCompleted() == true && resultImage != null) {
220 //The algorithm has completed and produced a new image to be displayed.
221
222 updateFileInfo(image, resultImage);
223 resultImage.clearMask();
224 try {
225 //resultImage.setImageName("Median: " image.getImageName());
226
227 int dimExtentsLUT[] = new int[2];
228 dimExtentsLUT[0] = 4;
229 dimExtentsLUT[1] = 256;
230 ModelLUT LUTa = new ModelLUT(ModelLUT.COOLHOT, 256, dimExtentsLUT);
231 imageFrame = new ViewJFrameImage(resultImage, LUTa, new Dimension(610,200),
232 userInterface);
233 }
234 catch (OutOfMemoryError error){
235 System.gc();
236 MipavUtil.displayError("Out of memory: unable to open new frame");
237 }
238 }
239 else if (resultImage == null) {
240 // These next lines set the titles in all frames where the source image
241 // is displayed to image name so as to indicate that the image is now
242 // unlocked! The image frames are enabled and then registered to the
243 // userinterface.
244 Vector imageFrames = image.getImageFrameVector();
245 for (int i = 0; i < imageFrames.size(); i ) {
246 ((Frame)(imageFrames.elementAt(i))).setTitle(titles[i]);
247 ((Frame)(imageFrames.elementAt(i))).setEnabled(true);
248 if ( ((Frame)(imageFrames.elementAt(i))) != parentFrame) {
249 userInterface.registerFrame((Frame)(imageFrames.elementAt(i)));
250 }
251 }
252 if (parentFrame != null) userInterface.registerFrame(parentFrame);
253 image.notifyImageDisplayListeners(null, true);
254 }
255 else if (resultImage != null){
256 //algorithm failed but result image still has garbage
257 resultImage.disposeLocal(); // clean up memory
258 resultImage = null;
259 System.gc();
260 }
261 }
262 if (ctSegAlgo.isCompleted() == true) {
263 if (userInterface.isScriptRecording()) {
264 userInterface.getScriptDialog().append("Flow "
265 userInterface.getScriptDialog().getVar(image.getImageName()) " "
266 correctionVal "\n");
267 }
268 }
269 dispose();
270
Â
|- |
271 } // end AlgorithmPerformed()
272
273
274 /**
275 * Use the GUI results to set up the variables needed to run the algorithm.
276 * @return <code>true</code> if parameters set successfully, <code>false
277 * </code> otherwise.
278 */
279 private boolean setVariables() {
280 String tmpStr;
281
282
283 // verify iteration is within bounds
284 tmpStr = fatLValTF.getText();
285 if ( testParameter(tmpStr, -4000, 4000) ){
286 fatLVal = Integer.valueOf(tmpStr).intValue();
287 }
288 else{
289 fatLValTF.requestFocus();
290 fatLValTF.selectAll();
291 return false;
292 }
293
294 tmpStr = fatHValTF.getText();
295 if ( testParameter(tmpStr, -4000, 4000) ){
296 fatHVal = Integer.valueOf(tmpStr).intValue();
297 }
298 else{
299 fatHValTF.requestFocus();
300 fatHValTF.selectAll();
301 return false;
302 }
303
304 tmpStr = ldmLValTF.getText();
305 if ( testParameter(tmpStr, -4000, 4000) ){
306 ldmLVal = Integer.valueOf(tmpStr).intValue();
307 }
308 else{
309 ldmLValTF.requestFocus();
310 ldmLValTF.selectAll();
311 return false;
312 }
313
314 tmpStr = ldmHValTF.getText();
315 if ( testParameter(tmpStr, -4000, 4000) ){
316 ldmHVal = Integer.valueOf(tmpStr).intValue();
317 }
318 else{
319 ldmHValTF.requestFocus();
320 ldmHValTF.selectAll();
321 return false;
322 }
323
324
Â
|- |
325 tmpStr = hdmLValTF.getText();
326 if ( testParameter(tmpStr, -4000, 4000) ){
327 hdmLVal = Integer.valueOf(tmpStr).intValue();
328 }
329 else{
330 hdmLValTF.requestFocus();
331 hdmLValTF.selectAll();
332 return false;
333 }
334
335 tmpStr = hdmHValTF.getText();
336 if ( testParameter(tmpStr, -4000, 4000) ){
337 hdmHVal = Integer.valueOf(tmpStr).intValue();
338 }
339 else{
340 hdmHValTF.requestFocus();
341 hdmHValTF.selectAll();
342 return false;
343 }
344
345 return true;
346 } // end setVariables()
347
348 /**
349 * Once all the necessary variables are set, call the Gaussian Blur
350 * algorithm based on what type of image this is and whether or not there
351 * is a separate destination image.
352 */
353 private void callAlgorithm() {
354 String name = makeImageName(image.getImageName(), "_CTseg");
355
356 // stuff to do when working on 2-D images.
357 if (image.getNDims() == 2 ) { // source image is 2D
358 int destExtents[] = new int[2];
359 destExtents[0] = image.getExtents()[0]; // X dim
360 destExtents[1] = image.getExtents()[1]; // Y dim
361
362 try{
363 // Make result image of Ubyte type
364 resultImage = new ModelImage(ModelStorageBase.UBYTE, destExtents, name,
365 userInterface);
366
367 // Make algorithm
368 boolean entireFlag = true;
369
370 //ctSegAlgo = new PlugInAlgorithmFlowWrapFix(resultImage, image, iters,
371 // kernelSize, kernelShape, stdDev, regionFlag);
372 ctSegAlgo = new PlugInAlgorithmCT_MD(resultImage, image);
373
374 System.out.println("Dialog fatL = " fatLVal " fatH = " fatHVal);
375 ctSegAlgo.fatL = fatLVal;
376 ctSegAlgo.fatH = fatHVal;
377 ctSegAlgo.ldmL = ldmLVal;
378 ctSegAlgo.ldmH = ldmHVal;
Â
|- |
379 ctSegAlgo.hdmL = hdmLVal;
380 ctSegAlgo.hdmH = hdmHVal;
381
382
383
384 // This is very important. Adding this object as a listener allows the
385 // algorithm to notify this object when it has completed or failed. See
386 // algorithm performed event.
387 // This is made possible by implementing AlgorithmedPerformed interface
388 ctSegAlgo.addListener(this);
389 setVisible(false); // Hide dialog
390
391 if (runInSeparateThread) {
392 // Start the thread as a low priority because we wish to still have
393 // user interface work fast.
394 if (ctSegAlgo.startMethod(Thread.MIN_PRIORITY) == false){
395 MipavUtil.displayError("A thread is already running on this object");
396 }
397 }
398 else {
399 ctSegAlgo.run();
400 }
401 }
402 catch (OutOfMemoryError x){
403 MipavUtil.displayError("Dialog median: unable to allocate enough memory");
404 if (resultImage != null){
405 resultImage.disposeLocal(); // Clean up memory of result image
406 resultImage = null;
407 }
408 return;
409 }
410 }
411 else if (image.getNDims() == 3 ) {
412 int destExtents[] = new int[3];
413 destExtents[0] = image.getExtents()[0];
414 destExtents[1] = image.getExtents()[1];
415 destExtents[2] = image.getExtents()[2];
416
417 try{
418 // Make result image of float type
419 resultImage = new ModelImage(ModelStorageBase.UBYTE, destExtents, name,
420 userInterface);
421 boolean entireFlag = true;
422
423 ctSegAlgo = new PlugInAlgorithmCT_MD(resultImage, image);
424 ctSegAlgo.fatL = fatLVal;
425 ctSegAlgo.fatH = fatHVal;
426 ctSegAlgo.ldmL = ldmLVal;
427 ctSegAlgo.ldmH = ldmHVal;
428 ctSegAlgo.hdmL = hdmLVal;
429 ctSegAlgo.hdmH = hdmHVal;
430
Â
|- |
431 // This is very important. Adding this object as a listener allows the
432 // algorithm to notify this object when it has completed or failed.
433 // See algorithm performed event. This is made possible by implementing
434 // AlgorithmedPerformed interface
435 ctSegAlgo.addListener(this);
436 setVisible(false); // Hide dialog
437
438 if (runInSeparateThread) {
439 // Start the thread as a low priority because we wish to still have
440 // user interface work fast.
441 if (ctSegAlgo.startMethod(Thread.MIN_PRIORITY) == false){
442 MipavUtil.displayError("A thread is already running on this object");
443 }
444 }
445 else {
446 ctSegAlgo.run();
447 }
448 }
449 catch (OutOfMemoryError x){
450 MipavUtil.displayError("Dialog median: unable to allocate enough memory");
451 if (resultImage != null){
452 resultImage.disposeLocal(); // Clean up image memory
453 resultImage = null;
454 }
455 return;
456 }
457 }
458 } // end callAlgorithm()
459
460 }
|}


Next: PlugInAlgorithmCT_MD.java

See also: