1 19 20 package taskblocks.app; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Component ; 24 import java.awt.FileDialog ; 25 import java.awt.Font ; 26 import java.awt.Toolkit ; 27 import java.awt.event.ActionEvent ; 28 import java.awt.event.ActionListener ; 29 import java.awt.event.KeyEvent ; 30 import java.awt.event.MouseEvent ; 31 import java.awt.event.WindowEvent ; 32 import java.awt.event.WindowListener ; 33 import java.io.File ; 34 import java.util.ArrayList ; 35 import java.util.List ; 36 37 import javax.swing.Action ; 38 import javax.swing.Box ; 39 import javax.swing.JCheckBoxMenuItem ; 40 import javax.swing.JFileChooser ; 41 import javax.swing.JFrame ; 42 import javax.swing.JLabel ; 43 import javax.swing.JMenu ; 44 import javax.swing.JMenuBar ; 45 import javax.swing.JMenuItem ; 46 import javax.swing.JOptionPane ; 47 import javax.swing.JPanel ; 48 import javax.swing.JSeparator ; 49 import javax.swing.KeyStroke ; 50 import javax.swing.event.ChangeEvent ; 51 import javax.swing.event.ChangeListener ; 52 import javax.swing.event.MenuEvent ; 53 import javax.swing.event.MenuListener ; 54 55 import taskblocks.graph.GraphActionListener; 56 import taskblocks.graph.TaskGraphComponent; 57 import taskblocks.io.BugzillaExportDialog; 58 import taskblocks.io.ProjectSaveLoad; 59 import taskblocks.io.WrongDataException; 60 import taskblocks.modelimpl.TaskImpl; 61 import taskblocks.modelimpl.TaskModelImpl; 62 import taskblocks.modelimpl.TaskPainterImpl; 63 64 public class ProjectFrame extends JFrame implements WindowListener , GraphActionListener { 65 66 static int _numWindows; 67 static List <JMenuItem > _windowMenuItems = new ArrayList <JMenuItem >(); 68 69 TaskModelImpl _taskModel; 70 TaskGraphComponent _graph; 71 72 File _file; 73 boolean _newCleanProject; 74 JCheckBoxMenuItem _myWindowMenuItem; 75 76 Action _shrinkAction = new MyAction("Shrink", TaskBlocks.getImage("shrink.png"), "Shrink tasks as near as possible") { 77 public void actionPerformed(ActionEvent e) { 78 _graph.getGraphRepresentation().shrinkTasks(); 79 _graph.repaint(); 80 } 81 }; 82 83 Action _scaleDownAction = new MyAction("Zoom Out", TaskBlocks.getImage("zoomOut.png")) { 84 public void actionPerformed(ActionEvent arg0) { 85 _graph.scaleDown(); 86 } 87 }; 88 89 Action _scaleUpAction = new MyAction("Zoom In", TaskBlocks.getImage("zoomIn.png")) { 90 public void actionPerformed(ActionEvent arg0) { 91 _graph.scaleUp(); 92 } 93 }; 94 95 Action _closeFileAction = new MyAction("Close") { 96 public void actionPerformed(ActionEvent arg0) { 97 tryClose(); 98 } 99 }; 100 101 Action _loadFileAction = new MyAction("Open...", TaskBlocks.getImage("folder.gif"), "Lets you open an existing project") { 102 public void actionPerformed(ActionEvent e) { 103 104 File f = null; 105 if(TaskBlocks.RUNNING_ON_MAC || TaskBlocks.RUNNING_ON_WINDOWS) { 106 FileDialog fd = new FileDialog (ProjectFrame.this, "blabla", FileDialog.LOAD); 108 fd.setVisible(true); 109 if(fd.getFile() != null) { 110 f = new File (fd.getDirectory(), fd.getFile()); 111 } 112 } else { 113 JFileChooser fc = new JFileChooser (); 114 fc.setFileSelectionMode(JFileChooser.FILES_ONLY); 115 fc.showOpenDialog(ProjectFrame.this); 116 f = fc.getSelectedFile(); 117 } 118 119 if(f != null) { 120 openFile(f); 121 } 122 } 123 }; 124 125 Action _newFileAction = new MyAction("New Project") { 126 public void actionPerformed(ActionEvent e) { 127 new ProjectFrame(); 128 } 129 }; 130 131 Action _saveAction = new MyAction("Save", TaskBlocks.getImage("save.png")) { 132 public void actionPerformed(ActionEvent e) { 133 save(); 134 } 135 }; 136 137 Action _saveAsAction = new MyAction("Save As...") { 138 public void actionPerformed(ActionEvent e) { 139 File oldFile = _file; 140 _file = null; 141 if(!save()) { 142 _file = oldFile; 143 } 144 } 145 }; 146 147 Action _leftAction = new MyAction("Left", TaskBlocks.getImage("left.gif"), "Scrolls left") { 148 public void actionPerformed(ActionEvent e) { 149 _graph.moveLeft(); 150 } 151 }; 152 153 Action _focusTodayAction = new MyAction("Focus on today", TaskBlocks.getImage("down.gif"), "Scrolls to current day") { 154 public void actionPerformed(ActionEvent e) { 155 _graph.focusOnToday(); 156 } 157 }; 158 159 Action _rightAction = new MyAction("Right", TaskBlocks.getImage("right.gif"), "Scrolls right") { 160 public void actionPerformed(ActionEvent e) { 161 _graph.moveRight(); 162 } 163 }; 164 165 ChangeListener _graphChangeListener = new ChangeListener (){ 166 public void stateChanged(ChangeEvent e) { 167 _newCleanProject = false; 168 updateActionsEnableState(); 169 } 170 }; 171 172 Action _minimizeAction = new MyAction("Minimize"){ 173 public void actionPerformed(ActionEvent e) { 174 ProjectFrame.this.setExtendedState(JFrame.ICONIFIED); 175 } 176 }; 177 178 Action _newTaskAction = new MyAction("New Task...", TaskBlocks.getImage("newtask.png"), "Opens the New Task Wizard"){ 179 public void actionPerformed(ActionEvent e) { 180 TaskConfigDialog.openDialog(ProjectFrame.this, null, _taskModel, _graph, true); 181 } 182 }; 183 184 Action _newManAction = new MyAction("New Worker...", TaskBlocks.getImage("newman.png"), "Opens the New Worker Wizard"){ 185 public void actionPerformed(ActionEvent e) { 186 ManConfigDialog.openDialog(ProjectFrame.this, null, _taskModel, _graph, true); 187 } 188 }; 189 Action _aboutAction = new MyAction("About..."){ 190 public void actionPerformed(ActionEvent e) { 191 AboutDialog.showAbout(ProjectFrame.this); 192 } 193 }; 194 195 Action _bugzillaSubmit = new MyAction("Export to Bugzilla...", TaskBlocks.getImage("bugzilla.png"), "Opens the Bugzilla Export dialog"){ 196 public void actionPerformed(ActionEvent e) { 197 BugzillaExportDialog.openDialog(ProjectFrame.this, _taskModel._tasks); 198 199 }}; 200 201 Action _deleteSel = new MyAction("Delete Selection", TaskBlocks.getImage("delete.gif"), "Deletes selected objects") { 202 public void actionPerformed(ActionEvent e) { 203 _graph.deleteSelection(); 204 } 205 }; 206 207 210 public ProjectFrame() { 211 this(TaskModelImpl.createEmptyModel()); 212 setTitle("New project"); 213 _newCleanProject = true; 214 updateActionsEnableState(); 215 } 216 217 public ProjectFrame(File f) throws WrongDataException { 218 this(new ProjectSaveLoad().loadProject(f)); 219 setFile(f); 220 updateActionsEnableState(); 221 } 222 223 private ProjectFrame(TaskModelImpl model) { 224 this.setIconImage(TaskBlocks.getImage("frameicon32.png").getImage()); 227 _taskModel = model; 228 buildGui(); 229 pack(); 230 setSize(800,400); 231 fillMenu(); 232 _graph.setGraphChangeListener(_graphChangeListener); 233 this.addWindowListener(this); 234 setLocationRelativeTo(null); 235 setVisible(true); 236 _numWindows++; 237 } 238 239 245 public void openFile(File f) { 246 try { 247 _graph.getGraphRepresentation().updateModel(); 249 if(_taskModel._tasks.length == 0) { 250 _taskModel = new ProjectSaveLoad().loadProject(f); 251 _graph.setModel(_taskModel); 252 setFile(f); 253 updateActionsEnableState(); 254 } else { 255 new ProjectFrame(f); 256 } 257 258 } catch (WrongDataException e) { 259 JOptionPane.showMessageDialog(null, "<html><b>Couldn't Open File</b><br><br><font size=\"-2\">" + e.getMessage() + "<br><br>"); 260 } 261 } 262 263 public void setTitle(String title) { 264 super.setTitle(title + " - Task Blocks"); 265 _myWindowMenuItem.setText(title); 266 } 267 268 public void windowActivated(WindowEvent arg0) { 269 } 270 271 public void windowClosed(WindowEvent arg0) { 272 _numWindows--; 273 _windowMenuItems.remove(_myWindowMenuItem); 274 if(_numWindows <= 0) { 275 System.exit(0); 276 } 277 } 278 279 public void windowClosing(WindowEvent arg0) { 280 tryClose(); 281 } 282 283 public void windowDeactivated(WindowEvent arg0) {} 284 285 public void windowDeiconified(WindowEvent arg0) {} 286 287 public void windowIconified(WindowEvent arg0) {} 288 289 public void windowOpened(WindowEvent arg0) {} 290 291 private void buildGui() { 292 293 JPanel mainP = new JPanel (new BorderLayout ()); 295 MyToolBar toolB = new MyToolBar(); 296 _graph = new TaskGraphComponent(_taskModel, new TaskPainterImpl()); 297 298 toolB.add(_loadFileAction); 300 toolB.add(_saveAction); 301 toolB.add(Box.createHorizontalStrut(4)); 302 toolB.add(new FixedSeparator(FixedSeparator.VERTICAL)); 303 toolB.add(Box.createHorizontalStrut(4)); 304 toolB.add(_newTaskAction); 305 toolB.add(_newManAction); 306 toolB.add(_shrinkAction); 307 toolB.add(Box.createHorizontalStrut(4)); 308 toolB.add(new FixedSeparator(FixedSeparator.VERTICAL)); 309 toolB.add(Box.createHorizontalStrut(4)); 310 toolB.add(_scaleUpAction); 311 toolB.add(_scaleDownAction); 312 toolB.add(Box.createHorizontalStrut(8)); 313 toolB.add(_leftAction); 314 toolB.add(_rightAction); 315 toolB.add(_focusTodayAction); 316 toolB.add(Box.createHorizontalStrut(4)); 317 toolB.add(new FixedSeparator(FixedSeparator.VERTICAL)); 318 toolB.add(Box.createHorizontalStrut(4)); 319 toolB.add(_deleteSel); 320 this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 322 mainP.add(toolB, BorderLayout.NORTH); 323 mainP.add(_graph, BorderLayout.CENTER); 324 getContentPane().setLayout(new BorderLayout ()); 325 getContentPane().add(mainP); 326 toolB.setFloatable(false); 328 329 _graph.setGraphActionListener(this); 330 } 331 332 private void fillMenu() { 333 JMenuBar menu = getJMenuBar(); 334 if(menu == null) { 335 menu = new JMenuBar (); 336 this.setJMenuBar(menu); 337 } 338 JMenu menuFile = new JMenu ("File"); 339 menuFile.add(_newFileAction).setAccelerator(getAcceleratorStroke('N')); 340 menuFile.add(_loadFileAction).setAccelerator(getAcceleratorStroke('O')); 341 menuFile.add(new JSeparator ()); 342 menuFile.add(_saveAction).setAccelerator(getAcceleratorStroke('S')); 343 menuFile.add(_saveAsAction); 344 menuFile.add(new JSeparator ()); 345 menuFile.add(_closeFileAction).setAccelerator(getAcceleratorStroke('W')); 346 menu.add(menuFile); 347 348 JMenu menuProject = new JMenu ("Project"); 349 menuProject.add(_newTaskAction).setAccelerator(getAcceleratorStroke('T')); 350 menuProject.add(_newManAction).setAccelerator(getAcceleratorStroke('U')); 351 menuProject.add(new JSeparator ()); 352 JMenuItem mi = menuProject.add(_deleteSel); 353 if(TaskBlocks.RUNNING_ON_MAC) { 354 mi.setAccelerator(getAcceleratorStroke(KeyEvent.VK_BACK_SPACE)); 355 } else { 356 mi.setAccelerator(getAcceleratorStroke(KeyEvent.VK_DELETE)); 357 } 358 menuProject.add(new JSeparator ()); 359 menuProject.add(_shrinkAction).setAccelerator(getAcceleratorStroke('R')); 360 menuProject.add(_bugzillaSubmit); 361 menu.add(menuProject); 362 363 364 final JMenu menuWindow = new JMenu ("Window"); 365 _myWindowMenuItem = new JCheckBoxMenuItem ("???"); 366 _myWindowMenuItem.setFont(_myWindowMenuItem.getFont().deriveFont(Font.PLAIN)); 367 _myWindowMenuItem.addActionListener(new ActionListener (){ 368 public void actionPerformed(ActionEvent e) { 369 ProjectFrame.this.toFront(); 370 }}); 371 _windowMenuItems.add(_myWindowMenuItem); 372 menuWindow.addMenuListener(new MenuListener (){ 373 public void menuCanceled(MenuEvent e) { 374 } 375 376 public void menuDeselected(MenuEvent e) { 377 } 378 379 public void menuSelected(MenuEvent e) { 380 menuWindow.removeAll(); 381 JMenuItem minItem = menuWindow.add(new JMenuItem (_minimizeAction)); 382 minItem.setAccelerator(getAcceleratorStroke('M')); 383 minItem.setFont(minItem.getFont().deriveFont(Font.PLAIN)); 384 menuWindow.add(new JSeparator ()); 385 for(JMenuItem winItem: _windowMenuItems) { 386 menuWindow.add(winItem); 387 winItem.setSelected(winItem == _myWindowMenuItem); 388 } 389 }}); 390 menu.add(menuWindow); 391 392 if(!TaskBlocks.RUNNING_ON_MAC) { 393 JMenu menuHelp = new JMenu ("Help"); 394 menuHelp.add(_aboutAction); 395 menu.add(menuHelp); 396 } 397 398 for(int i = 0; i < menu.getMenuCount(); i++) { 400 JMenu subMenu = menu.getMenu(i); 401 subMenu.setFont(subMenu.getFont().deriveFont(Font.PLAIN)); 402 for(Component c: subMenu.getMenuComponents()) { 403 if(c instanceof JMenuItem ) { 404 if(TaskBlocks.RUNNING_ON_MAC) { 406 ((JMenuItem )c).setIcon(null); 408 } 409 ((JMenuItem )c).setFont(c.getFont().deriveFont(Font.PLAIN)); 410 } 411 } 412 } 413 } 414 415 private KeyStroke getAcceleratorStroke(char key) { 416 return KeyStroke.getKeyStroke(key, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); 417 } 418 private KeyStroke getAcceleratorStroke(int keyCode) { 419 return KeyStroke.getKeyStroke(keyCode, 0); 420 } 421 422 private void setFile(File f) { 423 _file = f; 424 setTitle(_file.getName()); 425 } 426 427 private void tryClose() { 428 if(_graph.getGraphRepresentation().isSaveDirty()) { 429 String SAVE = "Save"; 431 String DONT_SAVE = "Don't Save"; 432 String CANCEL = "Cancel"; 433 Object [] options; 434 435 if(TaskBlocks.RUNNING_ON_MAC) { 437 options = new Object [] {SAVE, CANCEL, DONT_SAVE}; 438 } else { 439 options = new Object [] {DONT_SAVE, SAVE, CANCEL}; 440 } 441 JLabel l = new JLabel ("<html><b>Do you want to save changes to this document<br>before closing?</b><br><br><font size=\"-2\">If you don't save, your changes will be lost.<br></font><br>"); 442 l.setFont(l.getFont().deriveFont(Font.PLAIN)); 443 JOptionPane op = new JOptionPane (l, JOptionPane.QUESTION_MESSAGE, 0, null, options); 444 op.createDialog(this, _file == null ? "Unsaved project" : _file.getName()).setVisible(true); 445 op.setInitialSelectionValue(CANCEL); 446 Object choice = op.getValue(); 447 if(choice == null) { 448 return; } 450 if(choice.equals(SAVE)) { 451 if(!save()) { 453 return; 455 } else { 456 this.dispose(); 457 } 458 } else if(choice.equals(DONT_SAVE)) { 459 this.dispose(); 460 } 461 } else { 462 this.dispose(); 463 } 464 } 465 466 private void updateActionsEnableState() { 467 boolean unsaved = _newCleanProject || _graph.getGraphRepresentation().isSaveDirty(); 468 _saveAction.setEnabled(unsaved); 469 470 getRootPane().putClientProperty("windowModified", unsaved?Boolean.TRUE : Boolean.FALSE); 472 _newTaskAction.setEnabled(_graph.getGraphRepresentation().getManCount() > 0); 473 } 474 475 private boolean save() { 476 _graph.getGraphRepresentation().updateModel(); 477 File f = _file; 478 if(f == null) { 479 480 if(TaskBlocks.RUNNING_ON_MAC || TaskBlocks.RUNNING_ON_WINDOWS) { 482 FileDialog fd = new FileDialog (ProjectFrame.this, "blabla", FileDialog.SAVE); 484 fd.setVisible(true); 485 if(fd.getFile() != null) { 486 f = new File (fd.getDirectory(), fd.getFile()); 487 } 488 } else { 489 JFileChooser fc = new JFileChooser (); 490 fc.setFileSelectionMode(JFileChooser.FILES_ONLY); 491 fc.showSaveDialog(ProjectFrame.this); 492 f = fc.getSelectedFile(); 493 } 494 } 495 if(f != null) { 496 try { 497 new ProjectSaveLoad().saveProject(f, _taskModel); 498 setFile(f); 499 _graph.getGraphRepresentation().clearSaveDirtyFlag(); 500 return true; 501 } catch (Exception e1) { 502 JOptionPane.showMessageDialog(null, "<html><b>Couldn't Save</b><br><br><font size=\"-2\">" + e1.getMessage() + "<br><br>"); 503 e1.printStackTrace(); 504 } 505 } 506 return false; 507 } 508 509 private void configureTask(TaskImpl t) { 510 _graph.getGraphRepresentation().updateModel(); if(TaskConfigDialog.openDialog(this, t, _taskModel, _graph, false)) { 512 _graph.setModel(_taskModel); _graph.getGraphRepresentation().setDirty(); _graph.repaint(); 515 } 516 } 517 518 public void mouseClicked(Object task, MouseEvent e) { 519 if(task != null && e.getClickCount() >= 2) { 520 configureTask((TaskImpl)task); 521 } 522 } 523 } 524 | Popular Tags |