001/** 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: tao $' 006 * '$Date: 2010-06-03 16:45:10 -0700 (Thu, 03 Jun 2010) $' 007 * '$Revision: 24730 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.workflowscheduler.gui; 031 032import java.awt.BorderLayout; 033import java.awt.Container; 034import java.awt.Dimension; 035import java.awt.event.ActionEvent; 036import java.awt.event.ActionListener; 037import java.awt.event.WindowAdapter; 038import java.awt.event.WindowEvent; 039import java.util.List; 040 041import javax.swing.Box; 042import javax.swing.BoxLayout; 043import javax.swing.JButton; 044import javax.swing.JDialog; 045import javax.swing.JOptionPane; 046import javax.swing.JPanel; 047import javax.swing.JProgressBar; 048import javax.swing.SwingUtilities; 049 050import org.kepler.gui.ComponentLibraryTab; 051import org.kepler.gui.DualVerticalViewPane; 052import org.kepler.gui.TabPane; 053import org.kepler.gui.ViewPaneLocation; 054import org.kepler.gui.state.StateChangeEvent; 055import org.kepler.gui.state.StateChangeListener; 056import org.kepler.gui.state.StateChangeMonitor; 057import org.kepler.module.workflowschedulergui.Initialize; 058import org.kepler.workflowscheduler.gui.configurationwizard.WorkflowSchedulerConfigEvent; 059 060import ptolemy.actor.gui.TableauFrame; 061//import org.kepler.workflowscheduler.gui.configurationwizard.CompletingConfigurationListenerInterface; 062 063/** 064 * A dialog to display the workflow scheduler. This is a singleton class. 065 * It has two main panels. Left one is the component search. Right one 066 * is the scheduler parent panel. Scheduler parent panel has two options: 067 * shows the real scheduler panel when user click a remote workflow or show 068 * a message to indicate user to choose a remote workflow for scheduling 069 * @author tao 070 * 071 */ 072public class WorkflowSchedulerDialog extends JDialog implements ProgressBarControlInterface, StateChangeListener 073{ 074 private static final String TITLE = "Workflow Scheduler"; 075 private static final String COMPONENTS = "Components"; 076 private static final String EAST ="E"; 077 private static final int WIDTH = 1150; 078 private static final int HEIGHT = 650; 079 public static final int PROGRESSMIN = 0; 080 public static final int PROGRESSMAX = 100; 081 082 //private WorkflowSchedulerDialog scheduler = null; 083 private TableauFrame parent = null; 084 //private JButton okButton = null; 085 //private JButton cancelButton =null; 086 private JButton closeButton = null; 087 private JPanel topPanel = null; 088 private JProgressBar progressBar = null; 089 //private boolean showedMessage = true; 090 private ScheduleChangeController scheduleChangeController; 091 private WorkflowSchedulerComponentLibraryTab componentsTab = null; 092 private DualVerticalViewPane componentAndSchedulerPane = null; 093 094 /** 095 * Constructor 096 */ 097 public WorkflowSchedulerDialog(TableauFrame parent) 098 { 099 super(parent); 100 this.parent = parent; 101 initialize(); 102 this.pack(); 103 this.setVisible(true); 104 } 105 106 /* 107 * Initialize the dialog 108 */ 109 private void initialize() 110 { 111 scheduleChangeController = new ScheduleChangeController(); 112 scheduleChangeController.addListener(this); 113 setTitle(TITLE); 114 setPreferredSize(new Dimension(WIDTH, HEIGHT)); 115 if(parent != null) 116 { 117 setLocation(parent.getLocation()); 118 } 119 120 topPanel = new JPanel(); 121 topPanel.setLayout(new BorderLayout()); 122 componentAndSchedulerPane = new DualVerticalViewPane(); 123 try 124 { 125 componentAndSchedulerPane.initializeView(); 126 } 127 catch(Exception e) 128 { 129 JOptionPane.showMessageDialog(parent, "Couldn't initialize the scheduler dialog - "+ 130 e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 131 return; 132 } 133 134 componentsTab = new WorkflowSchedulerComponentLibraryTab(parent); 135 componentsTab.initializeTab(); 136 //componentsTab.setPreferredSize(new Dimension(200, HEIGHT)); 137 componentsTab.setTabName(COMPONENTS); 138 componentsTab.setSkipReposiotryOntology(true); 139 scheduleChangeController.setComponentLibraryTab(componentsTab); 140 //jTree = componentsTab.getJTree(); 141 //scheduleChangeController.setResultTree(jTree); 142 143 try 144 { 145 componentAndSchedulerPane.addTabPane(componentsTab, new ViewPaneLocation("W")); 146 initRightPanel(); 147 } 148 catch(Exception e) 149 { 150 JOptionPane.showMessageDialog(this, "Couldn't initialize the scheduler dialog - "+ 151 e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 152 return; 153 } 154 //topPanel.add(schedulerPanel, BorderLayout.EAST); 155 topPanel.add(componentAndSchedulerPane, BorderLayout.CENTER); 156 157 progressBar = new JProgressBar(PROGRESSMIN, PROGRESSMAX); 158 Dimension barDimension = new Dimension(300, 10); 159 progressBar.setPreferredSize(barDimension); 160 progressBar.setMaximumSize(barDimension); 161 progressBar.setVisible(false); 162 //progressBar.setIndeterminate(true); 163 164 closeButton = new JButton("Close"); 165 closeButton.setPreferredSize(new Dimension(100, 50)); 166 closeButton.addActionListener(new ActionListener() 167 { 168 public void actionPerformed(ActionEvent e) 169 { 170 setVisible(false); 171 } 172 }); 173 174 JPanel buttonPanel = new JPanel(); 175 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); 176 buttonPanel.add(progressBar); 177 buttonPanel.add(Box.createHorizontalGlue()); 178 //buttonPanel.setMaximumSize(new Dimension(350, 40)); 179 //buttonPanel.add(okButton); 180 //buttonPanel.add(Box.createHorizontalStrut(10)); 181 buttonPanel.add(closeButton); 182 buttonPanel.add(Box.createHorizontalStrut(10)); 183 topPanel.add(buttonPanel, BorderLayout.SOUTH); 184 185 getContentPane().add(topPanel); 186 addWindowListener(new DialogWindowAdapter(this)); 187 StateChangeMonitor.getInstance().addStateChangeListener(WorkflowSchedulerConfigEvent.MODIFYCONFIGEVENT, this); 188 } 189 190 191 /* 192 * If the workflow scheduler and run engine were configured, it will show a scheduler panel. 193 * Otherwise it will show an installation info panel 194 */ 195 private void initRightPanel() throws Exception 196 { 197 if(Initialize.isSchedulerURLConfigured() && Initialize.isWorkflowRunEngineConfigured()) 198 { 199 WorkflowSchedulerParentPanel schedulerPanel = 200 new WorkflowSchedulerParentPanel(parent, scheduleChangeController); 201 ComponentSearchResultTreeSelectionListener listener = 202 new ComponentSearchResultTreeSelectionListener(schedulerPanel); 203 componentsTab.addTreeSingleSelectionListener(listener); 204 componentAndSchedulerPane.addTabPane(schedulerPanel, new ViewPaneLocation(EAST)); 205 } 206 else 207 { 208 WorkflowSchedulerServerInstallationInfoPanel informationPanel = 209 new WorkflowSchedulerServerInstallationInfoPanel(parent, this); 210 componentAndSchedulerPane.addTabPane(informationPanel, new ViewPaneLocation(EAST)); 211 } 212 213 } 214 215 216 /** 217 * Method will be called when configuration is done 218 */ 219 public void handleStateChange(StateChangeEvent event) 220 { 221 if(event.getChangedState() != null && event.getChangedState().equals(WorkflowSchedulerConfigEvent.MODIFYCONFIGEVENT)) 222 { 223 try 224 { 225 //remove the old server installation info panel since the information may be incorrect after configuring the properties. 226 Container eastContainer = componentAndSchedulerPane.getLocationContainer(EAST); 227 List<TabPane> list = componentAndSchedulerPane.getTabPanes(WorkflowSchedulerParentPanel.SCHEDULER); 228 if(list != null) 229 { 230 for(TabPane pane : list) 231 { 232 if(pane instanceof WorkflowSchedulerServerInstallationInfoPanel) 233 { 234 WorkflowSchedulerServerInstallationInfoPanel infoPane = (WorkflowSchedulerServerInstallationInfoPanel)pane; 235 //System.out.println("removing the old information panel"); 236 eastContainer.remove(infoPane); 237 } 238 else if (pane instanceof WorkflowSchedulerParentPanel) 239 { 240 WorkflowSchedulerParentPanel schedulerParentPane = (WorkflowSchedulerParentPanel) pane; 241 //System.out.println("removing the old parent panel"); 242 eastContainer.remove(schedulerParentPane); 243 } 244 245 } 246 } 247 } 248 catch(Exception e) 249 { 250 return; 251 } 252 try 253 { 254 //initialize the new right panel base on the new configuration status (workflow url and run engines are configured or not) 255 initRightPanel(); 256 } 257 catch(Exception e) 258 { 259 JOptionPane.showMessageDialog(this, "Couldn't update the scheduler dialog - "+ 260 e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 261 } 262 componentAndSchedulerPane.validate(); 263 componentAndSchedulerPane.repaint(); 264 } 265 266 } 267 268 269 /** 270 * Get the component search tab 271 * @return 272 */ 273 public ComponentLibraryTab getComponentSearchTab() 274 { 275 return componentsTab; 276 } 277 /** 278 * Handle the event that a new schedule is added 279 * @param schedule the new schedule 280 * @throws Exception 281 */ 282 public void addSchedule(Schedule schedule) throws Exception 283 { 284 //do nothing 285 } 286 287 /** 288 * Handle the event that a schedule is removed 289 * @param schedule the schedule will be removed 290 * @throws Exception 291 */ 292 public void removeSchedule(Schedule schedule) throws Exception 293 { 294 //do nothing 295 } 296 297 /** 298 * Handle the event that a schedule will be enabled 299 * @param schedule the schedule will be enabled 300 * @throws Exception 301 */ 302 public void enableSchedule(Schedule schedule) throws Exception 303 { 304 //do nothing 305 } 306 307 /** 308 * Handle the event that a schedule will be disabled 309 * @param schedule the schedule will be disabled 310 * @throws Exception 311 */ 312 public void disableSchedule(Schedule schedule) throws Exception 313 { 314 //do nothing 315 } 316 317 /** 318 * Handle the event that new schedules will replace the old ones 319 * @param newSchedule new schedules 320 * @throws Exception 321 */ 322 public void update(Schedule[] newSchedules) throws Exception 323 { 324 //do nothing 325 } 326 327 /** 328 * Start the progress bar 329 * 330 */ 331 public void start() 332 { 333 if(progressBar != null) 334 { 335 SwingUtilities.invokeLater(new Runnable() 336 { 337 public void run() 338 { 339 progressBar.setVisible(true); 340 progressBar.setIndeterminate(true); 341 } 342 343 }); 344 } 345 } 346 347 /** 348 * Stop the progress bar 349 */ 350 public void stop() 351 { 352 if(progressBar != null) 353 { 354 SwingUtilities.invokeLater(new Runnable() 355 { 356 public void run() 357 { 358 progressBar.setIndeterminate(false); 359 progressBar.setValue(PROGRESSMAX); 360 progressBar.setVisible(false); 361 } 362 363 }); 364 } 365 } 366 367 /* 368 * A customized window adapter: the dialog box will be set invisible 369 * when users close the dialog. 370 */ 371 private class DialogWindowAdapter extends WindowAdapter 372 { 373 private JDialog dialog = null; 374 375 /** 376 * Constructor 377 * @param dialog 378 */ 379 public DialogWindowAdapter(JDialog dialog) 380 { 381 this.dialog = dialog; 382 } 383 384 /** 385 * Set the dialog box invisible 386 */ 387 public void windowClosing(WindowEvent e) 388 { 389 if(dialog != null) 390 { 391 dialog.setVisible(false); 392 } 393 } 394 } 395}