Layer Factory
The layer container delegates the creation of layers to a layer factory, which needs to implement the ILayerFactory interface. A default factory is included and will be sufficient for most applications. However, there are reasons why an application might choose to provide its own factory: to have a single point in the application where layers get configured, to use subclasses of the built-in layers or to use custom layers.
The following steps need to be taken to implement and use a custom layer factory that creates a custom layer.
- Implement the ILayerFactory interface or subclass DefaultLayerFactory
- Implement the IComponentFactory interface or subclass DefaultComponentFactory
- Create a Gantt chart model that adds one or more custom layers
- Create your Gantt chart using the custom component factory
/**
* Copyright 2006, 2007
* Dirk Lemmermann Software & Consulting
* http://www.dlsc.com
*/
package com.dlsc.flexgantt.manual;
import com.dlsc.flexgantt.model.gantt.ILayer;
import com.dlsc.flexgantt.swing.layer.AbstractCustomLayer;
import com.dlsc.flexgantt.swing.layer.DefaultLayerFactory;
import com.dlsc.flexgantt.swing.layer.LayerContainer;
/**
* A custom layer factory that gets used instead of the default layer factory so
* that a custom layer gets created when it finds a model layer named 'watermark'.
*/
public class WatermarkLayerFactory extends DefaultLayerFactory {
/*
* The singleton instance.
*/
private static WatermarkLayerFactory instance;
/**
* Private constructor as part of singleton pattern implementation.
*/
private WatermarkLayerFactory() {
}
public static synchronized WatermarkLayerFactory getInstance() {
if (instance == null) {
instance = new WatermarkLayerFactory();
}
return instance;
}
/**
* The default implementation of the factory method for creating custom
* layers does nothing. In order to add custom layers it is necessary to
* create a custom factory and then return custom layer implementations
* whenever a model layer's 'custom layer' flag indicates that the layer
* requires it.
*/
@Override
public AbstractCustomLayer createCustomLayer(LayerContainer lc, ILayer layer) {
if (layer.getObjectName().equals("watermark")) {
return new WatermarkLayer(lc);
} else {
return super.createCustomLayer(lc, layer);
}
}
}
The following code is the implementation of the custom watermark layer.
/**
* Copyright 2006, 2007
* Dirk Lemmermann Software & Consulting
* http://www.dlsc.com
*/
package com.dlsc.flexgantt.manual;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.ImageIcon;
import com.dlsc.flexgantt.swing.layer.AbstractCustomLayer;
import com.dlsc.flexgantt.swing.layer.LayerContainer;
/**
* The watermark layer is a custom layer implementation. It will be created and
* added to a layer container if one of the model layers is a custom layer and
* the layer's name equals 'watermark'.
*
* @author Dirk Lemmermann
*/
public class WatermarkLayer extends AbstractCustomLayer {
/*
* Stores the texture paint that will be drawn as tiles in the background
* of the layer (container).
*/
private TexturePaint texturePaint;
/**
* Constructs a new watermark layer.
*
* @param lc the layer container to which the layer will belong
*/
public WatermarkLayer(LayerContainer lc) {
super("Watermark", lc);
//
// Load an image and create a texture paint
// object with it. This paint object can then
// be used in the paintLayer() method to fill
// the background with the watermark image.
//
URL url = getClass().getResource("watermark.png");
ImageIcon icon = new ImageIcon(url);
Image texture = icon.getImage();
BufferedImage buffer = new BufferedImage(texture
.getWidth(layerContainer), texture
.getHeight(layerContainer), BufferedImage.TYPE_INT_RGB);
Graphics2D bg = buffer.createGraphics();
bg.drawImage(texture, 0, 0, layerContainer);
texturePaint = new TexturePaint(buffer, new Rectangle(0, 0, buffer
.getWidth(), buffer.getHeight()));
}
protected void paintLayer(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Rectangle clip = g.getClipBounds();
g2d.setPaint(texturePaint);
g2d.fillRect(clip.x, clip.y, clip.width, clip.height);
}
}
A Gantt chart model that wants the watermark layer to be shown then needs to add a custom model layer with the name 'watermark'.
/**
* Copyright 2006, 2007
* Dirk Lemmermann Software & Consulting
* http://www.dlsc.com
*/
package com.dlsc.flexgantt.manual;
import com.dlsc.flexgantt.model.gantt.DefaultGanttChartModel;
import com.dlsc.flexgantt.model.gantt.DefaultGanttChartNode;
import com.dlsc.flexgantt.model.gantt.Layer;
/**
* A specialization of the default Gantt chart model. It adds a custom layer
* named 'watermark'. This model needs to get used in combination with a layer
* factory that knows how to create a watermark layer.
*
* @author Dirk Lemmermann
*/
@SuppressWarnings("serial")
public class WatermarkGanttChartModel extends DefaultGanttChartModel {
/**
* Constructs a new Gantt chart model.
*/
@SuppressWarnings("unchecked")
public WatermarkGanttChartModel() {
super(new DefaultGanttChartNode());
Layer layer = new Layer("watermark");
layer.setCustomLayer(true);
addLayer(layer);
}
}
The last thing needed is a component factory that creates a layer container with the watermark layer factory. This company factory then needs to be passed to the constructor of the Gantt chart.
/**
* Copyright 2006, 2007
* Dirk Lemmermann Software & Consulting
* http://www.dlsc.com
*/
package com.dlsc.flexgantt.manual;
import com.dlsc.flexgantt.model.gantt.IGanttChartModel;
import com.dlsc.flexgantt.swing.AbstractGanttChart;
import com.dlsc.flexgantt.swing.DefaultComponentFactory;
import com.dlsc.flexgantt.swing.layer.LayerContainer;
import com.dlsc.flexgantt.swing.treetable.TreeTable;
public class WatermarkComponentFactory extends DefaultComponentFactory {
/**
* Creates a layer container that uses the watermark layer factory.
*/
@Override
public LayerContainer createLayerContainer(AbstractGanttChart gc,
TreeTable table, IGanttChartModel model) {
return new LayerContainer(gc, model, table, WatermarkLayerFactory
.getInstance());
}
}