/*
* 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 dualChart;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Date;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import ilog.views.gantt.IlvActivity;
import ilog.views.gantt.IlvDuration;
import ilog.views.gantt.IlvGanttChart;
import ilog.views.gantt.IlvGanttModel;
import ilog.views.gantt.IlvHierarchyChart;
import ilog.views.gantt.IlvResource;
import ilog.views.gantt.IlvScheduleChart;
import ilog.views.gantt.IlvTimeInterval;
import ilog.views.gantt.IlvTimeScrollController;
import ilog.views.gantt.IlvTimeUtil;
import ilog.views.gantt.action.IlvAction;
import ilog.views.gantt.action.IlvZoomToFitAction;
import ilog.views.gantt.event.ChartDividerEvent;
import ilog.views.gantt.event.ChartDividerListener;
import ilog.views.gantt.graphic.grid.IlvWeekendGrid;
import ilog.views.gantt.model.IlvDefaultGanttModel;
import ilog.views.gantt.swing.IlvJTable;
import ilog.views.util.IlvProductUtil;
import shared.AbstractExample;
import shared.GanttCommand;
import shared.data.GeneralActivityFactory;
import shared.data.GeneralResourceFactory;
import shared.data.SimpleEngineeringProject;
import shared.swing.ExampleFrame;
import xml.XMLGanttActions;
/**
* An example of synchronized Gantt and Schedule charts that display the same
* data model.
*/
public class DualChartExample extends AbstractExample {
/**
* The Gantt chart.
*/
protected IlvGanttChart gantt;
/**
* The Schedule chart.
*/
protected IlvScheduleChart schedule;
/**
* The data model used for the charts.
*/
protected IlvGanttModel model;
/**
* The various menu and toolbar actions.
*/
protected IlvAction newAction;
protected IlvAction openAction;
protected IlvAction saveAsAction;
protected IlvAction exitAction;
protected IlvAction insertActivityRowAction;
protected IlvAction deleteActivityRowAction;
protected IlvAction makeConstraintAction;
protected IlvAction deleteConstraintAction;
protected IlvAction insertResourceRowAction;
protected IlvAction deleteResourceRowAction;
protected IlvAction makeReservationAction;
protected IlvAction deleteReservationAction;
protected IlvAction deleteAllAction;
protected IlvAction rowExpandCollapseAction;
protected IlvZoomToFitAction zoomToFitAction;
protected IlvAction increaseRowHeightAction;
protected IlvAction decreaseRowHeightAction;
{
// 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);
}
/**
* Initializes the user interface of the example in the specified container.
*
* @param container
* The container that the example is running in. This will be the
* <code>contentPane</code> of the <code>JApplet</code> or the
* <code>JFrame</code>, depending on whether the example is run as an
* applet or as an application.
*/
Override
public void init(Container container) {
super.init(container);
container.setLayout(new BorderLayout());
// Create the charts.
gantt = new IlvGanttChart();
schedule = new IlvScheduleChart();
// Customize the data model factories and graphic renderers of the charts.
customizeFactories();
// Create the Gantt data model.
model = createGanttModel();
// Set the data model of the charts.
gantt.setGanttModel(model);
schedule.setGanttModel(model);
// Create the horizontal split pane and its 2 panels.
JPanel ganttPanel = new JPanel(new BorderLayout());
JPanel schedulePanel = new JPanel(new BorderLayout());
JSplitPane horizontalSplitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, ganttPanel, schedulePanel);
horizontalSplitter.setResizeWeight(0.5);
horizontalSplitter.setOneTouchExpandable(true);
// If the example is running as an applet, the container will have a defined
// fixed height already. In this case, we set the divider location to the
// approximate mid-point, not counting the menu bar, toolbar, or status bar
// components. If the example is running as an application, the container
// will not have a defined size yet. In this case, the preferred sizes of
// the gantt and schedule charts will be respected when the frame is packed.
int containerHeight = container.getHeight();
if (containerHeight > 0) {
horizontalSplitter.setDividerLocation(containerHeight / 2);
}
// Customize the appearance of the charts.
customizeCharts();
// Synchronize the behavior of the charts.
synchronizeCharts(gantt, schedule);
// Create and install the menu bar.
JMenuBar menuBar = createMenuBar();
setJMenuBar(menuBar);
// Create the status bar.
JLabel status = createStatusBar();
// Create the toolbars.
JToolBar mainToolBar = createMainToolBar();
JToolBar ganttToolBar = createGanttToolBar();
JToolBar scheduleToolBar = createScheduleToolBar();
ganttPanel.add(ganttToolBar, BorderLayout.LINE_START);
ganttPanel.add(gantt, BorderLayout.CENTER);
schedulePanel.add(scheduleToolBar, BorderLayout.LINE_START);
schedulePanel.add(schedule, BorderLayout.CENTER);
container.add(horizontalSplitter, BorderLayout.CENTER);
JPanel toolbarPanel = new JPanel();
toolbarPanel.add(mainToolBar);
container.add(toolbarPanel, BorderLayout.NORTH);
container.add(status, BorderLayout.SOUTH);
}
/**
* Customizes the data model factories and graphic renderers of the charts.
*/
protected void customizeFactories() {
// Change the default activity and resource factories of the Gantt chart
// to ones that sequentially number the activities and resources.
gantt.setActivityFactory(new GeneralActivityFactory(gantt));
gantt.setResourceFactory(new GeneralResourceFactory(gantt));
// Set the Schedule chart to use the same data factories as the Gantt chart.
schedule.setActivityFactory(gantt.getActivityFactory());
schedule.setResourceFactory(gantt.getResourceFactory());
schedule.setConstraintFactory(gantt.getConstraintFactory());
schedule.setReservationFactory(gantt.getReservationFactory());
}
/**
* Customizes the appearance of the Gantt and Schedule charts. The charts are
* not yet synchronized when this method is invoked.
*/
protected void customizeCharts() {
// Expand several activities in the Gantt chart so their children
// are visible.
IlvActivity ganttRoot = model.getRootActivity();
for (int i = 0; i <= 1; i++) {
if (model.getChildActivityCount(ganttRoot) > i) {
gantt.expandAllRows(model.getChildActivity(ganttRoot, i));
}
}
// Expand several resources in the Schedule chart so their children
// are visible.
IlvResource scheduleRoot = model.getRootResource();
for (int i = 0; i <= 1; i++) {
if (model.getChildResourceCount(scheduleRoot) > i) {
schedule.expandAllRows(model.getChildResource(scheduleRoot, i));
}
}
// Default column widths are 75. Resize some of the columns so that the
// text is not truncated.
IlvJTable table;
table = gantt.getTable();
table.getColumn("Name").setPreferredWidth(175);
table.getColumn("Start").setPreferredWidth(90);
table.getColumn("End").setPreferredWidth(90);
table = schedule.getTable();
table.getColumn("Name").setPreferredWidth(150);
table.getColumn("ID").setPreferredWidth(60);
table.getColumn("Qty").setPreferredWidth(40);
// Set the initially displayed time span to start 1 day before the beginning
// of the schedule and extend for 3 weeks. Later, the Schedule chart will be
// synchronized to the Gantt chart, so we only need to set the time span for
// the Gantt chart here.
Date visibleStartTime = IlvTimeUtil.subtract(model.getRootActivity().getStartTime(), IlvDuration.ONE_DAY);
gantt.setVisibleTime(visibleStartTime);
gantt.setVisibleDuration(IlvDuration.ONE_WEEK.multiply(3));
// Use a vertical grid in both charts that colors the weekends.
IlvWeekendGrid grid = new IlvWeekendGrid();
gantt.getGanttSheet().setVerticalGrid(grid);
grid = new IlvWeekendGrid();
schedule.getGanttSheet().setVerticalGrid(grid);
}
/**
* Synchronizes the behavior of the second specified chart to that of the
* first specified chart.
*
* @param chart1
* The primary chart.
* @param chart2
* The secondary chart that will be synchronized with the primary
* chart.
*/
protected void synchronizeCharts(final IlvHierarchyChart chart1, final IlvHierarchyChart chart2) {
// Use an IlvTimeScrollController to synchronize the visible time intervals
// of the two charts. This will only give the right effect if we also ensure
// that both charts always have their vertical scroll bar visible.
IlvTimeInterval visibleInterval = chart1.getVisibleInterval();
IlvTimeScrollController timeController = new IlvTimeScrollController();
timeController.addTimeScrollable(chart1);
timeController.addTimeScrollable(chart2);
timeController.setVisibleInterval(visibleInterval.getStart(), visibleInterval.getDuration());
chart1.setVerticalScrollBarPolicy(IlvHierarchyChart.VERTICAL_SCROLLBAR_ALWAYS);
chart2.setVerticalScrollBarPolicy(IlvHierarchyChart.VERTICAL_SCROLLBAR_ALWAYS);
// Synchronize the vertical splitters of both charts.
chart1.addChartDividerListener(new ChartDividerListener() {
Override
public void chartDividerLocationChanged(ChartDividerEvent evt) {
int location = evt.getDividerLocation();
if (location != chart2.getDividerLocation()) {
chart2.setDividerLocation(location);
}
}
});
chart2.addChartDividerListener(new ChartDividerListener() {
Override
public void chartDividerLocationChanged(ChartDividerEvent evt) {
int location = evt.getDividerLocation();
if (location != chart1.getDividerLocation()) {
chart1.setDividerLocation(location);
}
}
});
}
/**
* Creates the menu bar.
*
* @return The menu bar.
*/
public JMenuBar createMenuBar() {
JMenuBar menu = new JMenuBar();
menu.add(createFileMenu());
menu.add(createEditMenu());
menu.add(createRowMenu());
menu.add(createLAFMenu());
return menu;
}
/**
* Creates the "File" menu.
*
* @return The File menu.
*/
public JMenu createFileMenu() {
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
setStatusText(menu, "File operations");
// Menu item for "New".
newAction = new GanttCommand.NewDataModelAction(gantt) {
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = new IlvDefaultGanttModel();
gantt.setGanttModel(model);
schedule.setGanttModel(model);
}
};
addAction(menu, newAction);
if (isLocalFileAccessAllowed()) {
// Menu item for "Open ...".
openAction = new XMLGanttActions.OpenXMLAction(gantt) {
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = readXMLFile();
// Change the Gantt model of the Gantt chart
if (model != null) {
gantt.setGanttModel(model);
schedule.setGanttModel(model);
zoomToFit();
}
}
};
addAction(menu, openAction);
// Menu item for "Save ...".
saveAsAction = new XMLGanttActions.SaveAsXMLAction(gantt);
addAction(menu, saveAsAction);
}
// Menu item for "Exit".
if (isExitAllowed()) {
menu.addSeparator();
exitAction = new GanttCommand.ExitAction();
addAction(menu, exitAction);
}
return menu;
}
/**
* Creates the Edit menu.
*
* @return The Edit menu.
*/
public JMenu createEditMenu() {
JMenu menu = new JMenu("Edit");
menu.setMnemonic(KeyEvent.VK_E);
setStatusText(menu, "Adds, removes, or modifies activities, constraints, resources, and reservations.");
// Menu item for "Insert new activity".
insertActivityRowAction = new GanttCommand.InsertActivityAction(gantt);
addAction(menu, insertActivityRowAction);
// Menu item for "Delete selected activity".
deleteActivityRowAction = new GanttCommand.DeleteSelectedRowsAction(gantt);
deleteActivityRowAction.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
addAction(menu, deleteActivityRowAction);
// Menu item for "Create new constraint".
makeConstraintAction = new GanttCommand.MakeConstraintAction(gantt);
addAction(menu, makeConstraintAction);
// Menu item for "Delete selected constraints".
deleteConstraintAction = new GanttCommand.DeleteSelectedConstraintsAction(gantt);
deleteConstraintAction.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK));
addAction(menu, deleteConstraintAction);
menu.addSeparator();
// Menu item for "Insert new resource".
insertResourceRowAction = new GanttCommand.InsertResourceAction(schedule);
insertResourceRowAction.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.SHIFT_DOWN_MASK));
addAction(menu, insertResourceRowAction);
// Menu item for "Delete selected resource".
deleteResourceRowAction = new GanttCommand.DeleteSelectedRowsAction(schedule);
deleteResourceRowAction.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.SHIFT_DOWN_MASK));
addAction(menu, deleteResourceRowAction);
// Menu item for "Create reservation".
makeReservationAction = new GanttCommand.MakeActivityAction(schedule);
addAction(menu, makeReservationAction);
// Menu item for "Delete selected reservations".
deleteReservationAction = new GanttCommand.DeleteSelectedReservationsAction(schedule);
deleteReservationAction.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK));
addAction(menu, deleteReservationAction);
menu.addSeparator();
// Menu item for "Delete all".
deleteAllAction = new GanttCommand.DeleteSelectedAction(gantt, schedule);
deleteAllAction.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.CTRL_DOWN_MASK));
addAction(menu, deleteAllAction);
menu.addSeparator();
// Menu item for "Expand/Collapse".
rowExpandCollapseAction = new GanttCommand.RowExpandCollapseAction(gantt, schedule);
addAction(menu, rowExpandCollapseAction);
return menu;
}
/**
* Creates the Row menu.
*
* @return The Row menu.
*/
public JMenu createRowMenu() {
JMenu menu = new JMenu("Row");
menu.setMnemonic(KeyEvent.VK_R);
setStatusText(menu, "Changes the chart's row height.");
// Menu item for "Increase 2 pixels".
increaseRowHeightAction = new GanttCommand.RowHeightAction(2, gantt, schedule);
increaseRowHeightAction.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, KeyEvent.CTRL_DOWN_MASK));
addAction(menu, increaseRowHeightAction,
// Add an alternate keystroke, since Ctrl-2 is not available on some
// national keyboards.
new KeyStroke[] { KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD2, KeyEvent.CTRL_DOWN_MASK) });
// Menu item for "Decrease 2 pixels".
decreaseRowHeightAction = new GanttCommand.RowHeightAction(-2, gantt, schedule);
decreaseRowHeightAction
.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK));
addAction(menu, decreaseRowHeightAction,
new KeyStroke[] { KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD2, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK) });
return menu;
}
/**
* Creates the main toolbar.
*
* @return The main application toolbar.
*/
protected JToolBar createMainToolBar() {
JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL);
toolbar.setFloatable(false);
addAction(toolbar, newAction);
if (openAction != null) {
addAction(toolbar, openAction);
}
if (saveAsAction != null) {
addAction(toolbar, saveAsAction);
}
toolbar.addSeparator();
addAction(toolbar, deleteAllAction);
toolbar.addSeparator();
addAction(toolbar, rowExpandCollapseAction);
toolbar.addSeparator();
addAction(toolbar, gantt.getZoomOutAction());
addAction(toolbar, gantt.getZoomInAction());
zoomToFitAction = new IlvZoomToFitAction(gantt, "Zoom To Fit",
KeyStroke.getKeyStroke(KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK), "Zoom To Fit",
"Zooms the time scale to fit the data.");
addAction(toolbar, zoomToFitAction);
return toolbar;
}
/**
* Creates the toolbar of the Gantt chart.
*
* @return The Gantt chart toolbar.
*/
protected JToolBar createGanttToolBar() {
JToolBar toolbar = new JToolBar(JToolBar.VERTICAL);
toolbar.setFloatable(false);
addAction(toolbar, insertActivityRowAction);
addAction(toolbar, deleteActivityRowAction);
addAction(toolbar, makeConstraintAction);
addAction(toolbar, deleteConstraintAction);
return toolbar;
}
/**
* Creates the toolbar of the Schedule chart.
*
* @return The Schedule chart toolbar.
*/
protected JToolBar createScheduleToolBar() {
JToolBar toolbar = new JToolBar(JToolBar.VERTICAL);
toolbar.setFloatable(false);
addAction(toolbar, insertResourceRowAction);
addAction(toolbar, deleteResourceRowAction);
addAction(toolbar, makeReservationAction);
addAction(toolbar, deleteReservationAction);
return toolbar;
}
/**
* Creates and returns the Gantt data model.
*
* @return The data model.
*/
protected IlvGanttModel createGanttModel() {
return new SimpleEngineeringProject(gantt);
}
// =========================================
// Example Application
// =========================================
/**
* Returns the title of the example.
*
* @return The title of the example.
*/
Override
public String getTitle() {
return "Synchronized Gantt and Schedule Chart Example";
}
/**
* Application mainline.
*
* @param args
* The command line arguments.
*/
public static void main(String[] args) {
ExampleFrame.createAndShowGUI(DualChartExample.class);
}
}