JGantt is the Swing component for the gantt chart painting and editing.
This chapter contains descriptions of JGantt's most essential features:
Standard view - Standard chart appearance and behavior customizable settings. There are a treetable and a chart component side by side. The treetable on the left hand side, and the chart component on the right. Exactly as you know it from other gantt components. But you can modify their appearance as you need.
Advanced treetable - The treetable has a few very interesting features: It is derived from eu.beesoft.gaia.swing.JTreeTable, so it has the features of JTable and JTree - it is easy to use it, if you are familiar with Swing programming. JTreeTable can paint "zebra" background and also show / hide columns on user selection (right click on treetable header displays popup menu with column names to hide / show). There is also built-in support for the context popup menu and double click processing.
Data binding - Model for JGantt is oriented on the easy programming and usage. One of its features is automated data binding. You can set a name of the property of your domain object you want to display in some column and JGantt displays it without any more programming. And the same it does with setting user-changed visual data to domain object.
Lazy loading - If your application works with a large dataset, it is suitable to load to the memory just the visible part of the data. JGantt treetable listens to treeexpand event and if node is expanded for the first time, it invokes method explore() on GanttModel. This is the place you can load data for node's user object and build subnodes. Do you know any more simple solution?
Layers - Gantt chart is painted in some layers. You can choose which layers you want install into gantt chart, and also you can hide / show layers at runtime. Each layer has specific purpose and paints only the gadgets it is programmed for. You can develop new layers or customize the existing. This is the way you can customize the whole chart, change the shape of timeline objects or dependency lines or add an absolutelly new functionality. In each layer you can solve also a mouse service, there is a built-in support.
Relationships - Timeline objects (tasks) can have relationship with each other. You can define constraints on such relationship (for example: this task can start after that task is finished). In the JGantt you need implement one interface on the domain objects level. And you can subclass layer for dependencies painting to get your own visualization of dependencies, if the delivered is nor suitable for you.
Actions - JGantt comes with predefined set of actions. There are actions for zoom-in and zoom-out, creating, deleting and moving nodes (and their user-objects) in the tree hierarchy, and also actions for undo and redo operations. And also abstract superclasses for the smart building another actions.
Localization - JGantt uses data from resource bundle for treetable column names and action properties. There is a built-in mechanism to do it without any programming. If your application contains more resource bundles for more languages, you can build a multi-lingual gantt chart in a very simple way. JGantt listens to the language changes at runtime and repaints itself if gets event.
Here is the picture of our demo application distributed with JGantt:
Every object you want to display in JGantt treetable must implement eu.beesoft.gantt.TimelineObject interface. There are methods in this interface to get / set a start and end date of object, etc. In our example we create class Task for our domain objects. Our Task is the bean with some additional logic to handle start and end date changes:
public class Task extends AbstractBean implements TimelineObject { private String taskId; private String name; private String description; private Date startDate; private Date endDate; private long effort; private boolean milestone; private Task supertask; private List<Task> subtask; private List<Dependency> dependencies; private Resource assignee; public Task () { // empty } public String getName () { return name; } public void setName (String name) { String old = this.name; this.name = name; firePropertyChange ("name", old, name); } ..... public Date getStartDate () { if ((startDate == null) && isSummary ()) { updateStart (); } return startDate; } public void setStartDate (Date start) { if (Objects.equals (this.startDate, start)) { return; } Date old = this.startDate; this.startDate = start; if (supertask != null) { supertask.updateStart (); } firePropertyChange ("startDate", old, start); } private void updateStart () { if (isSummary ()) { Date thisStart = null; List<Task> tasks = getSubtask (); for (Task task : tasks) { Date taskStart = task.getStartDate (); if (taskStart != null) { if ((thisStart == null) || thisStart.after (taskStart)) { thisStart = taskStart; } } } if (thisStart != null) { setStartDate (thisStart); } } } ..... }
Next, we create our model. We implement these methods:
Here is the source:
public class Model extends GanttModel { public Model () { super (); } @Override public Class> getColumnClass (int column) { switch (column) { case 2: case 3: return Date.class; default: return super.getColumnClass (column); } } @Override public boolean isCellEditable (TreeTableNode node, int column) { if (column == 0) { return true; } return (column >= 2); } @Override public void explore (GanttNode node) { Task task = (Task) node.getUserObject (); for (Task t : task.getSubtask ()) { GanttNode child = new GanttNode (this, t); if (t.getSubtask ().isEmpty ()) { child.setExplorable (false); } node.add (child); } } @Override public boolean moveObject (TimelineObject object, TimelineObject newContainer, int newIndex, UndoStep undo) { Task task = (Task) object; Task supertask = (Task) newContainer; undo.registerObject (task); undo.registerObject (supertask); Task oldSupertask = task.getSupertask (); if (supertask != oldSupertask) { if (oldSupertask != null) { undo.registerObject (oldSupertask); oldSupertask.removeSubtask (task); } supertask.addSubtask (task); } supertask.shiftSubtask (task, newIndex); return true; } @Override public boolean deleteObject (TimelineObject what, UndoStep undo) { Task task = (Task) what; Task parent = task.getSupertask (); undo.registerObject (parent); undo.registerObject (task); parent.removeSubtask (task); return true; } @Override public TimelineObject createObject (TimelineObject parent, int index, UndoStep undo) { undo.registerObject (parent); Task parentTask = (Task) parent; Task task = new Task (); String id = Gantt.getNextTaskId (); task.setTaskId (id); task.setName ("Task " + id); parentTask.addSubtask (task); parentTask.shiftSubtask (task, index); return task; } @Override public String getLabel (TimelineObject object) { if (object instanceof Task) { Resource assignee = ((Task) object).getAssignee (); if (assignee != null) { return assignee.getName (); } } return null; } }
Now we can create our DemoGantt class that subclasses JGantt. It is very simple class, it has only two methods to support mouse actions:
public class DemoGantt extends JGantt { private static Action createNodeAction; private static Action editNodeAction; private static Action deleteNodeAction; private static Action indentNodeAction; private static Action unindentNodeAction; private static Action moveNodeUpAction; private static Action moveNodeDownAction; private static Action expandAllNodesAction; private static Action collapseAllNodesAction; private static Action zoomInAction; private static Action zoomOutAction; private static Action todayAction; private static Action undoAction; private static Action redoAction; private ListpopupActions; public DemoGantt (GanttModel model) { super (model); } @Override protected List<Action> getPopupActions (List<GanttNode> selectedNodes) { if (popupActions == null) { popupActions = new ArrayList<Action> (); popupActions.add (createNodeAction); popupActions.add (editNodeAction); popupActions.add (deleteNodeAction); popupActions.add (null); popupActions.add (indentNodeAction); popupActions.add (unindentNodeAction); popupActions.add (moveNodeUpAction); popupActions.add (moveNodeDownAction); } return popupActions; } @Override public void doubleClicked (GanttNode node) { Task task = (Task) node.getUserObject (); TaskPropertiesAction.showTaskProperties (task, this); } }
To keep the example here as simple as possible we ignore another auxiliary classes (as actions, form to edit task properties or date cell renderer). All of them you can find in our DEMO directory.
So what we need is put it all together. It is done in DemoGantt.main() method:
// create model // it extends GanttModel GanttModel model = new Model (); // create domain objects // they should come from database or server in real application Resource worker_1 = new Resource (); worker_1.setName ("Smith John"); ..... Task task_1_1 = createTask ("Task 1.1", -20, +1, 92); task_1_1.setAssignee (worker_1); ..... Task task_1 = createTask ("Task 1", 0, 0, 0); task_1.addSubtask (task_1_1); ..... Project project = new Project (); project.setName ("Project"); project.addResource (worker_1); project.addSubtask (task_1); ..... // set created project as gantt model root object model.setRootObject (project); ..... // create gantt component with "zebra" background // and vertical column-line-separators JGantt gantt = new DemoGantt (model); JTreeTable treeTable = gantt.getTreeTable (); treeTable.setAlternateBackground (treeTable .getDefaultAlternateBackground ()); treeTable.setShowVerticalLines (true); // create columns in gantt tree-table // this is the first column with task tree GanttColumn column = new GanttColumn (); column.setHeaderValue ("Task name"); column.setBinding ("name"); gantt.addColumn (column); column = new GanttColumn (); column.setHeaderValue ("Task ID"); column.setBinding ("taskId"); gantt.addColumn (column); ..... // resize columns to appropriate width gantt.getTreeTable ().pack (); // create layers for gantt chart // order of layers is important for painting gantt.addLayer (new BackgroundLayer ()); gantt.addLayer (new CalendarLayer ()); gantt.addLayer (new GridLayer ()); gantt.addLayer (new TodayLayer ()); gantt.addLayer (new GanttNodeLayer ()); gantt.addLayer (new LabelLayer ()); gantt.addLayer (new DependencyLayer ()); // create gantt actions createNodeAction = new CreateNodeAction (gantt); editNodeAction = new TaskPropertiesAction (gantt); ..... build menu and toolbar, create a swing frame and show it
Note in this example:
Simply unzip downloaded file to appropriate directory (you must create such directory). You will get this structure:
JGANTT - this is the root directory license.txt - license agreement DEMO - Java demo example for JGantt usage, contains sources and JAR file with instructions DOC - documentation directory manual.html - JGantt manual, this is what you are reading IMAGES - directory with images for manual API - Javadoc directory LIB - jars directory jgantt_2010_2.jar - component library gaia_2010_2.jar - BeeSoft general library abeona_2010_3.jar - license protector
You can copy JAR files to any appropriate place for your development. It is not necessary to keep them in the installation directory.
JGantt consists of these packages:
- contains main classes and interfaces (JGantt, GanttModel, TimelineObject, Dependency) | |||||
- contains all implemented actions | |||||
- contains chart related classes (ChartComponent, Layer, TimeSpan, TimeUnit) | |||||
- contains treetable related classes (GanttTreeTable, GanttColumn, GanttNode) | |||||
- contains classes for undo / redo functionality (UndoStep, StateEditableObject) |
JGantt strongly uses classes from our Gaia library. This is our company general library and is available for free. Current version of this library is included in your distribution, but you can upgrade at any time. These packages from Gaia are used by JGantt:
- contains Swing components and classes for Swing support | |||||
- contains utility classes |
JGantt is component protected by Abeona protection system. You can freely download this component and use it, but there is one feature built-in: if JGantt is not licensed, it stops to work 10 minutes after it was constructed. You must restart your application which uses this component.
When you purchase a license for JGantt, you will get a license file to your email. Copy this file where you want to your classpath and then complete your application with a similar code:
JGantt gantt = new JGantt (); ... init gantt component InputStream is = SomeMyClass.class.getInputStream ("path-to-license-file"); License license = gantt.setLicense (is); if (license == null) { throw new RuntimeException ("Ooops, something goes wrong here..."); }
The model for JGantt consists of:
That's all. Your domain objects must implement the given interfaces. And your model must subclass the GanttModel class to serve some methods.
TimelineObject is an interface that prescribes some methods for your domain objects. Each of these methods concerns on getting / setting data for the gantt chart:
void addPropertyChangeListener (PropertyChangeListener) | Adds instance of java.beans.PropertyChangeListener to a listener list. | Date getStartDate () | Returns the start date of this TimelineObject. | void setStartDate (Date) | Sets the new start date for this TimelineObject. | Date getEndDate () | Returns the end date of this TimelineObject. |
void setEndDate (Date) | Sets the new end date for this TimelineObject. | ||||
boolean isSummary () | Returns true if this is a summary object (it contains some subtasks) | ||||
boolean isMilestone () | Returns true if this is a milestone object. | ||||
void setMilestone (boolean) | Sets the milestone property. | ||||
List<Dependency> getDependencies () | Returns a list of all dependencies between this TimelineObject and other objects. | ||||
void setDependencies (List<Dependency>) | Sets a list of all dependencies between this TimelineObject and other objects. |
A typical application's domain object that has to implement this interface is a task.
Dependency is an interface that describes dependency between TimelineObjects. Here is the list of methods you need to implement:
TimelineObject getSuccessor () | Returns a dependant object. | |
void setSuccessor (TimelineObject) | Sets a dependant object. | |
TimelineObject getPredecessor () | Returns an object which dependant depends on. | |
void setPredecessor (TimelineObject) | Sets object which dependant depends on. | |
int getType () | Returns the type of this Dependency (one of the constants FINISH_TO_START, FINISH_TO_FINISH, START_TO_START, START_TO_FINISH). | |
void setType (int) | Sets the new type of this Dependency (one of the constants FINISH_TO_START, FINISH_TO_FINISH, START_TO_START, START_TO_FINISH). |
There are some constants defined in the Dependency interface. They define the type of dependency:
FINISH_TO_START | Constant for dependency type where dependant cannot begin until the object it depends on is complete. | |
FINISH_TO_FINISH | Constant for dependency type where dependant cannot be completed until the object that it depends on is completed. | |
START_TO_START | Constant for dependency type where dependant cannot begin until the object that it depends on begins. | |
START_TO_FINISH | Constant for dependency type where dependant cannot be completed until the object that it depends on begins. |
GanttModel extends JTreeTable model from Gaia library. You have to implement these methods:
TimelineObject createObject (TimelineObject, int, UndoStep) | Creates a new domain object and adds it as child to parent (you don't need to care about treetable nodes). Register all modified objects to undo before any change. | |
boolean deleteObject (TimelineObject, UndoStep) | Removes given object from its parent on domain objects level (you don't need to care about treetable nodes). Register object, its parent and all modified objects to undo before any change. | |
boolean moveObject (TimelineObject, TimelineObject, int, UndoStep) | Moves given object on domain objects level (you don't need to care about treetable nodes). Register all modified objects to undo before any change. |
The methods above are designed to manipulate with objects on the domain objects level. You don't need to work with treetable nodes.
If you want to paint in the chart component on the time lines some texts (if you use LabelLayer or TooltipLayer), you need override these methods:
String getLabel (TimelineObject) | Returns label text for given object. This text uses LabelLayer to paint additional info to timeline object. Typically, for a task is name of the assignee probably the best result. | |
String getTooltipText (TimelineObject) | Returns tooltip text for given object. |
GanttModel supports lazy loading for treetable data. The possibilities of ExplorableTreeNode, which is an ancestor of GanttNode, is emplyed here. When node is expanded and was not explored still, method explore(GanttNode) is invoked.
void explore (GanttNode) | This method is called by GanttNode for data loading. |
node
node
GanttTreeTable is the tree table for gantt chart. It is the left-located component of the JGantt.
GanttTreeTable is the descendant of the eu.beesoft.gaia.swing.JTreeTable (you can read about it in the next chapter, and the next informations are accessible in API documentation).
The eu.beesoft.gaia.swing.JTreeTable class is a combination of a JTree and a JTable - a component capable of both expanding and contracting rows, as well as showing multiple columns of data.
This component always displays a tree in the first column and the additional data in the next columns. You can see its usage in a very simple example of the directory tree.
This component has the next features:
GanttNode is the only javax.swing.tree.TreeNode acceptable by a gantt tree data structure. It is a final class, so there is no way to customize it.
Here are the key features of the GanttNode:
GanttColumn represents a column in the GanttTreeTable. It is a descendant of javax.swing.table.TableColumn . It supports:
Data binding is implemented by eu.beesoft.gaia.util.Miner class. It gets values from any object and sets them in. In the first step via property accessors (getter / setter) and if appropriate accessor is not found, on the field access level. More informations about Miner class you can find in API documentation.
GanttModel has implemented these methods related to data binding:
Miner getMiner () | Returns the current instance of the Miner used by this GanttModel. | |
void setMiner (Miner) | Sets a new instance of the Miner for use by this GanttModel. The Miner class is designated to obtain property value on method or field level from any object. You can subclass Miner class to reach your requirements. | |
Object getValueAt (TreeTableNode, int) | Returns value from given node and for given column. | |
void setValueAt (TreeTableNode, int, Object) | Sets given value to the user object in the node and column. |
These methods support data binding in GanttColumn:
String getBinding () | Returns binding for this column. Binding is a property name (or dot-separated chain of property names). A value for this column is mined from this property. | |
void setBinding (String) | Sets binding for this column. Binding is a property name (or dot-separated chain of property names). A value for this column is mined from this property. |
A GanttColumn has built-in support for resource bundle usage. These methods are implemented:
String getResourceBundleKey () | Returns key used for resource bundle. | |
void setResourceBundleKey (String) | Sets resource bundle key. This key is used when accessing resource bundle to get (localized) column label. | |
void languageChanged (Language) | Implements LanguageListener. Invoked when environment changes. Reinitializes column header from resource bundle. |
First two methods operates with resource bundle key. It is a key under which is stored localized text in resource bundle. The third method is a listener method and is invoked, when you change language settings in application. It is invoked from eu.beesoft.gaia.util.Language.
What resource bundle is used? The way the resource bundle is found, is described here.
Gantt chart is located on the right side of the JGantt component. It consists of:
All classes of the gantt chart are in the package eu.beesoft.gantt.chart.
There are two important classes for whole package:
TimeUnit is an enumeration for time unit granularity. It contains constants from seconds to year and some useful methods.
TimeSpan envelopes date range (start time - end time). Instances of TimeSpan are created by ChartComponent in its updateChart() method. They contains information about:
All of these informations are used by chart component to prepare painting.
The painting in gantt chart is implemented through the layers. A Layer is an abstract class that provides functionality to paint chart and interact with a user.
When you construct a gantt, you set to the ChartComponent several layers. Chart component, when painting, iterates through them and invokes the paint(Graphics) method on each of them. The order you add layers to ChartComponent is important.
ChartHeader paints headers above the ChartComponent instance. This component contains two headers - major and minor - and their models.
HeaderModel is used to paint major or minor header for ChartComponent. It contains data for header columns.
HeaderColumn is a subclass of javax.swing.table.TableColumn to hold list of TimeSpan instances. These instances are used to calculate sizes of the column.
There is very low probability you need to customize these classes. They are created by JGantt in initialization phase. All you need to do is to use them.
A ChartComponent is one of the most meaningful sub-components of JGantt. It is painted on the right side of JGantt (there is an instance of JTreeTable on the left).
It co-ordinates painting with registered instances of the Layer class and dispatches events to them.
The ChartComponent is created by JGantt in initialization phase and there is no way to customize it.
A layer is an object having a graphical representation that can be displayed in the gantt chart and that can interact with the user.
The Layer class is the abstract superclass of the each gantt chart layer.
The gantt ChartComponent holds a stack of user-defined layers. When the method paint(Graphics) on ChartComponent is invoked, it walks through this stack (in order the layers were added) and if the layer is visible (method isVisible() returns true) calls method paint(Graphics) on it.
Here are the methods that eu.beesoft.gantt.chart.Layer class provides:
JGantt getGantt () | Returns instance of JGantt to which this Layer belongs. | |
boolean isVisible () | Returns value of property 'visible'. | |
void setVisible (boolean) | Sets a new value for property 'visible'. Layer is painted only if visible = true. | |
List<GanttNode> getPaintedNodes () | Returns list of currently on-screen visible and painted gantt nodes. | |
int getPosition (Date) | Returns x-coordinate for given date. | |
void mouseClicked (MouseEvent) | Invoked when the mouse has been clicked on a component. In this implementation does nothing. | |
void mouseEntered (MouseEvent) | Invoked when the mouse enters a component. In this implementation does nothing. | |
void mouseExited (MouseEvent) | Invoked when the mouse exits a component. In this implementation does nothing. | |
void mousePressed (MouseEvent) | Invoked when a mouse button has been pressed on a component. In this implementation does nothing. | |
void mouseReleased (MouseEvent) | Invoked when a mouse button has been released on a component. In this implementation does nothing. | |
void mouseMoved (MouseEvent) | Invoked when the mouse button has been moved on a component (with no buttons no down). In this implementation does nothing. | |
void mouseDragged (MouseEvent) | Invoked when a mouse button is pressed on a component and then dragged. In this implementation does nothing. |
There is a set of implemented layers you can use. Of course, you can write your own - subclass eu.beesoft.gantt.chart.Layer and implement method paint(Graphics).
You can also modify an existing layer - subclass it and override method you need.
Here is the list of the implemented layers you can use:
BackgroundLayer | Paints colored background for gantt chart. | |
CalendarLayer | Paints background for weekend days. | |
DependencyLayer | Paints dependencies between gantt nodes. | |
GanttNodeLayer | Paints gantt nodes as time-line objects on chart component. | |
GridLayer | Paints grid (horizontal and vertical lines) in gantt chart component. | |
LabelLayer | Paints text label beside node. | |
TodayLayer | Paints strong vertical line on chart component at given date (usually today). |
As a standard Swing component, JGantt is controlled by actions.
AbstractGanttAction is a base class for gantt component actions. It is not necessary to subclass this class, you can use any action. But AbstractGanttAction offers these features:
AbstractGanttAction processes actionPerformed (ActionEvent) method to offer undo / redo support. It invokes executeAction (ActionEvent, UndoStep) method, which is an abstract method, and if it returns true, registers all changes from UndoStep in UndoManager.
AbstractGanttAction gets its properties from resource bundle. All action properties (currently: text, icon and tooltip) must be described in resource bundle. This process is automated, so you must observed some rules:
For example, if your action class is mydomain.mypackage.MyAction, then in the resource bundle should be:
mydomain.mypackage.MyAction.text=Text for action mydomain.mypackage.MyAction.icon=mydomain/mypackage/MyIcon.gif mydomain.mypackage.MyAction.tooltip=This is a tooltip for my actionor shorter:
MyAction.text=Text for action MyAction.icon=mydomain/mypackage/MyIcon.gif MyAction.tooltip=This is a tooltip for my action
The way the resource bundle is found, is described here.
JGantt uses Swing undo package functionality to provide support for undo/redo operations.
There are two classes in eu.beesoft.gantt.undo package for that purpose:
StateEditableObject implements javax.swing.undo.StateEditable interface. Its constructor takes one object, and StateEditableObject can this object introspect and to remember changed properties.
UndoStep is the descendant of javax.swing.undo.CompoundEdit class. It serves as a container of all operations for one undo / redo step. It offers two methods:
void registerObject (Object) | Registers object to store / restore its state. If given object does not implement interface javax.swing.undo.StateEditable, the object is covered by StateEditableObject to make it eligibly for undo / redo operations. Then is object registered and its pre-state is obtained. | |
void end () | Gets the post-edit state of the required objects and ends the edit. |
If you want to process undo / redo, you have to:
AbstractGanttAction supports all of these steps except step 2. So what you have to do, if your action is deriver from AbstractGanttAction, is to call registerObject(Object) for each object that can be changed in method executeAction (ActionEvent, UndoStep) only.
Here is the list of the implemented actions you can use:
CollapseAllNodesAction | This action collapses all nodes in the JGantt treetable. | |
CreateNodeAction | This action asks GanttModel.createObject(TimelineObject, int, UndoStep) to create new domain object and then creates a new GanttNode} and includes it in hierarchy. | |
DeleteNodeAction | Action asks GanttModel.deleteObject(TimelineObject, UndoStep) to delete domain object and if it is successful, removes the node from tree hierarchy. | |
ExpandAllNodesAction | This action expands all nodes in the JGantt treetable. | |
IndentNodeAction | This action asks GanttModel.moveObject(TimelineObject, TimelineObject, int, UndoStep) to move a domain object into domain hierarchy and then moves also corresponding GanttNode. | |
MoveNodeDownAction | This action asks GanttModel.moveObject(TimelineObject, TimelineObject, int, UndoStep) to move a domain object into domain hierarchy and then moves also corresponding GanttNode. | |
MoveNodeUpAction | This action asks GanttModel.moveObject(TimelineObject, TimelineObject, int, UndoStep) to move a domain object into domain hierarchy and then moves also corresponding GanttNode. | |
RedoAction | This action asks JGantt.getUndoManager() to redo next operation. | |
TodayAction | This action scrolls the date/time columns in the ChartComponent} so the column with today date is visible. You can set any date for this action as today date. | |
UndoAction | This action asks JGantt.getUndoManager() to undo last operation. | |
UnindentNodeAction | This action asks GanttModel.moveObject(TimelineObject, TimelineObject, int, UndoStep) to move a domain object into domain hierarchy and then moves also corresponding GanttNode. | |
ZoomInAction | This action zooms in the content of ChartComponent. | |
ZoomOutAction | This action zooms out the content of ChartComponent. |
JGantt covers all above components:
These components are constructed in the initialization phase and developer has no impact to it. You can change their properties only.
The standard JGantt subcomponents are accessible by these methods:
GanttTreeTable getTreeTable () | Returns the tree table object of this JGantt. | |
ChartComponent getChartComponent () | Returns the instance of ChartComponent. | |
ChartHeader getChartHeader () | Returns the instance of ChartHeader. | |
UndoManager getUndoManager () | Returns the undo manager for JGantt operations. | |
getDividerLocation () | Returns divider location of the split pane (between treetable and chart component). | |
setDividerLocation (int) | Sets the divider location of the split pane (between treetable and chart component). |
Here are JGantt methods you can use to build a chart:
GanttModel getModel () | Returns GanttModel instance for this JGantt object. . | |
void setModel (GanttModel) | Sets the new model for JGantt object. | |
void addColumn (GanttColumn) | Appends a column to the end of table columns. | |
GanttColumn addColumn (String, String) | Appends a column to the end of table columns. | |
void removeColumn (GanttColumn) | Removes the column from the treetable. | |
void removeColumn (String) | Removes a column with given key from the treetable. |
The methods working with columns are implemented in GanttTreeTable and methods in JGantt simply redirect to them.
Here are JGantt methods you can use to build a chart:
void addLayer (Layer) | Adds given layer to the list of chart component layers. | |
void addLayer (Layer, int) | Adds given layer to the list of chart component layers. | |
void removeLayer (Layer) | Removes given layer from the list of chart component layers. | |
List<Layer> getLayers () | Returns the list of chart component layers. |
All of these methods are implemented in ChartComponent and methods in JGantt simply redirect to them.
JGantt has built-in mouse support, so you don't need to work with mouse listeners. Use these methods instead:
void doubleClicked (GanttNode) | Invoked when user double clicked on the node. In this implementation does nothing. Typically, you should display properties dialog for node's user object. | |
List<Action> getPopupActions (List<GanttNode>) | Returns a list of actions for selected nodes. Invoked when user right clicks on the node(s) in treetable. In this implementation does nothing and returns null, you must override it to give it some functionality. |
Method doubleClicked() is invoked from treetable and also from gantt chart component. The getPopupActions() is treetable method only. If you return a non-null list, the popup menu is displayed.
The JGantt components (treetable columns and actions) intense use resource bundle technique. These methods of JGantt are about resource bundles:
String getResourceBundleName () | Returns the name of the resource bundle. | |
void setResourceBundleName (String) | Sets the name of resource bundle. This name must according to java.util.ResourceBundle specification. Resource bundle is then used to construct treetable columns and gantt actions. |
The main class for these purposes is eu.beesoft.gaia.util.Language. In the Swing environment is a singleton (but it has a public constructor, so you can create as many instances as you need in server environment). The singleton is accessible via method
Language.getInstance ();
which returns last created instance of Language. Using Language has big advantage when you change application's Locale. Setting this into Language provides for all LanguageListeners notification to easy reloading texts from resource bundles.
When you take a look at Language API documentation, you can see method getText() with first argument either a resource bundle name or some object. These methods are used from JGantt and its subcomponents.
JGantt is protected by the Abeona protection system.
It works without any license, but 10 minutes after JGantt was created it displays a warning message and stops to paint itself.
So if you want to develop an application, which will work more than 10 minutes, you need purchase the license from BeeSoft. License is plain properties file protected by digital signature and here are methods to tell JGantt about license:
License setLicense (InputStream) | Loads license from given licenseStream. This is a key method of library protection system. | |
License getLicense () | Returns instance of valid License or null. |
The first method has an input stream from license file as argument, and returns newly created License instance. You don't need to work with this object, just check for non-null return value. If it is null, you have some problem with that file.
When you will deploy your application based on the JGantt at your customer (or you will ship it), your product must contain libraries from our JGantt lib directory these JAR files:
and also license file you obtain when you purchase JGantt.
No other files are required.