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.configurationwizard; 030 031import java.awt.BorderLayout; 032import java.awt.Dimension; 033import java.awt.Point; 034import java.awt.event.ActionEvent; 035import java.awt.event.MouseAdapter; 036import java.awt.event.MouseEvent; 037 038import javax.swing.AbstractAction; 039import javax.swing.BorderFactory; 040import javax.swing.JMenuItem; 041import javax.swing.JPanel; 042import javax.swing.JPopupMenu; 043import javax.swing.JScrollPane; 044import javax.swing.JTable; 045import javax.swing.ListSelectionModel; 046 047import org.kepler.module.workflowschedulergui.Initialize; 048import org.kepler.workflowscheduler.gui.WorkflowRunEngine; 049 050 051public class KnownWorkflowRunEnginePanel extends JPanel implements WorkflowRunEngineConfigurationChangeListener 052{ 053 private int BORDERGAP = 20; 054 private WorkflowRunEngine[] engineList = null; 055 private KnownWorkflowRunEngineTableModel engineTableModel = null; 056 private JTable engineTable = null; 057 private WorkflowRunEngine selectedEngine = null; 058 059 /** 060 * Constructor 061 * @param engineList 062 */ 063 public KnownWorkflowRunEnginePanel(WorkflowRunEngine[] engineList) 064 { 065 this.engineList = engineList; 066 initialize(); 067 } 068 /* 069 * Initialize the panel 070 */ 071 private void initialize() 072 { 073 074 this.setLayout(new BorderLayout()); 075 this.setBorder(BorderFactory.createEmptyBorder(BORDERGAP, BORDERGAP, BORDERGAP, BORDERGAP)); 076 //JTableHeader header = scheduleTable.getTableHeader(); 077 //header.setBackground(Color.LIGHT_GRAY); 078 engineTableModel = new KnownWorkflowRunEngineTableModel(engineList); 079 engineTable = new JTable(engineTableModel); 080 engineTable.setAutoCreateColumnsFromModel(false); 081 engineTable.addMouseListener(new PopupListener()); 082 engineTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 083 JScrollPane scrollPane = new JScrollPane(engineTable); 084 scrollPane.setPreferredSize(new Dimension(600, 150)); 085 //scrollPane.setPreferredSize(new Dimension(800, 180)); 086 add(scrollPane, BorderLayout.CENTER); 087 /*if(engineList == null) 088 { 089 this.setVisible(false); 090 }*/ 091 092 } 093 094 /* 095 * Update the table after the table data model was changed 096 */ 097 private void updateTable() 098 { 099 engineTableModel = new KnownWorkflowRunEngineTableModel(engineList); 100 engineTable.setModel(engineTableModel); 101 //scheduleTableModel.fireTableDataChanged(); 102 engineTable.repaint(); 103 engineTable.validate(); 104 /*if(engineList == null) 105 { 106 this.setVisible(false); 107 } 108 else 109 { 110 this.setVisible(true); 111 }*/ 112 //System.out.println("After repaint table"); 113 } 114 115 116 /** 117 * Add a new engine to the configuration 118 * @param engine then engine will be added 119 */ 120 public void add(WorkflowRunEngine engine) 121 { 122 if(engine != null) 123 { 124 if(engineList == null ) 125 { 126 engineList = new WorkflowRunEngine[1]; 127 engineList[0] = engine; 128 } 129 else 130 { 131 WorkflowRunEngine[] oldArray = engineList; 132 int size = engineList.length; 133 int newSize = size+1; 134 engineList = new WorkflowRunEngine[newSize]; 135 engineList[0]= engine; 136 for(int i=0; i<size; i++) 137 { 138 engineList[i+1] = oldArray[i]; 139 } 140 } 141 updateTable(); 142 } 143 } 144 145 /* 146 * Delete an engine. 147 */ 148 private void delete(WorkflowRunEngine engine) 149 { 150 //first delete the engine from configuration file 151 Initialize.removeWorkflowRunEngineFromConfig(engine); 152 if(engine != null) 153 { 154 if(engineList != null && engineList.length != 0) 155 { 156 boolean foundIt = false; 157 WorkflowRunEngine[] oldArray = engineList; 158 int size = engineList.length; 159 int newSize = size-1; 160 WorkflowRunEngine[] newArray = null; 161 if(newSize > 0) 162 { 163 //Note: only newSize is greater than zero, we initialize the array. 164 newArray = new WorkflowRunEngine[newSize]; 165 } 166 //compare size -1 elements in old array 167 for(int i=0; i<newSize; i++) 168 { 169 WorkflowRunEngine existEngine = oldArray[i]; 170 if( existEngine != null && existEngine.getName() != null && 171 existEngine.getName().equals(engine.getName()) && 172 existEngine.getURL() != null && existEngine.getURL().equals(engine.getURL())) 173 { 174 foundIt = true; 175 newArray[i] = oldArray[i+1];//skip the the element having index=i in old array. 176 } 177 else 178 { 179 if(!foundIt) 180 { 181 newArray[i]=oldArray[i]; 182 } 183 else 184 { 185 newArray[i] = oldArray[i+1]; 186 } 187 } 188 } 189 190 if(!foundIt) 191 { 192 //If we didn't find matched schedule above for loop, 193 //We must compare the last element in the original list 194 WorkflowRunEngine existEngine = oldArray[size-1]; 195 if( existEngine != null && existEngine.getName() != null && 196 existEngine.getName().equals(engine.getName()) && 197 existEngine.getURL() != null && existEngine.getURL().equals(engine.getURL())) 198 { 199 // the last element is the schedule we will remove. So 200 //scheduleList will be the newArray 201 engineList = newArray; 202 updateTable(); 203 } 204 205 } 206 else 207 { 208 engineList = newArray; 209 updateTable(); 210 } 211 212 213 } 214 } 215 216 } 217 218 /* 219 * Class to handle right-click menu 220 */ 221 private class PopupListener extends MouseAdapter 222 { 223 224 // on the Mac, popups are triggered on mouse pressed, while mouseReleased triggers them 225 // on the PC; use the trigger flag to record a trigger in mac, but do not show popup until the 226 // mouse released event 227 228 boolean trigger = false; 229 private JPopupMenu popup = null; 230 //private WorkflowRunEngine selectedEngine = null; 231 232 /** 233 * Handle mouse pressed event 234 */ 235 public void mousePressed(MouseEvent e) 236 { 237 238 //select the clicked row first 239 engineTable.clearSelection(); 240 int selrow = engineTable.rowAtPoint(new Point(e.getX(), e.getY())); 241 //System.out.println("the selection row number is============= "+selrow); 242 engineTable.setRowSelectionInterval(selrow, selrow); 243 selectedEngine = engineList[selrow]; 244 // for mac 245 if (e.isPopupTrigger()) 246 { 247 trigger = true; 248 } 249 250 } 251 252 /** 253 * Handle mouse released event 254 */ 255 public void mouseReleased(MouseEvent e) 256 { 257 maybeShowPopup(e); 258 } 259 260 /* 261 *Show right popup menu 262 */ 263 private void maybeShowPopup(MouseEvent e) 264 { 265 //trigger = true is for mac. e.isPopupTrigger() is for pc 266 if(e.isPopupTrigger() || trigger) 267 { 268 if(selectedEngine != null) 269 { 270 popup = new JPopupMenu(); 271 JMenuItem delete = new JMenuItem("Delete"); 272 DeleteWorkflowRunEngineAction deleteAction = new DeleteWorkflowRunEngineAction(selectedEngine); 273 delete.addActionListener(deleteAction); 274 popup.add(delete); 275 trigger = false; 276 popup.show(e.getComponent(), e.getX(), e.getY()); 277 } 278 279 } 280 } 281 282 } 283 284 /* 285 * Action to remove the workflow run engine from configuration file and also remove 286 * it from the known workflow run engine table. 287 * @author tao 288 * 289 */ 290 private class DeleteWorkflowRunEngineAction extends AbstractAction 291 { 292 private WorkflowRunEngine deletedEngine = null; 293 294 public DeleteWorkflowRunEngineAction(WorkflowRunEngine deletedEngine) 295 { 296 this.deletedEngine = deletedEngine; 297 } 298 /** 299 * Remove the selected engine 300 */ 301 public void actionPerformed(ActionEvent e) 302 { 303 delete(deletedEngine); 304 } 305 } 306 307}