View Javadoc
1   package com.github.celldynamics.quimp.omero;
2   
3   import java.awt.BorderLayout;
4   import java.awt.Color;
5   import java.awt.Component;
6   import java.awt.Container;
7   import java.awt.FlowLayout;
8   import java.awt.GridBagConstraints;
9   import java.awt.GridBagLayout;
10  import java.awt.GridLayout;
11  import java.awt.Insets;
12  import java.awt.Window;
13  import java.awt.event.ActionEvent;
14  import java.awt.event.ActionListener;
15  import java.awt.event.FocusAdapter;
16  import java.awt.event.FocusEvent;
17  import java.awt.event.WindowAdapter;
18  import java.awt.event.WindowEvent;
19  import java.text.SimpleDateFormat;
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  import javax.swing.AbstractAction;
24  import javax.swing.Action;
25  import javax.swing.BoxLayout;
26  import javax.swing.DefaultListModel;
27  import javax.swing.JButton;
28  import javax.swing.JCheckBox;
29  import javax.swing.JDialog;
30  import javax.swing.JEditorPane;
31  import javax.swing.JLabel;
32  import javax.swing.JList;
33  import javax.swing.JPanel;
34  import javax.swing.JPasswordField;
35  import javax.swing.JScrollPane;
36  import javax.swing.JSplitPane;
37  import javax.swing.JTabbedPane;
38  import javax.swing.JTable;
39  import javax.swing.JTextField;
40  import javax.swing.JTextPane;
41  import javax.swing.ListSelectionModel;
42  import javax.swing.SwingConstants;
43  import javax.swing.border.EmptyBorder;
44  import javax.swing.event.ChangeEvent;
45  import javax.swing.event.ChangeListener;
46  import javax.swing.event.ListSelectionEvent;
47  import javax.swing.event.ListSelectionListener;
48  import javax.swing.table.AbstractTableModel;
49  
50  import org.slf4j.Logger;
51  import org.slf4j.LoggerFactory;
52  
53  import ij.io.DirectoryChooser;
54  import omero.gateway.model.DatasetData;
55  import omero.gateway.model.ImageData;
56  
57  /**
58   * Dialog by WindowsBuilder.
59   * 
60   * @author p.baniukiewicz
61   *
62   */
63  @SuppressWarnings("serial")
64  public class OmeroLoginDialog extends JDialog {
65    static final Logger LOGGER = LoggerFactory.getLogger(OmeroLoginDialog.class.getName());
66  
67    private static final String DISCONNECTED = "<b>Disconnected</b>";
68    private static final String CONNECTED = "<b>Connected</b>";
69  
70    private final JPanel contentPanel = new JPanel();
71    private final ImageTableeroLoginDialog.html#ImageTable">ImageTable imageTableModel = new ImageTable();
72    private JTextField tfHost;
73    private JTextField tfUser;
74    private JPasswordField tfPass;
75    private final Action testAction = new ConnectAction();
76    private OmeroClient_ omc;
77    private final Action downloadAction = new DownloadAction();
78    private final Action uploadAction = new UploadAction();
79    private JTabbedPane tabbedPane;
80    private JPanel panelDownload;
81    private JPanel panelUpload;
82    private final Action storeAction = new StoreAction();
83    private JTextField tfPort;
84    private JCheckBox chckbxStoreCred;
85    private JTextPane tpInfo;
86    private JPanel panelSetup;
87    private JList<String> listDatasetsDownload;
88    private JTable tableImagesDownload;
89    private JTable tableImagesUpload;
90    private JList<String> listDatasetsUpload;
91    private final Action uploadExperimentAction = new UploadExperimentAction();
92    private final Action downloadExperimentAction = new DownloadExperimentAction();
93  
94    /**
95     * Editable fields in config pane.
96     * 
97     * @author p.baniukiewicz
98     *
99     */
100   private enum Fields {
101     HOST, USER, PASS, PORT
102   }
103 
104   /**
105    * Set {@link OmeroBrowser} login fields.
106    * 
107    * @param obj component
108    * @param name name
109    */
110   private void readTextField(Object obj, Fields name) {
111     LOGGER.debug("Reading: " + name);
112     if (obj instanceof JTextField) {
113       String text = ((JTextField) obj).getText();
114       switch (name) {
115         case HOST:
116           omc.setHost(text);
117           break;
118         case USER:
119           omc.setUser(text);
120           break;
121         case PASS:
122           omc.setPass(text);
123           break;
124         case PORT:
125           omc.setPort(text);
126           break;
127         default:
128           throw new IllegalArgumentException("Wrong input type.");
129       }
130     } else {
131       throw new IllegalArgumentException("Wrong input type.");
132     }
133 
134   }
135 
136   /**
137    * Default constructor.
138    * 
139    * <p>Add icon in toolbar.
140    */
141   public OmeroLoginDialog() {
142     super((Window) null);
143   }
144 
145   /**
146    * Create the dialog and update fields.
147    * 
148    * @param omc instance of model class.
149    */
150   public OmeroLoginDialog(OmeroClient_ omc) {
151     this();
152     addWindowListener(new WindowAdapter() {
153       @Override
154       public void windowClosing(WindowEvent arg0) {
155         omc.disconnect();
156       }
157     });
158     this.omc = omc;
159     setTitle("Omero login");
160     setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
161     setBounds(100, 100, 789, 594);
162     getContentPane().setLayout(new BorderLayout());
163     contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
164     getContentPane().add(contentPanel, BorderLayout.CENTER);
165     contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.X_AXIS));
166     {
167       tabbedPane = new JTabbedPane(JTabbedPane.TOP);
168       tabbedPane.addChangeListener(new ChangeListener() {
169         public void stateChanged(ChangeEvent e) {
170           if (e.getSource() instanceof JTabbedPane) {
171             JTabbedPane pane = (JTabbedPane) e.getSource();
172             if (pane.getSelectedComponent() == getPanelDownload()) {
173               LOGGER.trace("Selected download pane");
174 
175             }
176             if (pane.getSelectedComponent() == getPanelUpload()) {
177               LOGGER.trace("Selected upload pane");
178 
179             }
180             if (pane.getSelectedComponent() == getPanelSetup()) {
181               LOGGER.trace("Selected setup pane");
182             }
183           }
184         }
185       });
186       contentPanel.add(tabbedPane);
187       {
188         panelSetup = new JPanel();
189         panelSetup.setBorder(new EmptyBorder(4, 4, 4, 4));
190         tabbedPane.addTab("Setup", null, panelSetup, "Setup connection");
191         tabbedPane.setEnabledAt(0, true);
192         GridBagLayout gbl_panelSetup = new GridBagLayout();
193         gbl_panelSetup.columnWidths = new int[] { 417 };
194         gbl_panelSetup.rowHeights = new int[] { 26, 26, 26, 26, 26, 26, 26 };
195         gbl_panelSetup.columnWeights = new double[] { 1.0 };
196         gbl_panelSetup.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 };
197         panelSetup.setLayout(gbl_panelSetup);
198         {
199           JPanel panel_1 = new JPanel();
200           GridBagConstraints gbc_panel_1 = new GridBagConstraints();
201           gbc_panel_1.fill = GridBagConstraints.BOTH;
202           gbc_panel_1.insets = new Insets(0, 0, 5, 0);
203           gbc_panel_1.gridx = 0;
204           gbc_panel_1.gridy = 0;
205           panelSetup.add(panel_1, gbc_panel_1);
206           panel_1.setLayout(new GridLayout(0, 2, 0, 0));
207           {
208             JLabel lblNewLabel = new JLabel("Host address");
209             panel_1.add(lblNewLabel);
210           }
211           {
212             tfHost = new JTextField();
213             tfHost.setText(omc.getHost());
214             tfHost.setHorizontalAlignment(SwingConstants.RIGHT);
215             tfHost.addFocusListener(new FocusAdapter() {
216               @Override
217               public void focusLost(FocusEvent arg0) {
218                 readTextField(arg0.getSource(), Fields.HOST);
219               }
220             });
221             tfHost.addActionListener(new ActionListener() {
222               public void actionPerformed(ActionEvent arg0) {
223                 readTextField(arg0.getSource(), Fields.HOST);
224               }
225             });
226             tfHost.setToolTipText("Host name");
227             panel_1.add(tfHost);
228             tfHost.setColumns(10);
229           }
230         }
231         {
232           JPanel panel_1 = new JPanel();
233           GridBagConstraints gbc_panel_1 = new GridBagConstraints();
234           gbc_panel_1.fill = GridBagConstraints.BOTH;
235           gbc_panel_1.insets = new Insets(0, 0, 5, 0);
236           gbc_panel_1.gridx = 0;
237           gbc_panel_1.gridy = 1;
238           panelSetup.add(panel_1, gbc_panel_1);
239           panel_1.setLayout(new GridLayout(0, 2, 0, 0));
240           {
241             JLabel lblNewLabel_1 = new JLabel("User name");
242             panel_1.add(lblNewLabel_1);
243           }
244           {
245             tfUser = new JTextField();
246             tfUser.setText(omc.getUser());
247             tfUser.setHorizontalAlignment(SwingConstants.RIGHT);
248             tfUser.addFocusListener(new FocusAdapter() {
249               @Override
250               public void focusLost(FocusEvent e) {
251                 readTextField(e.getSource(), Fields.USER);
252               }
253             });
254             tfUser.addActionListener(new ActionListener() {
255               public void actionPerformed(ActionEvent arg0) {
256                 readTextField(arg0.getSource(), Fields.USER);
257               }
258             });
259             tfUser.setToolTipText("User name");
260             panel_1.add(tfUser);
261             tfUser.setColumns(10);
262           }
263         }
264         {
265           JPanel panel_1 = new JPanel();
266           GridBagConstraints gbc_panel_1 = new GridBagConstraints();
267           gbc_panel_1.fill = GridBagConstraints.BOTH;
268           gbc_panel_1.insets = new Insets(0, 0, 5, 0);
269           gbc_panel_1.gridx = 0;
270           gbc_panel_1.gridy = 2;
271           panelSetup.add(panel_1, gbc_panel_1);
272           panel_1.setLayout(new GridLayout(0, 2, 0, 0));
273           {
274             JLabel lblNewLabel_2 = new JLabel("Password");
275             panel_1.add(lblNewLabel_2);
276           }
277           {
278             tfPass = new JPasswordField();
279             tfPass.setHorizontalAlignment(SwingConstants.RIGHT);
280             tfPass.addFocusListener(new FocusAdapter() {
281               @Override
282               public void focusLost(FocusEvent e) {
283                 readTextField(e.getSource(), Fields.PASS);
284               }
285             });
286             tfPass.addActionListener(new ActionListener() {
287               public void actionPerformed(ActionEvent e) {
288                 readTextField(e.getSource(), Fields.PASS);
289               }
290             });
291             tfPass.setToolTipText("Password");
292             tfPass.setText(omc.getPass());
293             panel_1.add(tfPass);
294             tfPass.setColumns(10);
295           }
296         }
297         {
298           JPanel panel = new JPanel();
299           GridBagConstraints gbc_panel = new GridBagConstraints();
300           gbc_panel.insets = new Insets(0, 0, 5, 0);
301           gbc_panel.fill = GridBagConstraints.BOTH;
302           gbc_panel.gridx = 0;
303           gbc_panel.gridy = 3;
304           panelSetup.add(panel, gbc_panel);
305           panel.setLayout(new GridLayout(0, 2, 0, 0));
306           {
307             JLabel lblNewLabel_3 = new JLabel("Port");
308             panel.add(lblNewLabel_3);
309           }
310           {
311             tfPort = new JTextField();
312             tfPort.setText(omc.getPort());
313             tfPort.setToolTipText("Port number");
314             tfPort.setHorizontalAlignment(SwingConstants.RIGHT);
315             tfPort.addFocusListener(new FocusAdapter() {
316               @Override
317               public void focusLost(FocusEvent e) {
318                 readTextField(e.getSource(), Fields.PORT);
319               }
320             });
321             tfPort.addActionListener(new ActionListener() {
322               public void actionPerformed(ActionEvent e) {
323                 readTextField(e.getSource(), Fields.PORT);
324               }
325             });
326             panel.add(tfPort);
327             tfPort.setColumns(10);
328           }
329         }
330         {
331           JPanel panel_1 = new JPanel();
332           GridBagConstraints gbc_panel_1 = new GridBagConstraints();
333           gbc_panel_1.fill = GridBagConstraints.BOTH;
334           gbc_panel_1.insets = new Insets(0, 0, 5, 0);
335           gbc_panel_1.gridx = 0;
336           gbc_panel_1.gridy = 4;
337           panelSetup.add(panel_1, gbc_panel_1);
338           panel_1.setLayout(new GridLayout(0, 1, 0, 0));
339           {
340             chckbxStoreCred = new JCheckBox("Store credentials");
341             chckbxStoreCred.setSelected(true);
342             chckbxStoreCred.setAction(storeAction);
343             chckbxStoreCred.setToolTipText(
344                     "Store login details in ImageJ preference file. Password will be obfuscated.");
345             panel_1.add(chckbxStoreCred);
346           }
347         }
348         {
349           JScrollPane scrollPane = new JScrollPane();
350           GridBagConstraints gbc_scrollPane = new GridBagConstraints();
351           gbc_scrollPane.fill = GridBagConstraints.BOTH;
352           gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
353           gbc_scrollPane.gridx = 0;
354           gbc_scrollPane.gridy = 5;
355           panelSetup.add(scrollPane, gbc_scrollPane);
356           {
357             JEditorPane tpHelp = new JEditorPane();
358             scrollPane.setViewportView(tpHelp);
359             tpHelp.setContentType("text/html");
360             tpHelp.setText(
361                     "<h2>About</h2>\r\n<p>\r\n\tThis simple tool allows for uploading and downloading QuimP datafiles to/from Omero. \r\n\t<ol>\r\n\t\t<li>After filling credential click <i>Connect</i> to establish connection with Omero. Datasets available for logged user will be displayed in <i>Download</i> and <i>Upload</i> tabs.</li>\r\n\t\t<li>To disconnect click <i>Cancel</i></li>\r\n\t\t<li>Select <i>Store credentials</i> to save your password, user, host and port in ImageJ preference file.</li>\r\n\t</ol>\r\n</p>\r\n<h2>Upload</h2>\r\n<p>\r\n\tYou have to select <i>QCONF</i> file that will be uploaded to dataset selected in <i>Upload</i> tab. Corresponding image is read from <i>QCONF</i> (note that due to compatibility reasons <i>QCONF</i> stores full path to the image and if image is not found you will have to locate it manually). Both image and <i>QCONF</i> are uploaded to the Omero. <i>QCONF</i> is attached to the image.\r\n</p>\r\n<h2>Download</h2>\r\n<p>\r\n\tThe image selected in <i>Download</i> will be downloaded to selected folder together with attached <i>QCONF</i>.\r\n</p>");
362             tpHelp.setEditable(false);
363             tpHelp.setCaretPosition(0);
364           }
365         }
366         {
367           JPanel buttonPane = new JPanel();
368           FlowLayout flowLayout = (FlowLayout) buttonPane.getLayout();
369           flowLayout.setAlignment(FlowLayout.RIGHT);
370           GridBagConstraints gbc_buttonPane = new GridBagConstraints();
371           gbc_buttonPane.fill = GridBagConstraints.BOTH;
372           gbc_buttonPane.gridx = 0;
373           gbc_buttonPane.gridy = 6;
374           panelSetup.add(buttonPane, gbc_buttonPane);
375           {
376             JButton btnDownload = new JButton("Download");
377             buttonPane.add(btnDownload);
378             btnDownload.setToolTipText("Download experiment to local folder");
379             btnDownload.setAction(downloadAction);
380           }
381           {
382             JButton btnUpload = new JButton("Upload");
383             buttonPane.add(btnUpload);
384             btnUpload.setToolTipText("Upload experiment to Omero");
385             btnUpload.setAction(uploadAction);
386           }
387           {
388             JButton btnNewButton = new JButton("Test");
389             buttonPane.add(btnNewButton);
390             btnNewButton.setToolTipText("Test connection");
391             btnNewButton.setAction(testAction);
392           }
393         }
394       }
395       {
396         panelDownload = new JPanel();
397         tabbedPane.addTab("Download", null, panelDownload, "Download experiment settings");
398         panelDownload.setLayout(new BorderLayout(2, 2));
399         {
400           JButton btnDownloadExp = new JButton("");
401           btnDownloadExp.setAction(downloadExperimentAction);
402           btnDownloadExp.setToolTipText("");
403           panelDownload.add(btnDownloadExp, BorderLayout.SOUTH);
404         }
405         {
406           JPanel panel = new JPanel();
407           panelDownload.add(panel, BorderLayout.CENTER);
408           panel.setLayout(new GridLayout(1, 2, 0, 2));
409           {
410             JSplitPane splitPane = new JSplitPane();
411             panel.add(splitPane);
412             splitPane.setContinuousLayout(true);
413             splitPane.setResizeWeight(0.5);
414             splitPane.setOneTouchExpandable(true);
415             {
416               listDatasetsDownload = new JList<String>();
417               listDatasetsDownload.addListSelectionListener(new ListSelectionListener() {
418                 public void valueChanged(ListSelectionEvent e) {
419                   if (!e.getValueIsAdjusting()) {
420                     int index = listDatasetsDownload.getSelectedIndex();
421                     if (index >= 0) {
422                       String name = listDatasetsDownload.getModel().getElementAt(index);
423                       LOGGER.trace("Selected: " + name);
424                       omc.setCurrentDs(index);
425                       imageTableModel.update(omc.getImages(index));
426                     }
427                   }
428                 }
429               });
430               listDatasetsDownload.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
431               JScrollPane scrollPane = new JScrollPane(listDatasetsDownload);
432               splitPane.setLeftComponent(scrollPane);
433             }
434             {
435               tableImagesDownload = new JTable(imageTableModel);
436               tableImagesDownload.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
437               tableImagesDownload.getSelectionModel()
438                       .addListSelectionListener(new ListSelectionListener() {
439 
440                         @Override
441                         public void valueChanged(ListSelectionEvent e) {
442                           if (!e.getValueIsAdjusting()) {
443                             int index = tableImagesDownload.getSelectedRow();
444                             if (index >= 0) {
445                               String name = tableImagesDownload.getValueAt(index, 0).toString();
446                               LOGGER.trace("Selected: " + name);
447                               omc.setCurrentIm(index);
448                             }
449                           }
450 
451                         }
452                       });
453               JScrollPane scrollPane = new JScrollPane(tableImagesDownload);
454               splitPane.setRightComponent(scrollPane);
455             }
456           }
457         }
458         tabbedPane.setEnabledAt(1, true);
459       }
460       {
461         panelUpload = new JPanel();
462         tabbedPane.addTab("Upload", null, panelUpload, "Upload experiment settings");
463         panelUpload.setLayout(new BorderLayout(0, 0));
464         {
465           JButton btnUploadExp = new JButton("");
466           btnUploadExp.setAction(uploadExperimentAction);
467           btnUploadExp.setToolTipText("");
468           panelUpload.add(btnUploadExp, BorderLayout.SOUTH);
469         }
470         {
471           JPanel panel = new JPanel();
472           panelUpload.add(panel, BorderLayout.CENTER);
473           panel.setLayout(new GridLayout(1, 0, 0, 0));
474           {
475             JSplitPane splitPane = new JSplitPane();
476             splitPane.setResizeWeight(0.5);
477             splitPane.setOneTouchExpandable(true);
478             splitPane.setContinuousLayout(true);
479             panel.add(splitPane);
480             {
481               JScrollPane scrollPane = new JScrollPane();
482               splitPane.setLeftComponent(scrollPane);
483               {
484                 listDatasetsUpload = new JList<String>();
485                 listDatasetsUpload.addListSelectionListener(new ListSelectionListener() {
486                   public void valueChanged(ListSelectionEvent e) {
487                     if (!e.getValueIsAdjusting()) {
488                       int index = listDatasetsUpload.getSelectedIndex();
489                       if (index >= 0) {
490                         String name = listDatasetsUpload.getModel().getElementAt(index);
491                         LOGGER.trace("Selected: " + name);
492                         omc.setCurrentDs(index);
493                         imageTableModel.update(omc.getImages(index));
494                       }
495                     }
496                   }
497                 });
498                 listDatasetsUpload.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
499                 scrollPane.setViewportView(listDatasetsUpload);
500               }
501             }
502             {
503               JScrollPane scrollPane = new JScrollPane();
504               splitPane.setRightComponent(scrollPane);
505               {
506                 tableImagesUpload = new JTable(imageTableModel);
507                 tableImagesUpload.setRowSelectionAllowed(false);
508                 scrollPane.setViewportView(tableImagesUpload);
509               }
510             }
511           }
512         }
513         tabbedPane.setEnabledAt(2, true);
514       }
515     }
516     {
517       JPanel buttonPane = new JPanel();
518       buttonPane.setBorder(new EmptyBorder(0, 4, 4, 4));
519       getContentPane().add(buttonPane, BorderLayout.SOUTH);
520       {
521         GridBagLayout gbl_buttonPane = new GridBagLayout();
522         gbl_buttonPane.columnWidths = new int[] { 210, 110 };
523         gbl_buttonPane.rowHeights = new int[] { 25 };
524         gbl_buttonPane.columnWeights = new double[] { 1.0, 0.0, 0.0 };
525         gbl_buttonPane.rowWeights = new double[] { 1.0 };
526         buttonPane.setLayout(gbl_buttonPane);
527         {
528           tpInfo = new JTextPane();
529           tpInfo.setContentType("text/html");
530           tpInfo.setText(DISCONNECTED);
531           tpInfo.setBackground(Color.ORANGE);
532           tpInfo.setEditable(false);
533           GridBagConstraints gbc_tpInfo = new GridBagConstraints();
534           gbc_tpInfo.insets = new Insets(0, 0, 0, 5);
535           gbc_tpInfo.fill = GridBagConstraints.BOTH;
536           gbc_tpInfo.gridx = 0;
537           gbc_tpInfo.gridy = 0;
538           buttonPane.add(tpInfo, gbc_tpInfo);
539         }
540       }
541       JButton cancelButton = new JButton("Cancel");
542       cancelButton.addActionListener(new ActionListener() {
543         public void actionPerformed(ActionEvent e) {
544           omc.disconnect();
545           getTpInfo().setText(DISCONNECTED);
546           getTpInfo().setBackground(Color.ORANGE);
547         }
548       });
549       cancelButton.setActionCommand("Cancel");
550       GridBagConstraints gbc_cancelButton = new GridBagConstraints();
551       gbc_cancelButton.anchor = GridBagConstraints.NORTHWEST;
552       gbc_cancelButton.gridx = 2;
553       gbc_cancelButton.gridy = 0;
554       buttonPane.add(cancelButton, gbc_cancelButton);
555     }
556   }
557 
558   /**
559    * Action on Test button.
560    * 
561    * <p>Try to connect to Omero using credentials stored and downloads datasets from Omero and
562    * populates them to Download tab.
563    * 
564    * @author p.baniukiewicz
565    *
566    */
567   @SuppressWarnings("serial")
568   private class ConnectAction extends AbstractAction {
569     public ConnectAction() {
570       putValue(NAME, "Connect");
571       putValue(SHORT_DESCRIPTION, "Connect to database and read datasets.");
572     }
573 
574     public void actionPerformed(ActionEvent e) {
575       if (omc.connect()) {
576         getTpInfo().setText(CONNECTED);
577         getTpInfo().setBackground(Color.GREEN);
578         JList<String> lid = getListDatasetsDownload();
579         JList<String> liu = getListDatasetsUpload();
580         DefaultListModel<String> model = new DefaultListModel<String>();
581         for (DatasetData e1 : omc.getDatasets()) {
582           model.addElement(e1.getName() + " (" + e1.getId() + ")");
583         }
584         lid.setModel(model);
585         liu.setModel(model);
586 
587       } else {
588         getTpInfo().setText(DISCONNECTED);
589         getTpInfo().setBackground(Color.ORANGE);
590       }
591     }
592   }
593 
594   /**
595    * Action on Download button.
596    * 
597    * <p>switch tab to download.
598    * 
599    * @author p.baniukiewicz
600    *
601    */
602   @SuppressWarnings("serial")
603   private class DownloadAction extends AbstractAction {
604     public DownloadAction() {
605       putValue(NAME, "Download");
606       putValue(SHORT_DESCRIPTION, "Download experiment");
607     }
608 
609     public void actionPerformed(ActionEvent e) {
610       getTabbedPane().setSelectedComponent(getPanelDownload());
611     }
612   }
613 
614   /**
615    * Action on Upload button.
616    * 
617    * <p>switch tab to upload.
618    * 
619    * @author p.baniukiewicz
620    *
621    */
622   @SuppressWarnings("serial")
623   private class UploadAction extends AbstractAction {
624     public UploadAction() {
625       putValue(NAME, "Upload");
626       putValue(SHORT_DESCRIPTION, "Upload folder");
627     }
628 
629     public void actionPerformed(ActionEvent e) {
630       getTabbedPane().setSelectedComponent(getPanelUpload());
631     }
632   }
633 
634   protected JTabbedPane getTabbedPane() {
635     return tabbedPane;
636   }
637 
638   protected JPanel getPanelDownload() {
639     return panelDownload;
640   }
641 
642   protected JPanel getPanelUpload() {
643     return panelUpload;
644   }
645 
646   /**
647    * Action executed on Store checkbox.
648    * 
649    * <p>Copies current prefs to IJ prefs or clean those stored already.
650    * 
651    * @author p.baniukiewicz
652    *
653    */
654   @SuppressWarnings("serial")
655   private class StoreAction extends AbstractAction {
656 
657     public StoreAction() {
658       putValue(NAME, "Store credentials");
659       putValue(SHORT_DESCRIPTION, "Store login details in ImageJ preference file");
660     }
661 
662     public void actionPerformed(ActionEvent e) {
663       if (e.getSource() instanceof JCheckBox) {
664         JCheckBox obj = (JCheckBox) e.getSource();
665         LOGGER.debug("Store: " + obj.isSelected());
666         if (obj.isSelected()) { // upload content to IJ
667           omc.uploadPrefs(false);
668         } else { // erase content
669           omc.uploadPrefs(true);
670         }
671       }
672     }
673   }
674 
675   protected JCheckBox getChckbxStoreCred() {
676     return chckbxStoreCred;
677   }
678 
679   protected JTextPane getTpInfo() {
680     return tpInfo;
681   }
682 
683   protected JPanel getPanelSetup() {
684     return panelSetup;
685   }
686 
687   protected JList<String> getListDatasetsDownload() {
688     return listDatasetsDownload;
689   }
690 
691   protected JTable getTableImagesDownload() {
692     return tableImagesDownload;
693   }
694 
695   protected JList<String> getListDatasetsUpload() {
696     return listDatasetsUpload;
697   }
698 
699   protected JTable getTableImagesUpload() {
700     return tableImagesUpload;
701   }
702 
703   /**
704    * Action executed on uploading experiment button.
705    * 
706    * @author p.baniukiewicz
707    *
708    */
709   @SuppressWarnings("serial")
710   private class UploadExperimentAction extends AbstractAction {
711     public UploadExperimentAction() {
712       putValue(NAME, "Select experiment and upload");
713       putValue(SHORT_DESCRIPTION, "Upload QCONF to Omero");
714     }
715 
716     public void actionPerformed(ActionEvent e) {
717       setPanelEnabled(getContentPane(), false);
718       omc.upload();
719       if (omc.getCurrentDatasets().validate()) {
720         imageTableModel.update(omc.getImages(omc.getCurrentDatasets().currentEl));
721       }
722       setPanelEnabled(getContentPane(), true);
723     }
724   }
725 
726   private void setPanelEnabled(Container container, Boolean isEnabled) {
727     container.setEnabled(isEnabled);
728 
729     Component[] components = container.getComponents();
730 
731     for (Component component : components) {
732       if (component instanceof Container) {
733         setPanelEnabled((Container) component, isEnabled);
734       }
735       component.setEnabled(isEnabled);
736     }
737   }
738 
739   /**
740    * Action executed on download experiment button.
741    * 
742    * @author p.baniukiewicz
743    *
744    */
745   @SuppressWarnings("serial")
746   private class DownloadExperimentAction extends AbstractAction {
747     public DownloadExperimentAction() {
748       putValue(NAME, "Select folder and download");
749       putValue(SHORT_DESCRIPTION, "Download selected dataset");
750     }
751 
752     public void actionPerformed(ActionEvent e) {
753       String folder = new DirectoryChooser("Select destination folder").getDirectory();
754       if (folder != null && !folder.isEmpty()) {
755         setPanelEnabled(getContentPane(), false);
756         omc.download(folder);
757         setPanelEnabled(getContentPane(), true);
758       }
759     }
760   }
761 
762   protected JPanel getContentPanel() {
763     return contentPanel;
764   }
765 }
766 
767 class ImageTable extends AbstractTableModel {
768 
769   public String[] columnNames = { "Image", "Creation time", "ID" };
770 
771   List<String[]> rows;
772 
773   public ImageTable() {
774     rows = new ArrayList<>();
775   }
776 
777   @Override
778   public int getRowCount() {
779     return rows.size();
780   }
781 
782   /*
783    * (non-Javadoc)
784    * 
785    * @see javax.swing.table.AbstractTableModel#getColumnName(int)
786    */
787   @Override
788   public String getColumnName(int column) {
789     return columnNames[column];
790   }
791 
792   @Override
793   public int getColumnCount() {
794     return columnNames.length;
795   }
796 
797   @Override
798   public Object getValueAt(int rowIndex, int columnIndex) {
799     return rows.get(rowIndex)[columnIndex];
800   }
801 
802   public void update(List<ImageData> up) {
803     rows.clear();
804     for (ImageData im : up) {
805       rows.add(new String[] { im.getName(),
806           new SimpleDateFormat("yyyy-MM-dd-HH mm ss").format(im.getCreated()),
807           Long.toString(im.getId()) });
808     }
809     fireTableDataChanged();
810   }
811 
812 }