/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © Copyright IBM Corp. 2009, 2014 * © Copyright ILOG 1996, 2009 * All Rights Reserved. * * Note to U.S. Government Users Restricted Rights: * The Software and Documentation were developed at private expense and * are "Commercial Items" as that term is defined at 48 CFR 2.101, * consisting of "Commercial Computer Software" and * "Commercial Computer Software Documentation", as such terms are * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4, * as applicable. */ package ganttviewer; import ganttviewer.StyleManager.Style; import ganttviewer.actions.GanttViewerDeleteConstraintAction; import ganttviewer.actions.GanttViewerDeleteRowAction; import ganttviewer.actions.GanttViewerEditPropertiesAction; import ganttviewer.actions.GanttViewerInsertConstraintAction; import ganttviewer.actions.GanttViewerInsertRowAction; import ganttviewer.actions.GanttViewerMagnifyAction; import ganttviewer.actions.GanttViewerPanAction; import ganttviewer.actions.GanttViewerRowDownAction; import ganttviewer.actions.GanttViewerRowExpandCollapseAction; import ganttviewer.actions.GanttViewerRowIndentAction; import ganttviewer.actions.GanttViewerRowOutdentAction; import ganttviewer.actions.GanttViewerRowUpAction; import ganttviewer.actions.GanttViewerSelectAction; import ganttviewer.actions.GanttViewerZoomInAction; import ganttviewer.actions.GanttViewerZoomOutAction; import ganttviewer.actions.GanttViewerZoomToFitAction; import ganttviewer.exceptions.ApplyStyleException; import ganttviewer.model.GanttViewerConstraint; import ganttviewer.util.CustomExample; import ganttviewer.util.GanttViewerLogger; import ganttviewer.util.GanttViewerProperties; import ganttviewer.util.ImageUtilities; import ganttviewer.util.WindowSizeUtils; import ganttviewer.util.help.HelpPanel; import ganttviewer.viewer.View; import ganttviewer.viewer.Viewer; import ganttviewer.viewer.ViewerAbstractAction; import ganttviewer.viewer.event.CurrentViewChangedEvent; import ganttviewer.viewer.event.CurrentViewListener; import ganttviewer.viewer.exceptions.AttachModelException; import ganttviewer.viewer.exceptions.ViewException; import ganttviewer.views.GanttTableView; import ganttviewer.views.GanttView; import ganttviewer.views.MonthlyCalendarView; import ganttviewer.views.PERTView; import ganttviewer.views.ResourceUsageView; import ganttviewer.views.ScheduleTableView; import ilog.views.gantt.IlvActivity; import ilog.views.gantt.IlvActivityFactory; import ilog.views.gantt.IlvConstraint; import ilog.views.gantt.IlvConstraintFactory; import ilog.views.gantt.IlvConstraintType; import ilog.views.gantt.IlvGanttModel; import ilog.views.gantt.IlvTimeInterval; import ilog.views.gantt.IlvTimeScrollController; import ilog.views.gantt.action.IlvAction; import ilog.views.gantt.model.IlvDefaultGanttModel; import ilog.views.gantt.model.general.IlvGeneralActivity; import ilog.views.gantt.model.general.IlvGeneralConstraint; import ilog.views.gantt.xml.IlvGanttDocumentReader; import ilog.views.gantt.xml.IlvGeneralActivityReader; import ilog.views.gantt.xml.IlvGeneralConstraintReader; import ilog.views.util.IlvProductUtil; import ilog.views.util.swing.IlvSwingUtil; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.net.MalformedURLException; import java.text.MessageFormat; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.swing.AbstractButton; import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JRadioButtonMenuItem; import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.filechooser.FileFilter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.xml.sax.InputSource; import shared.AbstractExample; import shared.GanttCommand; import shared.swing.ExampleFrame; /** * <code>GanttViewer</code> is the main class of the sample. */ SuppressWarnings("serial") public class GanttViewer extends CustomExample { private static int ACTIVITY_ID_INCR = 0; /** * Available actions property. */ public static final String ACTIONS_SUFFIX = ".Actions"; /** * Calendar view ID. */ public static final String CALENDAR_VIEW = "View.Calendar"; /** * Gantt Chart view ID. */ public static final String GANTT_CHART_VIEW = "View.GanttChart"; /** * Resource Sheet view ID. */ public static final String RESOURCE_SHEET_VIEW = "View.ResourceSheet"; /** * Resource Usage view ID. */ public static final String RESOURCE_USAGE_VIEW = "View.ResourceUsage"; /** * Task Sheet view ID. */ public static final String TASK_SHEET_VIEW = "View.TaskSheet"; /** * PERT View view ID. */ public static final String PERT_VIEW = "View.PERTDiagram"; /** * The frame icon. */ private static final String ICON_IMAGE = "ilog32.gif"; /** * View icon property. */ private static final String CHANGE_VIEW_ICON_SUFFIX = ".Icon"; /** * View short description property. */ private static final String CHANGE_VIEW_SHORT_DESCRIPTION = "Action.ChangeView.Tooltip"; /** * View long description property. */ private static final String CHANGE_VIEW_LONG_DESCRIPTION = "Action.ChangeView.Description"; /** * The viewer. */ private Viewer viewer = null; /** * Activity factory. */ private final IlvActivityFactory activityFactory = new ActivityFactory(); /** * Constraint factory. */ private final IlvConstraintFactory constraintFactory = new ConstraintFactory(); /** * Handle lag time management. */ private LagTimeHandler lagTimeHandler; /** * List of available views. */ private JComponent viewBar = null; /** * Button updater. */ private final ButtonUpdater buttonUpdater = new ButtonUpdater(); /** * MenuItem updater. */ private final MenuItemUpdater menuUpdater = new MenuItemUpdater(); /** * Style manager. */ private final StyleManager styleManager = new StyleManager(); /** * Changes view actions. */ private final Map<String, ChangeViewAction> changeViewActions = new HashMap<String, ChangeViewAction>(); /** * Show/Hide Help Panel action. */ private final ShowHideHelpAction showHideHelpAction = new ShowHideHelpAction(); /** * The actions that set styles. */ private Set<SetStyleAction> setStyleActions = new HashSet<SetStyleAction>(); /** * Help panel. */ private HelpPanel helpPanel; /** * Show/Hide help button. */ private JToggleButton helpButton; /** * Data set change action. */ private final ActionListener dataSetChangesHandler = new ActionListener() { Override public void actionPerformed(ActionEvent event) { AbstractButton button = (AbstractButton) event.getSource(); String dataSet = button.getActionCommand(); try { // set Gantt model setGanttModel(createGanttModel(dataSet, true)); } catch (AttachModelException e) { GanttViewerLogger.error(e); } } }; /** * Synchronizes visible time intervals. */ private final IlvTimeScrollController timeScrollController = new IlvTimeScrollController(); /** * Action Description Suffix. */ public static final String DESCRIPTION_SUFFIX = ".Description"; /** * Action Tooltip Suffix. */ public static final String TOOLTIP_SUFFIX = ".Tooltip"; /** * Action Icon Suffix. */ public static final String ICON_SUFFIX = ".Icon"; /** * Builds a <code>GanttViewer</code>. */ public GanttViewer() { createHelpPanel(); } /** * Creates the help panel. */ protected void createHelpPanel() { helpPanel = new HelpPanel(GanttViewerProperties.getString("Help.Title"), GanttViewer.class.getResource(GanttViewerProperties .getString("Help.HtmlFileName")), GanttViewerProperties .getString("Help.BackToHomePage"), ImageUtilities.getIcon( GanttViewer.class, "help/images/home.gif"), GanttViewerProperties .getString("Help.BackToHomePage.Description")); helpPanel.addWindowListener(new WindowAdapter() { Override public void windowClosing(WindowEvent e) { helpButton.setSelected(false); } Override public void windowIconified(WindowEvent e) { helpButton.setSelected(false); } Override public void windowDeiconified(WindowEvent e) { helpButton.setSelected(true); } }); helpPanel.setIconImage(ImageUtilities.getImage( shared.swing.ExampleFrame.class, GanttViewer.ICON_IMAGE)); } /** * Returns the help panel. * * @return The help panel. */ Override public HelpPanel getHelpPanel() { return helpPanel; } /** * Initializes the user interface of the sample in the specified container. * This will be the <code>JFrame</code> of the application. */ Override public void init(Container container) { // This sample uses JViews Gantt features. When deploying an // application that includes this code, you need to be in possession // of a Perforce JViews Gantt Deployment license. IlvProductUtil.DeploymentLicenseRequired( IlvProductUtil.JViews_Gantt_Deployment); // This sample uses JViews Diagrammer features, for the PERT diagram. // When deploying an application that includes this code, you need to // be in possession of a Perforce JViews Diagrammer Deployment license. IlvProductUtil.DeploymentLicenseRequired( IlvProductUtil.JViews_Diagrammer_Deployment); super.init(container); // creates a lag time manager. lagTimeHandler = new LagTimeHandler(); // create the viewer. viewer = this.createViewer(); viewerCreated(); // set Gantt model IlvGanttModel ganttModel = null; try { ganttModel = createGanttModel(GanttViewerProperties .getString("DataSets.Default"), true); setGanttModel(ganttModel); } catch (AttachModelException e) { GanttViewerLogger.error(e); } // initialize the GUI. initializeGUI(container); // sets the current view. getViewer().setCurrentView(getViewer().getView(GANTT_CHART_VIEW)); // set preferred size container.setPreferredSize(WindowSizeUtils.getMainWindowSize()); // styling try { this.styleManager.applyStyle(getViewer()); } catch (ApplyStyleException e) { GanttViewerLogger.error(e); } // display the help panel if (showHelp) { SwingUtilities.invokeLater(new Runnable() { Override public void run() { helpButton.getAction().actionPerformed( new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "")); } }); } } /** * Sets the Gantt data model to the viewer. * * @param ganttModel * The Gantt model. */ private void setGanttModel(IlvGanttModel ganttModel) throws AttachModelException { // computation on styles before // count the number of activities and resources int count = 0; Iterator<?> it = ganttModel.activityPreorderIterator(ganttModel .getRootActivity()); for (; it.hasNext(); it.next()) { count++; } it = ganttModel.resourcePreorderIterator(ganttModel.getRootResource()); for (; it.hasNext(); it.next()) { count++; } if (count >= 1000) { // if there are between 1000 and 5000 elements, prefer simple and medium complexity styles // if there are more than 5000 elements, prefer simple styles Style aStyle = null; for (SetStyleAction action : setStyleActions) { if ((count >= 5000 && action.getStyle().getComplexity() == StyleManager.COMPLEXITY_SIMPLE) || (count < 5000 && action.getStyle().getComplexity() != StyleManager.COMPLEXITY_HIGH)) { if (aStyle == null) { aStyle = action.getStyle(); } } } if (aStyle != null && (count >= 5000 && styleManager.getCurrentStyle().getComplexity() != StyleManager.COMPLEXITY_SIMPLE) || (count < 5000 && styleManager.getCurrentStyle().getComplexity() == StyleManager.COMPLEXITY_HIGH)) { try { this.styleManager.applyStyle(getViewer(), aStyle); } catch (ApplyStyleException e) { GanttViewerLogger.error(e); } } } else { for (SetStyleAction action : setStyleActions) { action.setEnabled(true); } } viewer.setModel(ganttModel); // handles lag time management lagTimeHandler.setGanttModel(ganttModel); // initial selection. viewer.setSelected(ganttModel.getRootActivity(), true); viewer.setSelected(ganttModel.getRootResource(), true); // initial zoom-to-fit if there isn't default transformer associated // with the current view if (viewer.getCurrentView().getDefaultTransformer() == null) { SwingUtilities.invokeLater(new Runnable() { Override public void run() { viewer.getAction(GanttViewerZoomToFitAction.ID).actionPerformed( new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "")); } }); } } /** * Initializes the GUI. * * @param container * The graphical container. */ protected void initializeGUI(Container container) { container.setLayout(new BorderLayout()); // create and install the menu bar. JMenuBar menuBar = createMenuBar(); setJMenuBar(menuBar); // create the status bar. JLabel status = createStatusBar(); // create the toolbar. JToolBar toolbar = createToolBar(); container.add(toolbar, BorderLayout.NORTH); container.add(viewer, BorderLayout.CENTER); container.add(status, BorderLayout.SOUTH); // size setSize(WindowSizeUtils.getMainWindowSize()); // register GUI components updaters getViewer().addCurrentViewListener(menuUpdater); getViewer().addCurrentViewListener(buttonUpdater); // create the viewbar viewBar = createViewBar(); container.add(viewBar, BorderLayout.LINE_START); } /** * Once the viewer is created, actions are created to change the current * view. */ protected void viewerCreated() { for (View view : getViewer().views()) { Object[] args = { view.getName() }; Icon icon = ImageUtilities.getIcon(GanttViewer.class, GanttViewerProperties.getString(view.getID().concat( GanttViewer.CHANGE_VIEW_ICON_SUFFIX))); String shortDescription = MessageFormat.format(GanttViewerProperties .getString(GanttViewer.CHANGE_VIEW_SHORT_DESCRIPTION), args); String longDescription = MessageFormat.format(GanttViewerProperties .getString(GanttViewer.CHANGE_VIEW_LONG_DESCRIPTION), args); changeViewActions.put(view.getID(), new ChangeViewAction(view, icon, shortDescription, longDescription)); } } /** * Creates the menu bar. */ public JMenuBar createMenuBar() { JMenuBar menubar = new JMenuBar(); menubar.add(createFileMenu(), 0); menubar.add(createEditMenu(), 1); menubar.add(createStyleMenu(), 2); menubar.add(createViewMenu(), 3); return menubar; } /** * Returns the Gantt Viewer title. * * @return The title. */ Override public String getTitle() { return GanttViewerProperties.getString("Demo.Title"); } /** * Registers the actions. * * @param viewer * The viewer. */ protected void registerActions(Viewer viewer) { viewer.registerAction(new GanttViewerZoomInAction(viewer)); viewer.registerAction(new GanttViewerZoomOutAction(viewer)); viewer.registerAction(new GanttViewerZoomToFitAction(viewer)); viewer.registerAction(new GanttViewerRowUpAction(viewer)); viewer.registerAction(new GanttViewerRowDownAction(viewer)); viewer.registerAction(new GanttViewerRowIndentAction(viewer)); viewer.registerAction(new GanttViewerRowOutdentAction(viewer)); viewer.registerAction(new GanttViewerInsertRowAction(viewer)); viewer.registerAction(new GanttViewerInsertConstraintAction(viewer)); viewer.registerAction(new GanttViewerEditPropertiesAction(viewer)); viewer.registerAction(new GanttViewerDeleteRowAction(viewer)); viewer.registerAction(new GanttViewerDeleteConstraintAction(viewer)); viewer.registerAction(new GanttViewerRowExpandCollapseAction(viewer)); viewer.registerAction(new GanttViewerSelectAction(viewer)); viewer.registerAction(new GanttViewerPanAction(viewer)); viewer.registerAction(new GanttViewerMagnifyAction(viewer)); } /** * Registers view actions. * * @param view * The view. * @param actionsStr * A string indicating the actions to associate with. */ protected void registerActions(View view, String actionsStr) { // list available actions from the given string and create a controller. if (!"".equals(actionsStr)) { String[] actionsArray = actionsStr .split(GanttViewerProperties.PROPERTIES_SEPARATOR); for (String element : actionsArray) { view.registerAction(view.getViewer().getAction(element.trim())); } } } /** * Creates the viewer and the views. * * @return The new <code>GanttViewerChart</code>. */ protected Viewer createViewer() { String[] viewActions = new String[] { GanttViewer.GANTT_CHART_VIEW.concat(GanttViewer.ACTIONS_SUFFIX), GanttViewer.CALENDAR_VIEW.concat(GanttViewer.ACTIONS_SUFFIX), GanttViewer.RESOURCE_USAGE_VIEW.concat(GanttViewer.ACTIONS_SUFFIX), GanttViewer.TASK_SHEET_VIEW.concat(GanttViewer.ACTIONS_SUFFIX), GanttViewer.RESOURCE_SHEET_VIEW.concat(GanttViewer.ACTIONS_SUFFIX), GanttViewer.PERT_VIEW.concat(GanttViewer.ACTIONS_SUFFIX) }; Viewer viewer = new Viewer(); // register actions registerActions(viewer); // create views try { new GanttView(viewer, GanttViewer.GANTT_CHART_VIEW, GanttViewerProperties .getString(GanttViewer.GANTT_CHART_VIEW), timeScrollController, activityFactory, constraintFactory); new MonthlyCalendarView(viewer, GanttViewer.CALENDAR_VIEW, GanttViewerProperties.getString(GanttViewer.CALENDAR_VIEW)); new ResourceUsageView(viewer, GanttViewer.RESOURCE_USAGE_VIEW, GanttViewerProperties.getString(GanttViewer.RESOURCE_USAGE_VIEW), timeScrollController, activityFactory, constraintFactory); new GanttTableView(viewer, GanttViewer.TASK_SHEET_VIEW, GanttViewerProperties.getString(GanttViewer.TASK_SHEET_VIEW), activityFactory, constraintFactory); new ScheduleTableView(viewer, GanttViewer.RESOURCE_SHEET_VIEW, GanttViewerProperties.getString(GanttViewer.RESOURCE_SHEET_VIEW), activityFactory, constraintFactory); new PERTView(viewer, GanttViewer.PERT_VIEW, GanttViewerProperties .getString(GanttViewer.PERT_VIEW)); // associate actions int k = 0; for (View view : viewer.views()) { registerActions(view, GanttViewerProperties.getString(viewActions[k++])); } } catch (ViewException e) { GanttViewerLogger.error(e); } return viewer; } /** * Returns the viewer. * * @return The viewer. */ public Viewer getViewer() { return viewer; } /** * Creates the Gantt data model. * * @param dataSet * The dataSet to load. * @param resolve * Resolves the data set location. * @return The Gantt data model. */ protected IlvGanttModel createGanttModel(String dataSet, boolean resolve) { // model creation InputSource source; IlvGanttDocumentReader docReader; try { String path = dataSet; if (resolve) { path = getClass().getResource(dataSet).toString(); } // create an InputSource source = new InputSource(path); docReader = new IlvGanttDocumentReader(); docReader.setActivityReader(new IlvGeneralActivityReader() { Override protected IlvActivity createActivity(String id, String name, Date start, Date end) { IlvActivity activity = activityFactory .createActivity(new IlvTimeInterval(start, end)); activity.setID(id); activity.setName(name); return activity; } }); docReader.setConstraintReader(new IlvGeneralConstraintReader() { Override protected IlvConstraint createConstraint(IlvActivity from, IlvActivity to, IlvConstraintType type) { return constraintFactory.createConstraint(from, to, type); } }); } catch (Exception e) { IlvSwingUtil.showErrorDialog(this, e); return null; } // create the document Document document; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(source); } catch (Exception ex) { IlvSwingUtil.showErrorDialog(this, ex); return null; } // create a default Gantt model IlvGanttModel model = new IlvDefaultGanttModel(); // read the document into the Gantt model. try { docReader.readGanttModel(document, model); } catch (Exception ex) { IlvSwingUtil.showErrorDialog(this, ex); return null; } return model; } /** * Creates the File menu. * * @return The File menu. */ public JMenu createFileMenu() { JMenu menu = new JMenu(GanttViewerProperties.getString("Menu.File")); menu.setMnemonic(KeyEvent.VK_F); setStatusText(menu, GanttViewerProperties .getString("Menu.File.Description")); // classic open file dialog in standalone mode addAction(menu, new OpenFileAction()); if (isExitAllowed()) { menu.addSeparator(); addAction(menu, new GanttCommand.ExitAction()); } return menu; } /** * Creates the menu for selecting the data set. * * @param dataSetMenu * The parent menu item. */ protected void createDataSetSelectorMenu(JMenu dataSetMenu) { String dataSetsProperty = GanttViewerProperties.getString("DataSets") .trim(); String defaultDataSet = GanttViewerProperties.getString("DataSets.Default") .trim(); ButtonGroup buttonGroup = new ButtonGroup(); if (!"".equals(dataSetsProperty)) { String[] dataSetsArray = dataSetsProperty .split(GanttViewerProperties.PROPERTIES_SEPARATOR); for (String element : dataSetsArray) { String dataSet = element.trim(); JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(dataSet, dataSet.equals(defaultDataSet)); menuItem.setActionCommand(dataSet); menuItem.addActionListener(this.dataSetChangesHandler); dataSetMenu.add(menuItem); buttonGroup.add(menuItem); } } } /** * Adds the specified action to a toolbar as a button and returns the * button. <code>AbstractButton</code>. * * @param toolbar * The toolbar where the button is to be added. * @param action * The action to launch. * @param toggle * Add a toggle button? */ protected AbstractButton addAction(JToolBar toolbar, final ViewerAbstractAction action, boolean toggle) { final AbstractButton button; if (!toggle) { button = new JButton(action); } else { button = new JToggleButton(action); // synchronize selection state action.addPropertyChangeListener(new PropertyChangeListener() { Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(ViewerAbstractAction.SELECTED_KEY)) { button.setSelected((Boolean) evt.getNewValue()); } } }); button.addItemListener(new ItemListener() { Override public void itemStateChanged(ItemEvent e) { boolean value = e.getStateChange() == ItemEvent.SELECTED; action.putValue(ViewerAbstractAction.SELECTED_KEY, value); } }); } if (button.getIcon() != null) { button.setText(null); } // populate the action map ActionMap actionMap = button.getActionMap(); if (actionMap != null) { actionMap.put(action, action); } // register accelerator if there is one KeyStroke accelerator = action.getAccelerator(); if (accelerator != null) { InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); inputMap.put(accelerator, action); } String shortDescription = action.getShortDescription(); if (shortDescription != null) { if (accelerator != null) { shortDescription += ToolTipUI.TIP_DELIMITER + action.getAcceleratorText(); } button.setToolTipText(shortDescription); } toolbar.add(button); buttonUpdater.registerButton(button); return button; } /** * Overrides <code>addAction()</code> to listen for current view changes. */ protected JMenuItem addAction(JMenu menu, ViewerAbstractAction action) { JMenuItem menuItem = super.addAction(menu, action); menuUpdater.registerMenuItem(menuItem); return menuItem; } /** * Creates the Edit menu. * * @return The edit menu. */ public JMenu createEditMenu() { JMenu menu = new JMenu(GanttViewerProperties.getString("Menu.Edit")); menu.setMnemonic(KeyEvent.VK_E); setStatusText(menu, GanttViewerProperties .getString("Menu.Edit.Description")); Viewer viewer = getViewer(); addAction(menu, viewer.getAction(GanttViewerInsertRowAction.ID)); addAction(menu, viewer.getAction(GanttViewerInsertConstraintAction.ID)); menu.addSeparator(); addAction(menu, viewer.getAction(GanttViewerDeleteRowAction.ID)); addAction(menu, viewer.getAction(GanttViewerDeleteConstraintAction.ID)); menu.addSeparator(); addAction(menu, viewer.getAction(GanttViewerEditPropertiesAction.ID)); return menu; } /** * Creates the Style menu. * * @return The Style menu. */ public JMenu createStyleMenu() { JMenu menu = new JMenu(GanttViewerProperties.getString("Menu.Style")); menu.setMnemonic(KeyEvent.VK_S); setStatusText(menu, GanttViewerProperties .getString("Menu.Style.Description")); final Map<Style, JRadioButtonMenuItem> index = new HashMap<Style, JRadioButtonMenuItem>(); ButtonGroup styleGroup = new ButtonGroup(); for (Object element : styleManager.styles()) { StyleManager.Style style = (StyleManager.Style) element; SetStyleAction action = new SetStyleAction(style); setStyleActions.add(action); JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(action); menu.add(menuItem); styleGroup.add(menuItem); index.put(style, menuItem); } styleManager.addCurrentStyleListener(new CurrentStyleListener() { Override public void currentStyleChanged() { index.get(styleManager.getCurrentStyle()).setSelected(true); } }); return menu; } /** * Creates the View menu. * * @return The View menu. */ public JMenu createViewMenu() { JMenu menu = new JMenu(GanttViewerProperties.getString("Menu.View")); menu.setMnemonic(KeyEvent.VK_V); setStatusText(menu, GanttViewerProperties .getString("Menu.View.Description")); // group of items final ButtonGroup group = new ButtonGroup(); for (View view : getViewer().views()) { ChangeViewAction changeAction = changeViewActions.get(view.getID()); JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(changeAction); menuItem.setToolTipText(null); menuItem.setIcon(null); setStatusText(menuItem, changeAction.getLongDescription()); group.add(menuItem); menu.add(menuItem); } // listen to view changes getViewer().addCurrentViewListener(new CurrentViewListener() { Override public void currentViewChanged(CurrentViewChangedEvent event) { for (Enumeration<AbstractButton> e = group.getElements(); e .hasMoreElements();) { AbstractButton button = e.nextElement(); if (button.getAction().equals( changeViewActions.get(getViewer().getCurrentView().getID()))) { group.setSelected(button.getModel(), true); break; } } } }); return menu; } /** * Creates the list of available views. * * @return The toolbar. */ public JComponent createViewBar() { JToolBar viewBar = new JToolBar(SwingConstants.VERTICAL); viewBar.setBackground(UIManager.getColor("controlShadow")); viewBar.setFloatable(false); // group of items final ButtonGroup group = new ButtonGroup(); // create menu items Dimension max = new Dimension(0, 0); for (View view : getViewer().views()) { ChangeViewAction changeAction = changeViewActions.get(view.getID()); JToggleButton button = new JToggleButton(changeAction); button.setHorizontalTextPosition(SwingConstants.CENTER); button.setVerticalTextPosition(SwingConstants.BOTTOM); button.setToolTipText(changeAction.getShortDescription()); group.add(button); viewBar.add(button); if (button.getMaximumSize().getWidth() > max.getWidth()) { max = button.getMaximumSize(); } } // set button sizes for (Enumeration<AbstractButton> e = group.getElements(); e .hasMoreElements();) { e.nextElement().setMaximumSize(max); } // listen to view changes getViewer().addCurrentViewListener(new CurrentViewListener() { Override public void currentViewChanged(CurrentViewChangedEvent event) { for (Enumeration<AbstractButton> e = group.getElements(); e .hasMoreElements();) { AbstractButton button = e.nextElement(); if (button.getAction().equals( changeViewActions.get(getViewer().getCurrentView().getID()))) { group.setSelected(button.getModel(), true); break; } } } }); viewBar.setBorder(BorderFactory.createEtchedBorder()); return viewBar; } /** * Overrides <code>setLookAndFeel</code>. * * @param laf * The look-and-feel object. */ Override protected void setLookAndFeel(LookAndFeelInfo laf) { super.setLookAndFeel(laf); if (viewBar != null) { viewBar.setBackground(UIManager.getColor("controlShadow")); } } /** * Populates the toolbar. * * @param toolbar * The toolbar to populate. */ Override protected void populateToolBar(JToolBar toolbar) { Viewer viewer = getViewer(); addAction(toolbar, viewer.getAction(GanttViewerInsertRowAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerInsertConstraintAction.ID), false); toolbar.addSeparator(); addAction(toolbar, viewer.getAction(GanttViewerDeleteRowAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerDeleteConstraintAction.ID), false); toolbar.addSeparator(); addAction(toolbar, viewer.getAction(GanttViewerEditPropertiesAction.ID), false); toolbar.addSeparator(); addAction(toolbar, viewer.getAction(GanttViewerRowExpandCollapseAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerRowOutdentAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerRowIndentAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerRowUpAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerRowDownAction.ID), false); toolbar.addSeparator(); // add interactions addAction(toolbar, viewer.getAction(GanttViewerSelectAction.ID), true) .setSelected(true); addAction(toolbar, viewer.getAction(GanttViewerPanAction.ID), true); addAction(toolbar, viewer.getAction(GanttViewerMagnifyAction.ID), true); toolbar.addSeparator(); addAction(toolbar, viewer.getAction(GanttViewerZoomInAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerZoomOutAction.ID), false); addAction(toolbar, viewer.getAction(GanttViewerZoomToFitAction.ID), false); // help toolbar.addSeparator(); helpButton = new JToggleButton(showHideHelpAction); helpButton.setText(null); toolbar.add(helpButton); toolbar.setBorder(BorderFactory.createEtchedBorder()); } /** * View change action of the chart. */ class ChangeViewAction extends IlvAction { /** * The view. */ private View relatedView; /** * Builds a <code>ChangeViewAction</code>. */ public ChangeViewAction(View relatedView, Icon icon, String shortDescription, String longDescription) { super(relatedView.getName(), icon, null, shortDescription, longDescription); this.relatedView = relatedView; } /** * Performs the action. * * @param event * The event. */ Override public void actionPerformed(ActionEvent event) { relatedView.getViewer().setCurrentView(relatedView); } /** * Returns the related view. * * @return The view. */ public View getRelatedView() { return relatedView; } } /** * The show/hide help action. */ class ShowHideHelpAction extends IlvAction { /** * ID of the action. */ public static final String ID = "Action.ShowHideHelp"; /** * Builds a <code>ShowHideHelpAction</code>. */ public ShowHideHelpAction() { super(GanttViewerProperties.getString(ShowHideHelpAction.ID), ImageUtilities.getIcon(shared.AbstractExample.class, GanttViewerProperties.getString(ShowHideHelpAction.ID .concat(".Icon"))), null, GanttViewerProperties .getString(ShowHideHelpAction.ID.concat(".Tooltip")), GanttViewerProperties.getString(ShowHideHelpAction.ID .concat(".Description"))); } /** * Shows/Hides help panel. */ Override public void actionPerformed(ActionEvent arg0) { helpPanel.setVisible(helpButton.isSelected()); if (helpButton.isSelected()) { helpPanel.setState(Frame.NORMAL); helpPanel.toFront(); } } } /** * Represents the open file action. * * @since JViews 8.5 */ class OpenFileAction extends IlvAction { /** * The ID of the action. */ public static final String ID = "Action.OpenFile"; /** * The file chooser. */ private JFileChooser fileChooser; /** * Builds an <code>OpenFileAction</code> object. */ public OpenFileAction() { super( GanttViewerProperties.getString(OpenFileAction.ID), null, null, GanttViewerProperties.getString(OpenFileAction.ID.concat(".Tooltip")), GanttViewerProperties.getString(OpenFileAction.ID .concat(".Description"))); fileChooser = new JFileChooser("."); fileChooser.setMultiSelectionEnabled(false); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); fileChooser.setFileFilter(new FileFilter() { Override public boolean accept(File f) { return f.isDirectory() || f.getName().toLowerCase().endsWith(".sdxl"); } Override public String getDescription() { return "*.sdxl"; } }); } /** * Opens a file. */ Override public void actionPerformed(ActionEvent evt) { if (fileChooser.showOpenDialog(GanttViewer.this) == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); try { // set Gantt model setGanttModel(createGanttModel(file.toURI().toURL().toString(), false)); } catch (AttachModelException e) { GanttViewerLogger.error(e); } catch (MalformedURLException e) { GanttViewerLogger.error(e); } } } } /** * Represents the change style action. * * @since JViews 8.5 */ class SetStyleAction extends IlvAction { /** * The ID of the action. */ public static final String ID = "Action.SetStyle"; /** * The style. */ private Style style; /** * Builds a new <code>SetStyleAction</code> object. * @param style The style. */ public SetStyleAction(Style style) { super(style.getName(), null, null); this.style = style; } /** * Returns the style. * @return The current style. */ public Style getStyle() { return style; } /** * Sets the style. * @param evt Used to set the style. */ Override public void actionPerformed(ActionEvent evt) { try { styleManager.applyStyle(GanttViewer.this.getViewer(), style); } catch (ApplyStyleException e) { GanttViewerLogger.error(e); } } } /** * Custom activity factory. */ protected class ActivityFactory implements IlvActivityFactory { /** * The factory method. * * @param interval * The given time interval. */ Override public IlvActivity createActivity(IlvTimeInterval interval) { IlvGeneralActivity activity = new IlvGeneralActivity("New Activity " + (GanttViewer.ACTIVITY_ID_INCR++), "New Activity", interval); return activity; } } /** * Custom constraint factory. */ protected class ConstraintFactory implements IlvConstraintFactory { /** * The factory method. * * @param interval * The given time interval. */ Override public IlvConstraint createConstraint(IlvActivity from, IlvActivity to, IlvConstraintType type) { IlvGeneralConstraint constraint = new GanttViewerConstraint(from, to, type); constraint .setProperty(LagTimeHandler.CONSTRAINT_SATISFIED_PROPERTY, true); return constraint; } } /** * Entry Point of the Gantt Viewer. * * @param args */ public static void main(String[] args) { ExampleFrame.createAndShowGUI(GanttViewer.class, new ExampleFrame.FrameInitialLocationPolicy() { Override public void initPosition(JFrame frame, AbstractExample example) { frame.setLocation(WindowSizeUtils.getMainWindowLocation()); } }); } }