001/** 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 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 */ 029package org.kepler.workflowscheduler.gui; 030 031import java.awt.BorderLayout; 032import java.awt.Dimension; 033import java.awt.Point; 034import java.awt.event.MouseAdapter; 035import java.awt.event.MouseEvent; 036 037import javax.swing.BorderFactory; 038import javax.swing.JMenuItem; 039import javax.swing.JPanel; 040import javax.swing.JPopupMenu; 041import javax.swing.JScrollPane; 042import javax.swing.JTable; 043import javax.swing.border.TitledBorder; 044 045import ptolemy.actor.gui.TableauFrame; 046 047 048/** 049 * A tab pane to display existing schedule. 050 * @author tao 051 * 052 */ 053public class ExistingSchedulePanel extends JPanel implements ScheduleChangeListenerInterface 054{ 055 private static final String TITLE = "Existing Schedules"; 056 private Schedule[] scheduleList = null; 057 private ScheduleTableModel scheduleTableModel = null; 058 private JTable scheduleTable = null; 059 private TableauFrame parent = null; 060 private ScheduleChangeController scheduleChangeController = null; 061 private WorkflowSchedulerParentPanel schedulerParentPanel = null; 062 063 /** 064 * Constructor 065 */ 066 public ExistingSchedulePanel(Schedule[] scheduleList, TableauFrame parent, 067 WorkflowSchedulerParentPanel schedulerParentPanel, ScheduleChangeController scheduleChangeController) 068 { 069 this.scheduleList = scheduleList; 070 this.parent = parent; 071 this.schedulerParentPanel = schedulerParentPanel; 072 this.scheduleChangeController = scheduleChangeController; 073 initialize(); 074 } 075 076 /* 077 * Initialize the panel 078 */ 079 private void initialize() 080 { 081 //create a titled border for parameter panel 082 TitledBorder title = BorderFactory.createTitledBorder(TITLE); 083 setBorder(title); 084 this.setLayout(new BorderLayout()); 085 //JTableHeader header = scheduleTable.getTableHeader(); 086 //header.setBackground(Color.LIGHT_GRAY); 087 scheduleTableModel = new ScheduleTableModel(scheduleList); 088 scheduleTable = new JTable(scheduleTableModel); 089 scheduleTable.setAutoCreateColumnsFromModel(false); 090 PopupListener popupListener = new PopupListener(); 091 scheduleTable.addMouseListener(popupListener); 092 JScrollPane scrollPane = new JScrollPane(scheduleTable); 093 scrollPane.setPreferredSize(new Dimension(800, 180)); 094 add(scrollPane, BorderLayout.CENTER); 095 096 } 097 098 /** 099 * Handle the event that a new schedule is added 100 * Note: this method will handle the table which displays existing schedules. 101 * It doesn't do anything to the server. 102 * @param schedule the new schedule 103 * @throws Exception 104 */ 105 public void addSchedule(Schedule schedule) throws Exception 106 { 107 if(schedule != null && schedule.isValid()) 108 { 109 if(scheduleList == null ) 110 { 111 scheduleList = new Schedule[1]; 112 scheduleList[0] = schedule; 113 } 114 else 115 { 116 117 Schedule[] oldArray = scheduleList; 118 int size = scheduleList.length; 119 int newSize = size+1; 120 scheduleList = new Schedule[newSize]; 121 scheduleList[0]= schedule; 122 for(int i=0; i<size; i++) 123 { 124 scheduleList[i+1] = oldArray[i]; 125 } 126 } 127 updateTable(); 128 } 129 else 130 { 131 throw new Exception("The added schedule is not valid schedule and we couldn't add it"); 132 } 133 134 } 135 136 /** 137 * Handle the event that a schedule is removed. 138 * Note: this method will handle the table which displays existing schedules. 139 * It doesn't do anything to the server. 140 * @param schedule the schedule will be removed 141 * @throws Exception 142 */ 143 public void removeSchedule(Schedule schedule) throws Exception 144 { 145 if(schedule != null) 146 { 147 if(scheduleList == null || scheduleList.length == 0) 148 { 149 throw new Exception("Current schedule list is empty and we couldn't remove any schedule from it"); 150 } 151 else 152 { 153 boolean foundIt = false; 154 Schedule[] oldArray = scheduleList; 155 int size = scheduleList.length; 156 int newSize = size-1; 157 Schedule[] newArray = null; 158 if(newSize > 0) 159 { 160 //Note: only newSize is greater than zero, we initialize the array. 161 newArray = new Schedule[newSize]; 162 } 163 //compare size -1 elements in old array 164 for(int i=0; i<newSize; i++) 165 { 166 Schedule existSchedule = oldArray[i]; 167 if(existSchedule != null && existSchedule.getWorkflowJobName() != null && 168 existSchedule.getWorkflowJobName().equals(schedule.getWorkflowJobName())) 169 { 170 foundIt = true; 171 newArray[i] = oldArray[i+1];//skip the the element having index=i in old array. 172 } 173 else 174 { 175 if(!foundIt) 176 { 177 newArray[i]=oldArray[i]; 178 } 179 else 180 { 181 newArray[i] = oldArray[i+1]; 182 } 183 } 184 } 185 186 if(!foundIt) 187 { 188 //If we didn't find matched schedule above for loop, 189 //We must compare the last element in the original list 190 Schedule existSchedule = oldArray[size-1]; 191 if(existSchedule != null && existSchedule.getWorkflowJobName() != null && 192 existSchedule.getWorkflowJobName().equals(schedule.getWorkflowJobName())) 193 { 194 // the last element is the schedule we will remove. So 195 //scheduleList will be the newArray 196 scheduleList = newArray; 197 updateTable(); 198 } 199 else 200 { 201 throw new Exception("We couldn't find the deleted schedule "+schedule.getWorkflowJobName() +" in the existing schedule list. So remove action couldn't be peformed"); 202 } 203 } 204 else 205 { 206 scheduleList = newArray; 207 updateTable(); 208 } 209 210 211 } 212 } 213 else 214 { 215 throw new Exception("The removed schedule is not valid schedule and we couldn't remove it"); 216 } 217 } 218 219 /** 220 * Handle the event that a schedule will be enabled 221 * Note: this method will handle the table which displays existing schedules. 222 * It doesn't do anything to the server. 223 * @param schedule the schedule will be enabled 224 * @throws Exception 225 */ 226 public void enableSchedule(Schedule schedule) throws Exception 227 { 228 setScheduleStatus(true, schedule); 229 } 230 231 /** 232 * Handle the event that a schedule will be disabled 233 * Note: this method will handle the table which displays existing schedules. 234 * It doesn't do anything to the server. 235 * @param schedule the schedule will be disabled 236 * @throws Exception 237 */ 238 public void disableSchedule(Schedule schedule) throws Exception 239 { 240 setScheduleStatus(false, schedule); 241 } 242 243 /* 244 * Set a schedule to be enabled or disalbed 245 */ 246 private void setScheduleStatus(boolean enabled, Schedule schedule) 247 { 248 if(schedule != null && scheduleList != null && scheduleList.length >0) 249 { 250 String workflowJobName = schedule.getWorkflowJobName(); 251 if(workflowJobName != null) 252 { 253 for(int i=0; i<scheduleList.length; i++) 254 { 255 Schedule existingSchedule = scheduleList[i]; 256 if(existingSchedule != null && workflowJobName.equals(existingSchedule.getWorkflowJobName())) 257 { 258 existingSchedule.setEnabled(enabled); 259 updateTable(); 260 } 261 } 262 } 263 } 264 } 265 266 /** 267 * Handle the event that new schedules will replace the old ones 268 * @param newSchedule new schedules 269 * @throws Exception 270 */ 271 public void update(Schedule[] newSchedules) throws Exception 272 { 273 scheduleList = newSchedules; 274 updateTable(); 275 this.repaint(); 276 this.validate(); 277 } 278 279 /* 280 * Update the table after the table data model was changed 281 */ 282 private void updateTable() 283 { 284 scheduleTableModel = new ScheduleTableModel(scheduleList); 285 scheduleTable.setModel(scheduleTableModel); 286 //scheduleTableModel.fireTableDataChanged(); 287 scheduleTable.repaint(); 288 scheduleTable.validate(); 289 //System.out.println("After repaint table"); 290 } 291 292 /* 293 * Class to handle right-click menu 294 */ 295 private class PopupListener extends MouseAdapter { 296 297 // on the Mac, popups are triggered on mouse pressed, while mouseReleased triggers them 298 // on the PC; use the trigger flag to record a trigger in mac, but do not show popup until the 299 // mouse released event 300 301 boolean trigger = false; 302 private JPopupMenu popup = null; 303 private Schedule selectedSchedule = null; 304 305 /** 306 * Handle mouse pressed event 307 */ 308 public void mousePressed(MouseEvent e) 309 { 310 311 //select the clicked row first 312 scheduleTable.clearSelection(); 313 int selrow = scheduleTable.rowAtPoint(new Point(e.getX(), e.getY())); 314 //System.out.println("the selection row number is============= "+selrow); 315 scheduleTable.setRowSelectionInterval(selrow, selrow); 316 selectedSchedule = scheduleList[selrow]; 317 // for mac 318 if (e.isPopupTrigger()) 319 { 320 trigger = true; 321 } 322 323 } 324 325 /** 326 * Handle mouse released event 327 */ 328 public void mouseReleased(MouseEvent e) 329 { 330 maybeShowPopup(e); 331 } 332 333 /* 334 *Show right popup menu 335 */ 336 private void maybeShowPopup(MouseEvent e) 337 { 338 //trigger = true is for mac. e.isPopupTrigger() is for pc 339 if(e.isPopupTrigger() || trigger) 340 { 341 if(selectedSchedule != null) 342 { 343 popup = new JPopupMenu(); 344 RemoveScheduleAction deleteAction = new RemoveScheduleAction(parent, schedulerParentPanel, scheduleChangeController); 345 deleteAction.setSchedule(selectedSchedule); 346 JMenuItem delete = new JMenuItem("Delete"); 347 delete.addActionListener(deleteAction); 348 popup.add(delete); 349 EnableScheduleAction enableAction = null; 350 DisableScheduleAction disableAction = null; 351 boolean isEnabled = selectedSchedule.isEnabled(); 352 if(isEnabled) 353 { 354 disableAction = new DisableScheduleAction(parent, schedulerParentPanel, scheduleChangeController); 355 disableAction.setSchedule(selectedSchedule); 356 JMenuItem disable = new JMenuItem("Disable"); 357 disable.addActionListener(disableAction); 358 popup.add(disable); 359 } 360 else 361 { 362 enableAction = new EnableScheduleAction(parent, schedulerParentPanel,scheduleChangeController); 363 enableAction.setSchedule(selectedSchedule); 364 JMenuItem enable = new JMenuItem("Enable"); 365 enable.addActionListener(enableAction); 366 popup.add(enable); 367 } 368 trigger = false; 369 popup.show(e.getComponent(), e.getX(), e.getY()); 370 } 371 372 } 373 } 374 375 } 376 377}