/*
* 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 dualTable;
import java.awt.BorderLayout;
import java.awt.Container;
import java.text.DateFormat;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import ilog.views.gantt.IlvGanttChart;
import ilog.views.gantt.IlvGanttComponentManager;
import ilog.views.gantt.IlvHierarchyChart;
import ilog.views.gantt.IlvJScrollPane;
import ilog.views.gantt.event.HeaderHeightChangedEvent;
import ilog.views.gantt.event.HeaderListener;
import ilog.views.gantt.swing.IlvJTable;
import ilog.views.gantt.swing.IlvJTableColumn;
import ilog.views.gantt.swing.IlvJTableHeader;
import shared.swing.ExampleFrame;
import xml.XMLGanttExample;
/**
* An example of adding a secondary table to the right side of a Gantt chart.
*/
public class DualTableExample extends XMLGanttExample {
/**
* The new table on the right side.
*/
protected IlvJTable rightTable;
/**
* The scroll pane containing the new table.
*/
protected IlvJScrollPane rightScrollPane;
/**
* The new splitter that separates the table on the right from the Gantt
* chart.
*/
protected JSplitPane rightSplitter;
/**
* 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);
// Create a new table and move the "Start" and "End" columns into it.
rightTable = new IlvJTable();
IlvJTable leftTable = chart.getTable();
IlvJTableColumn startColumn = leftTable.getTableColumn("Start");
leftTable.removeColumn(startColumn);
rightTable.addColumn(startColumn);
IlvJTableColumn endColumn = leftTable.getTableColumn("End");
leftTable.removeColumn(endColumn);
rightTable.addColumn(endColumn);
// Place the new table into an IlvJScrollPane.
rightScrollPane = new IlvJScrollPane(rightTable);
rightScrollPane.setPreferredSize(rightTable.getPreferredSize());
// Create opaque labels to fill the corners when the vertical scroll bar
// becomes visible.
JLabel urLabel = new JLabel();
urLabel.setOpaque(true);
rightScrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER, urLabel);
JLabel lrLabel = new JLabel();
lrLabel.setOpaque(true);
rightScrollPane.setCorner(JScrollPane.LOWER_RIGHT_CORNER, lrLabel);
// Create a new split pane. Place the Gantt chart on the left side and the
// new table on the right side.
rightSplitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
container.remove(chart);
rightSplitter.add(chart, JSplitPane.LEFT);
rightSplitter.add(rightScrollPane, JSplitPane.RIGHT);
rightSplitter.setResizeWeight(1);
container.add(rightSplitter, BorderLayout.CENTER);
// If the example is running as an applet, the container will have a defined
// fixed width already. In this case, we set the divider location to respect
// the preferred size of the new table. 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 components will be respected when the
// frame is packed.
int containerWidth = container.getWidth();
if (containerWidth > 0)
rightSplitter.setDividerLocation(containerWidth - rightTable.getPreferredSize().width);
// Synchronize the vertical scrolling, the horizontal scrolling, and
// selection behavior of the new table with the Gantt chart.
IlvGanttComponentManager componentManager = chart.getComponentManager();
componentManager.addVerticalScrollable(rightScrollPane);
componentManager.addVerticalExpandable(rightTable);
componentManager.addSelectable(rightTable);
// Synchronize the visibility of the new table's horizontal scroll bar to
// that of the Gantt chart.
rightScrollPane.setHorizontalScrollBarPolicy(chart.isHorizontalScrollBarVisible()
? JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS : JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// Disable the vertical scroll bar from the Gantt chart and enable it for
// the new table.
rightScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
chart.setVerticalScrollBarPolicy(IlvHierarchyChart.VERTICAL_SCROLLBAR_NEVER);
// Synchronize the borders, insets, and preferred size of the new table to
// the Gantt chart. This ensures that the new table aligns properly with
// the chart.
chart.addHeaderListener(new HeaderHeightListener());
}
/**
* Creates the Gantt chart.
*/
Override
protected IlvHierarchyChart createChart() {
return new IlvGanttChart() {
/**
* This method is a notification that the look and feel of the chart has
* been initialized or changed. This method is overridden to resynchronize
* the size and layout of the new table with the Gantt chart.
*/
Override
public void updateUI() {
// Update the Gantt's UI before we synchronize the new table.
super.updateUI();
// Update the new table on the Swing event queue so that all other
// components update first.
SwingUtilities.invokeLater(new Runnable() {
Override
public void run() {
// The first invocation of this method occurs while the chart is
// still being constructed. Until the constructor has completed, the
// reference from the chart to the outer example class is not
// initialized yet.
if (DualTableExample.this != null && chart != null)
syncRightTableUI();
}
});
}
};
}
/**
* Synchronizes the borders, insets, and preferred size of the new table to
* the Gantt chart. This synchronization makes sure that the new table aligns
* properly with the chart.
*/
private void syncRightTableUI() {
// Set the chart to have no border. This will ensure that the chart's table
// and Gantt sheet will be aligned vertically with the new table.
chart.setBorder(null);
chart.setInsideBorder(null);
// If the table is smaller than the view port, make the exposed area of the
// view port the same background color.
rightScrollPane.setViewportBackground(rightTable.getBackground());
// Synchronize the size of the splitters.
rightSplitter.setDividerSize(chart.getDividerSize());
rightSplitter.setOneTouchExpandable(chart.isDividerOneTouchExpandable());
}
/**
* Sets the current date format. This method is overridden to update the
* columns of the secondary table.
*/
Override
public void setDateFormat(DateFormat format) {
if (format.equals(getDateFormat()))
return;
setDateFormat(rightTable, format);
super.setDateFormat(format);
}
/**
* This class listens for header height changes of the chart time scale and
* makes the necessary UI rearrangements. It synchronizes the height of the
* table header with the height of the time scale.
*/
class HeaderHeightListener implements HeaderListener {
/**
* This method is called when the height value of the Gantt header changes.
*
* @param event
* <code>HeaderHeightChangedEvent</code> The event.
*/
Override
public void headerHeightChanged(HeaderHeightChangedEvent event) {
IlvJTableHeader tableHeader = rightTable.getHeader();
int preferredHeight = tableHeader.computePreferredHeight(chart);
tableHeader.setPreferredHeight(preferredHeight);
tableHeader.revalidate();
}
}
// =========================================
// Example Application
// =========================================
/**
* Returns the title of the example.
*/
Override
public String getTitle() {
return "Secondary Data Table Example";
}
/**
* Application mainline.
*
* @param args
* The command line arguments.
*/
public static void main(String[] args) {
ExampleFrame.createAndShowGUI(DualTableExample.class);
}
}