View Javadoc
1   package com.github.celldynamics.quimp.plugin.bar;
2   
3   import java.awt.Color;
4   import java.awt.Component;
5   import java.awt.FlowLayout;
6   import java.awt.Frame;
7   import java.awt.GridBagConstraints;
8   import java.awt.GridBagLayout;
9   import java.awt.Menu;
10  import java.awt.MenuBar;
11  import java.awt.MenuItem;
12  import java.awt.Window;
13  import java.awt.event.ActionEvent;
14  import java.awt.event.ActionListener;
15  import java.awt.event.ItemEvent;
16  import java.awt.event.ItemListener;
17  import java.awt.event.WindowAdapter;
18  import java.awt.event.WindowEvent;
19  import java.io.BufferedReader;
20  import java.io.IOException;
21  import java.io.InputStreamReader;
22  import java.net.URI;
23  import java.net.URL;
24  import java.util.Enumeration;
25  
26  import javax.swing.ImageIcon;
27  import javax.swing.JButton;
28  import javax.swing.JCheckBox;
29  import javax.swing.JFrame;
30  import javax.swing.JPanel;
31  import javax.swing.JTextPane;
32  import javax.swing.JToolBar;
33  import javax.swing.ToolTipManager;
34  import javax.swing.text.SimpleAttributeSet;
35  import javax.swing.text.StyleConstants;
36  import javax.swing.text.StyledDocument;
37  
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  import com.github.celldynamics.quimp.AboutDialog;
42  import com.github.celldynamics.quimp.PropertyReader;
43  import com.github.celldynamics.quimp.QuimP;
44  import com.github.celldynamics.quimp.QuimpException;
45  import com.github.celldynamics.quimp.QuimpException.MessageSinkTypes;
46  import com.github.celldynamics.quimp.QuimpVersion;
47  import com.github.celldynamics.quimp.filesystem.FileDialogEx;
48  import com.github.celldynamics.quimp.filesystem.FileExtensions;
49  import com.github.celldynamics.quimp.filesystem.converter.FormatConverter;
50  import com.github.celldynamics.quimp.omero.OmeroClient_;
51  import com.github.celldynamics.quimp.registration.Registration;
52  import com.github.celldynamics.quimp.utils.QuimpToolsCollection;
53  import com.github.celldynamics.quimp.utils.UiTools;
54  
55  import ij.IJ;
56  import ij.Prefs;
57  import ij.WindowManager;
58  import ij.io.OpenDialog;
59  import ij.macro.MacroRunner;
60  import ij.plugin.PlugIn;
61  
62  /**
63   * Create QuimP bar with icons to QuimP plugins.
64   * 
65   * @author r.tyson
66   * @author p.baniukiewicz
67   */
68  public class QuimP_Bar implements PlugIn, ActionListener {
69  
70    /**
71     * The Constant LOGGER.
72     */
73    static final Logger LOGGER = LoggerFactory.getLogger(QuimP_Bar.class.getName());
74  
75    /**
76     * The path.
77     */
78    String path;
79  
80    /**
81     * The separator.
82     */
83    String separator = System.getProperty("file.separator");
84  
85    /**
86     * The frame.
87     */
88    JFrame frame = new JFrame();
89  
90    /**
91     * The frontframe.
92     */
93    Window frontframe;
94  
95    /**
96     * The xfw.
97     */
98    int xfw = 0;
99  
100   /**
101    * The yfw.
102    */
103   int yfw = 0;
104 
105   /**
106    * The wfw.
107    */
108   int wfw = 0;
109 
110   /**
111    * The hfw.
112    */
113   int hfw = 0;
114 
115   /**
116    * The tool bar upper.
117    */
118   JToolBar toolBarUpper = null;
119 
120   /**
121    * The tool bar bottom.
122    */
123   JToolBar toolBarBottom = null;
124 
125   /**
126    * The button.
127    */
128   JButton button = null;
129 
130   /**
131    * The c file format.
132    */
133   JCheckBox cbFileformat;
134 
135   /**
136    * The tool bar title 1.
137    */
138   JTextPane toolBarTitle1 = null;
139 
140   /**
141    * The tool bar title 2.
142    */
143   JTextPane toolBarTitle2 = null;
144   private final Color barColor = new Color(0xFB, 0xFF, 0x94); // Color of title bar
145   private MenuBar menuBar;
146   private Menu menuTools;
147   private Menu menuMisc;
148   private MenuItem menuShowreg;
149   private MenuItem menuFormatConverter;
150   private MenuItem menuOmero;
151   private Menu menuHelp;
152   private MenuItem menuVersion;
153   private MenuItem menuOpenHelp;
154   private MenuItem menuOpenSite;
155   private MenuItem menuLicense;
156 
157   /*
158    * (non-Javadoc)
159    * 
160    * @see ij.plugin.PlugIn#run(java.lang.String)
161    */
162   @Override
163   public void run(String s) {
164     ToolTipManager.sharedInstance().setDismissDelay(UiTools.TOOLTIPDELAY);
165     String title;
166     QuimpVersion quimpInfo = QuimP.TOOL_VERSION; // get jar title
167     title = quimpInfo.getName() + " " + quimpInfo.getVersion();
168 
169     frame.setTitle(title); // and set to window title
170 
171     // if already open, bring to front
172     if (WindowManager.getFrame(title) != null) {
173       WindowManager.getFrame(title).toFront();
174       return;
175     }
176 
177     // this listener will save the bar's position and close it.
178     frame.addWindowListener(new WindowAdapter() {
179       @Override
180       public void windowClosing(WindowEvent e) {
181         storeLocation();
182         e.getWindow().dispose();
183         WindowManager.removeWindow((Frame) frame);
184       }
185     });
186 
187     frontframe = WindowManager.getActiveWindow();
188     if (frontframe != null) {
189       xfw = frontframe.getLocation().x;
190       yfw = frontframe.getLocation().y;
191       wfw = frontframe.getWidth();
192       hfw = frontframe.getHeight();
193     }
194 
195     frame.getContentPane().setLayout(new GridBagLayout());
196     buildPanel(); // build the QuimP bar
197     // add menu
198     menuBar = new MenuBar();
199     menuHelp = new Menu("Quimp-Help");
200     menuTools = new Menu("Tools");
201     menuMisc = new Menu("Misc");
202     menuBar.add(menuHelp);
203     menuBar.add(menuTools);
204     menuBar.add(menuMisc);
205     menuVersion = new MenuItem("About");
206     menuOpenHelp = new MenuItem("Help Contents");
207     menuOpenSite = new MenuItem("History of changes");
208     menuLicense = new MenuItem("Show licence");
209     menuFormatConverter = new MenuItem("Format converter");
210     menuOmero = new MenuItem("Omero client");
211     menuShowreg = new MenuItem("Show registration");
212     menuHelp.add(menuOpenHelp);
213     menuHelp.add(menuOpenSite);
214     menuHelp.add(menuVersion);
215     menuTools.add(menuFormatConverter);
216     menuTools.add(menuOmero);
217     menuMisc.add(menuShowreg);
218     menuMisc.add(menuLicense);
219     menuVersion.addActionListener(this);
220     menuOpenHelp.addActionListener(this);
221     menuOpenSite.addActionListener(this);
222     menuLicense.addActionListener(this);
223     menuFormatConverter.addActionListener(this);
224     menuOmero.addActionListener(this);
225     menuShowreg.addActionListener(this);
226     frame.setMenuBar(menuBar);
227 
228     // captures the ImageJ KeyListener
229     frame.setFocusable(true);
230     frame.addKeyListener(IJ.getInstance());
231 
232     frame.setResizable(false);
233     // frame.setAlwaysOnTop(true);
234 
235     frame.setLocation((int) Prefs.get("actionbar" + QuimP.QUIMP_PREFS_SUFFIX + ".xloc", 10),
236             (int) Prefs.get("actionbar" + QuimP.QUIMP_PREFS_SUFFIX + ".yloc", 10));
237     WindowManager.addWindow(frame);
238 
239     frame.pack();
240 
241     frame.setVisible(true);
242 
243     // validate registered user
244     new Registration(frame, "QuimP Registration");
245 
246     WindowManager.setWindow(frontframe);
247 
248   }
249 
250   /**
251    * Build QuimP panel and run macros.
252    * 
253    * <p>Macros are defined in plugins.conf file, where the name of the macro is related to class
254    * name
255    * to run.
256    */
257   private void buildPanel() {
258     toolBarTitle1 = new JTextPane(); // first title bar
259     toolBarUpper = new JToolBar(); // icons below it
260     toolBarTitle2 = new JTextPane(); // second title bar
261     toolBarBottom = new JToolBar(); // icons below it
262 
263     // define atributes for title bars
264     SimpleAttributeSet titlebaratr = new SimpleAttributeSet();
265     StyleConstants.setAlignment(titlebaratr, StyleConstants.ALIGN_CENTER);
266     titlebaratr.addAttribute(StyleConstants.CharacterConstants.Bold, true);
267 
268     // first row title - centered text
269     StyledDocument doc = toolBarTitle1.getStyledDocument();
270     doc.setParagraphAttributes(0, doc.getLength(), titlebaratr, false);
271     toolBarTitle1.setText("QuimP workflow");
272     toolBarTitle1.setBackground(barColor);
273 
274     // second row - buttons and quimp icons
275     JPanel panelButtons = new JPanel();
276     panelButtons.setLayout(new GridBagLayout());
277     JPanel firstRow = new JPanel();
278     firstRow.setLayout(new FlowLayout(FlowLayout.LEADING));
279 
280     GridBagConstraints constrains = new GridBagConstraints();
281     button = makeNavigationButton("x.jpg", "open(\"\")", "Open a file", "OPEN IMAGE");
282     firstRow.add(button, constrains);
283 
284     button = makeNavigationButton("x.jpg", "run(\"ROI Manager...\");", "Open the ROI manager",
285             "ROI");
286     firstRow.add(button);
287 
288     GridBagConstraints cons = new GridBagConstraints();
289     cons.gridx = 0;
290     cons.gridy = 0;
291     cons.fill = GridBagConstraints.HORIZONTAL;
292     panelButtons.add(firstRow, cons);
293     cbFileformat = new JCheckBox("Use new file format");
294     cbFileformat.setAlignmentX(Component.LEFT_ALIGNMENT);
295     UiTools.setToolTip(cbFileformat,
296             "Unselect to use (load and save) old " + FileExtensions.configFileExt + " files."
297                     + "New file is always produced. Do not mix workflows - use paQP or"
298                     + " QCONF but not" + " both in the same time.");
299     cbFileformat.setSelected(QuimP.newFileFormat.get()); // default selection
300     cbFileformat.addItemListener(new ItemListener() { // set static field
301 
302       @Override
303       public void itemStateChanged(ItemEvent e) {
304         if (e.getStateChange() == ItemEvent.SELECTED) {
305           QuimP.newFileFormat.set(true);
306         } else {
307           QuimP.newFileFormat.set(false);
308         }
309       }
310     });
311 
312     cons.gridx = 0;
313     cons.gridy = 1;
314     panelButtons.add(cbFileformat, cons);
315 
316     toolBarUpper.add(panelButtons);
317 
318     toolBarUpper.addSeparator();
319 
320     button = makeNavigationButton("boa.jpg", "run(\"BOA\")", "Cell segmentation", "BOA");
321     toolBarUpper.add(button);
322 
323     button = makeNavigationButton("ecmm.jpg", "run(\"ECMM Mapping\")", "Cell membrane tracking",
324             "ECMM");
325     toolBarUpper.add(button);
326 
327     button = makeNavigationButton("ana.jpg", "run(\"ANA\")", "Measure fluorescence", "ANA");
328     toolBarUpper.add(button);
329 
330     toolBarUpper.addSeparator();
331 
332     button = makeNavigationButton("qanalysis.jpg", "run(\"QuimP Analysis\")", "Q Analysis of data",
333             "Q Analysis");
334     toolBarUpper.add(button);
335 
336     button = makeNavigationButton("prot.jpg", "run(\"Protrusion Analysis\")",
337             "Run protrusion analysis", "Protrusion Analysis");
338     toolBarUpper.add(button);
339 
340     // third row title
341     StyledDocument doc1 = toolBarTitle2.getStyledDocument();
342     doc1.setParagraphAttributes(0, doc1.getLength(), titlebaratr, false);
343     toolBarTitle2.setText("Pre- and post-processing methods");
344     toolBarTitle2.setBackground(barColor);
345 
346     // fourth - preprocessing tools
347     button = makeNavigationButton("diclid.jpg", "run(\"DIC\")",
348             "Reconstruction of DIC images by Line Integral Method", "DIC LID");
349     toolBarBottom.add(button);
350     button = makeNavigationButton("rw.jpg", "run(\"RandomWalk\")", "Run random walk segmentation",
351             "Random Walk");
352     toolBarBottom.add(button);
353     button = makeNavigationButton("generatemask.png", "run(\"Generate mask\")",
354             "Convert Qconf (Snakes) to binary masks", "Generate mask");
355     toolBarBottom.add(button);
356     button = makeNavigationButton("generateqconf.png", "run(\"Generate Qconf\")",
357             "Convert binary or grayscale mask to Qconf", "Generate Qconf");
358     toolBarBottom.add(button);
359     button = makeNavigationButton("formatconv.jpg", "run(\"Format converter\")",
360             "Convert between formats", "Format converter");
361     toolBarBottom.add(button);
362 
363     toolBarUpper.setFloatable(false);
364     toolBarBottom.setFloatable(false);
365     // build window
366     constrains.gridx = 0;
367     constrains.gridy = 0;
368     constrains.fill = GridBagConstraints.HORIZONTAL;
369     frame.getContentPane().add(toolBarTitle1, constrains);
370     constrains.gridx = 0;
371     constrains.gridy = 1;
372     frame.getContentPane().add(toolBarUpper, constrains);
373     constrains.gridx = 0;
374     constrains.gridy = 2;
375     constrains.fill = GridBagConstraints.HORIZONTAL;
376     frame.getContentPane().add(toolBarTitle2, constrains);
377     constrains.gridx = 0;
378     constrains.gridy = 4;
379     frame.getContentPane().add(toolBarBottom, constrains);
380   }
381 
382   /**
383    * Make navigation button.
384    *
385    * @param imageName the image name
386    * @param actionCommand the action command
387    * @param toolTipText the tool tip text
388    * @param altText the alt text
389    * @return the j button
390    */
391   protected JButton makeNavigationButton(String imageName, String actionCommand, String toolTipText,
392           String altText) {
393 
394     String imgLocation = "icons/" + imageName;
395     JButton newbutton = new JButton();
396     newbutton.setActionCommand(actionCommand);
397     // newbutton.setMargin(new Insets(2, 2, 2, 2));
398     newbutton.setBorderPainted(true);
399     newbutton.addActionListener(this);
400     newbutton.setFocusable(true);
401     newbutton.addKeyListener(IJ.getInstance());
402     URL imageURL = QuimP_Bar.class.getResource(imgLocation);
403     if (imageURL != null) {
404       newbutton.setIcon(new ImageIcon(imageURL, altText));
405       newbutton.setToolTipText(toolTipText);
406     } else {
407       newbutton.setText(altText);
408       newbutton.setToolTipText(toolTipText);
409     }
410     return newbutton;
411   }
412 
413   /*
414    * (non-Javadoc)
415    * 
416    * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
417    */
418   @Override
419   public void actionPerformed(ActionEvent e) {
420     if (e.getSource() == menuVersion) { // menu version
421       String quimpInfo = new QuimpToolsCollection().getQuimPversion(); // prepare info plate
422       AboutDialog/quimp/AboutDialog.html#AboutDialog">AboutDialog ad = new AboutDialog(frame); // create about dialog with parent 'window'
423       ad.appendLine(quimpInfo); // display template filled by quimpInfo
424       ad.appendDistance();
425       ad.appendLine("All plugins for QuimP are reported in modules that use them natively.");
426       ad.setVisible(true);
427       return;
428     }
429     if (e.getSource() == menuOpenHelp) { // open help
430       String url = new PropertyReader().readProperty("quimpconfig.properties", "manualURL");
431       try {
432         java.awt.Desktop.getDesktop().browse(new URI(url));
433       } catch (Exception e1) {
434         LOGGER.error("Could not open help: " + e1.getMessage(), e1);
435       }
436       return;
437     }
438     if (e.getSource() == menuOpenSite) { // open help
439       String url = new PropertyReader().readProperty("quimpconfig.properties", "siteURL");
440       try {
441         java.awt.Desktop.getDesktop().browse(new URI(url));
442       } catch (Exception e1) {
443         LOGGER.error("Could not open help: " + e1.getMessage());
444       }
445       return;
446     }
447     if (e.getSource() == menuLicense) {
448       AboutDialog/quimp/AboutDialog.html#AboutDialog">AboutDialog ad = new AboutDialog(frame, 50, 130);
449       BufferedReader in = null;
450       try {
451         // get internal name - jar name
452         String iname = new PropertyReader().readProperty("quimpconfig.properties", "internalName");
453         // read file from resources
454         Enumeration<URL> resources = getClass().getClassLoader().getResources("LICENSE.txt");
455         while (resources.hasMoreElements()) {
456           URL reselement = resources.nextElement();
457           if (reselement.toString().contains("/" + iname)) {
458             in = new BufferedReader(new InputStreamReader(reselement.openStream()));
459             String line = in.readLine();
460             while (line != null) {
461               ad.appendLine(line);
462               line = in.readLine();
463             }
464           }
465         }
466         ad.setVisible(true);
467       } catch (IOException e1) {
468         LOGGER.debug(e1.getMessage(), e1);
469         LOGGER.error("Can not find license file in jar: " + e1.getMessage());
470       } finally {
471         try {
472           if (in != null) {
473             in.close();
474           }
475         } catch (IOException e1) {
476           e1.printStackTrace();
477         }
478       }
479       return;
480     }
481     if (e.getSource() == menuShowreg) {
482       // show window filled with reg data
483       Registrationegistration/Registration.html#Registration">Registration regwindow = new Registration(frame); // use manual constructor
484       regwindow.waited = true; // user waited already
485       regwindow.build("QuimP Registration", false); // build UI
486       regwindow.fillRegForm(); // fill reg form from IJ_Prefs data
487       regwindow.setVisible(true); // show and wait for user action
488       return;
489     }
490     if (e.getSource() == menuFormatConverter) { // convert between file formats
491       FileDialogExquimp/filesystem/FileDialogEx.html#FileDialogEx">FileDialogEx od = new FileDialogEx(IJ.getInstance(), FileExtensions.newConfigFileExt,
492               FileExtensions.configFileExt);
493       od.setDirectory(OpenDialog.getLastDirectory());
494       if (od.showOpenDialog() == null) {
495         IJ.log("Cancelled - exiting...");
496         return;
497       }
498       try {
499         // load config file but check if it is new format or old
500         FormatConverterystem/converter/FormatConverter.html#FormatConverter">FormatConverter formatConv = new FormatConverter(od.getPath().toFile());
501         formatConv.showConversionCapabilities(frame);
502         formatConv.doConversion();
503       } catch (QuimpException qe) {
504         qe.setMessageSinkType(MessageSinkTypes.GUI);
505         qe.handleException(frame, "Error during conversion:");
506       } catch (Exception e1) {
507         LOGGER.debug(e1.getMessage(), e1);
508         LOGGER.error("Problem with running FormatConverter: " + e1.getMessage());
509       }
510       return;
511     }
512     if (e.getSource() == menuOmero) {
513       new OmeroClient_();
514       return;
515     }
516     try {
517       new MacroRunner(e.getActionCommand() + "\n");
518     } catch (Exception ex) {
519       IJ.error("Error in QuimP plugin");
520     }
521     frame.repaint();
522   }
523 
524   /**
525    * Store location.
526    */
527   protected void storeLocation() {
528     Prefs.set("actionbar" + QuimP.QUIMP_PREFS_SUFFIX + ".xloc", frame.getLocation().x);
529     Prefs.set("actionbar" + QuimP.QUIMP_PREFS_SUFFIX + ".yloc", frame.getLocation().y);
530   }
531 
532 }