NetPlan -> Gantt

thobaben_diagram
Harald Wolff 2015-08-12 22:27:20 +02:00
parent 0d6222bad9
commit 1a7e8c35c2
15 changed files with 820 additions and 457 deletions

View File

@ -1,11 +1,11 @@
package org.hwo.ui.netplan;
package org.hwo.ui.gantt;
import java.util.LinkedList;
import java.util.List;
import org.hwo.datetime.DateTime;
public class BaseNetPlanObject implements INetPlanObject {
public class BaseGanttObject implements IGanttObject {
private DateTime startTime,
endTime;
@ -13,12 +13,12 @@ public class BaseNetPlanObject implements INetPlanObject {
private String label,
detailedLabel;
List<INetPlanObject> dependencies;
List<INetPlanResource> resources;
List<IGanttObject> dependencies;
List<IGanttResource> resources;
public BaseNetPlanObject() {
dependencies = new LinkedList<INetPlanObject>();
resources = new LinkedList<INetPlanResource>();
public BaseGanttObject() {
dependencies = new LinkedList<IGanttObject>();
resources = new LinkedList<IGanttResource>();
}
@Override
@ -49,42 +49,49 @@ public class BaseNetPlanObject implements INetPlanObject {
}
@Override
public INetPlanObject[] getDependencies() {
return this.dependencies.toArray(new INetPlanObject[0]);
public IGanttObject[] getDependencies() {
return this.dependencies.toArray(new IGanttObject[0]);
}
@Override
public void addDependency(INetPlanObject depend) {
public void addDependency(IGanttObject depend) {
if (!this.dependencies.contains(depend))
this.dependencies.add(depend);
}
@Override
public void removeDependency(INetPlanObject depend) {
public void removeDependency(IGanttObject depend) {
this.dependencies.remove(depend);
}
@Override
public INetPlanResource[] getResources() {
return this.resources.toArray(new INetPlanResource[0]);
public IGanttResource[] getResources() {
return this.resources.toArray(new IGanttResource[0]);
}
@Override
public void addResource(INetPlanResource resource) {
public void addResource(IGanttResource resource) {
if (!this.resources.contains(resource))
this.resources.add(resource);
}
@Override
public void removeResource(INetPlanResource resource) {
public void removeResource(IGanttResource resource) {
this.resources.remove(resource);
}
@Override
public void replaceResource(IGanttResource oldResource, IGanttResource newResource) {
addResource(newResource);
removeResource(oldResource);
}
@Override
public String getDetailedLabel() {
// TODO Auto-generated method stub
return null;
}public void setDetailedLabel(String detailedLabel) {
return this.detailedLabel;
}
public void setDetailedLabel(String detailedLabel) {
this.detailedLabel = detailedLabel;
}
public String getShortLabel() {
return label;
}
@ -92,5 +99,12 @@ public class BaseNetPlanObject implements INetPlanObject {
this.label = label;
}
@Override
public void addNotify(JGantt gantt) {
}
@Override
public void removeNotify(JGantt gantt) {
}
}

View File

@ -0,0 +1,85 @@
package org.hwo.ui.gantt;
import org.hwo.datetime.DateTime;
public class BaseGanttResource implements IGanttResource {
private String shortLabel;
private String detailedLabel;
private int maxParallelUsage;
private ResourceAvailability resourceAvailability;
public BaseGanttResource(String shortLabel,String detailedLabel) {
this.shortLabel = shortLabel;
this.detailedLabel = detailedLabel;
this.maxParallelUsage = 1;
}
@Override
public String getLabel() {
return this.shortLabel;
}
@Override
public String getDetailedLabel() {
return this.detailedLabel;
}
public void setResourceAvailability(
ResourceAvailability resourceAvailability) {
this.resourceAvailability = resourceAvailability;
}
@Override
public ResourceAvailability getAvailability() {
return resourceAvailability;
}
@Override
public ResourceAvailability getAvailability(DateTime fromDateTime) {
return resourceAvailability.findAvailableAfter(fromDateTime);
}
@Override
public int getMaxParallelUsage() {
return this.maxParallelUsage;
}
public void setMaxParallelUsage(int maxParallelUsage) {
this.maxParallelUsage = maxParallelUsage;
}
public DateTime calculateUsageTime(DateTime begin,int seconds){
ResourceAvailability ra = getAvailability(begin);
DateTime dt = new DateTime(begin);
if (ra != null && dt.isBefore(ra.getStartTime())){
dt = ra.getStartTime();
}
while (ra != null){
int availSeconds = ra.getSeconds(dt);
//System.err.println(String.format("RES: %s needs %d seconds from %s. Has %d seconds.", shortLabel, seconds, dt.toString(), availSeconds));
if (availSeconds >= seconds){ // Soll kann erfüllt werden...
DateTime endTime = new DateTime(dt);
endTime.addSeconds(seconds);
return endTime;
}
seconds -= availSeconds;
ra = ra.getNext();
dt = ra.getStartTime();
}
return null;
}
}

View File

@ -0,0 +1,5 @@
package org.hwo.ui.gantt;
public class GanttException extends Exception {
}

View File

@ -0,0 +1,9 @@
package org.hwo.ui.gantt;
import org.hwo.datetime.DateTime;
public interface GanttMouseEventListener {
public void mouseClick(JGantt gantt,IGanttResource ganttResource,DateTime dateTime,IGanttObject ganttObject);
}

View File

@ -0,0 +1,69 @@
package org.hwo.ui.gantt;
import org.hwo.datetime.DateTime;
public class GanttResolver {
JGantt gantt;
public GanttResolver(JGantt gantt) {
this.gantt = gantt;
}
/* Optimieren links: (Einsetzen)
*
* Schneidendes Objekt bei startTime finden, startTime korrigieren, wiederholen für abhängige in gleicher resource
*
*
*/
public void leftOptimize(IGanttObject object){
for (IGanttResource resource: object.getResources()){
IGanttObject o = gantt.findObjectAt(resource, object.getStartTime());
if (o != null){
DateTime dt = o.getEndTime();
dt.addSeconds(1);
System.err.println(String.format("Resolver: Move Start Time of %s from %s to %s after end of %s",object.toString(),object.getStartTime(),dt.toString(),o.toString()));
object.setStartTime(dt);
for (IGanttObject dobj: gantt.findDependedObjects(o, resource)){
leftOptimize(dobj);
}
}
}
}
/* Optimieren rechts: (Verschieben)
*
* Objekte mit StartTime innerhalb finden, und nach rechts verschieben
*
*
*/
public void rightOptimize(IGanttObject object){
for (IGanttResource resource: object.getResources()){
IGanttObject o = gantt.findObjectAt(resource, object.getStartTime());
if (o != null){
DateTime dt = o.getEndTime();
dt.addSeconds(1);
System.err.println(String.format("Resolver: Move Start Time of %s from %s to %s after end of %s",object.toString(),object.getStartTime(),dt.toString(),o.toString()));
object.setStartTime(dt);
for (IGanttObject dobj: gantt.findDependedObjects(o, resource)){
leftOptimize(dobj);
}
}
}
}
}

View File

@ -0,0 +1,10 @@
package org.hwo.ui.gantt;
import java.awt.Graphics2D;
import java.awt.Rectangle;
public interface IGanttDrawable {
void paint(Graphics2D g,Rectangle rect);
}

View File

@ -1,8 +1,8 @@
package org.hwo.ui.netplan;
package org.hwo.ui.gantt;
import org.hwo.datetime.DateTime;
public interface INetPlanObject {
public interface IGanttObject {
boolean canMove(); // Startzeitpunkt kann verändert werden
boolean canStretch(); // Dauer kann verändert werden
@ -21,17 +21,21 @@ public interface INetPlanObject {
String getDetailedLabel();
/* Abhängige Objekte */
INetPlanObject[] getDependencies();
IGanttObject[] getDependencies();
void addDependency(INetPlanObject depend);
void removeDependency(INetPlanObject depend);
void addDependency(IGanttObject depend);
void removeDependency(IGanttObject depend);
/* Notwendige Resourcen */
INetPlanResource[] getResources();
void addResource(INetPlanResource resource);
void removeResource(INetPlanResource resource);
IGanttResource[] getResources();
void addResource(IGanttResource resource);
void removeResource(IGanttResource resource);
void replaceResource(IGanttResource oldResource,IGanttResource newResource);
void addNotify(JGantt gantt);
void removeNotify(JGantt gantt);
}

View File

@ -1,8 +1,8 @@
package org.hwo.ui.netplan;
package org.hwo.ui.gantt;
import org.hwo.datetime.DateTime;
public interface INetPlanResource {
public interface IGanttResource {
String getLabel();
String getDetailedLabel();

View File

@ -0,0 +1,531 @@
package org.hwo.ui.gantt;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
import org.hwo.datetime.Date;
import org.hwo.datetime.DateTime;
import org.hwo.datetime.TimeOfDay;
public class JGantt extends JComponent {
GanttResolver resolver;
List<IGanttObject> ganttObjects;
List<IGanttResource> ganttResources;
List<IGanttDrawable> ganttDrawables;
Date firstDate;
int days;
int zoom;
boolean timeVisible;
boolean relevantChange;
JViewport topPane,
leftPane;
IGanttObject selectedObject;
List<GanttMouseEventListener> ganttMouseEventListener;
public JGantt() {
ganttMouseEventListener = new ArrayList<GanttMouseEventListener>();
resolver = new GanttResolver(this);
ganttObjects = new ArrayList<IGanttObject>();
ganttResources = new ArrayList<IGanttResource>();
ganttDrawables = new ArrayList<IGanttDrawable>();
firstDate = new Date();
days = 31;
zoom = 1;
timeVisible = false;
relevantChange = true;
setDoubleBuffered(true);
topPane = new JViewport();
topPane.add(new TopPane());
leftPane = new JViewport();
leftPane.add(new Leftpane());
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
switch (e.getButton()){
case MouseEvent.BUTTON1:
if (e.getClickCount()==1){
DateTime dt = getDateTimeAt(e.getPoint().x);
IGanttResource r = getResourceAt(e.getPoint().y);
IGanttObject o = null;
if (r != null)
o = getObjectAt(r, dt);
fireGanttMouseClick(JGantt.this, r, dt, o);
}
break;
}
}
});
addGanttMouseListener(new GanttMouseEventListener() {
@Override
public void mouseClick(JGantt gantt, IGanttResource ganttResource,
DateTime dateTime, IGanttObject ganttObject) {
setSelectedObject(ganttObject);
}
});
}
public void addGanttMouseListener(GanttMouseEventListener listener){
ganttMouseEventListener.add(listener);
}
public void removeGanttMouseListener(GanttMouseEventListener listener){
ganttMouseEventListener.add(listener);
}
public void fireGanttMouseClick(JGantt gantt,IGanttResource ganttResource,DateTime dateTime,IGanttObject ganttObject){
for (GanttMouseEventListener listener: ganttMouseEventListener){
listener.mouseClick(this, ganttResource, dateTime, ganttObject);
}
};
public int getZoom() {
return zoom;
}
public void setZoom(int zoom) {
this.zoom = zoom;
relevantChange = true;
repaint();
}
public void addGanttObject(IGanttObject object){
if (!this.ganttObjects.contains(object)){
this.ganttObjects.add(object);
if (IGanttDrawable.class.isInstance(object)){
ganttDrawables.add((IGanttDrawable)object);
}
resolver.leftOptimize(object);
object.addNotify(this);
}
for (IGanttResource res: object.getResources()){
addGanttResource(res);
}
repaint();
}
public void removeGanttObject(IGanttObject object){
if (this.ganttObjects.contains(object)){
this.ganttObjects.remove(object);
if (this.ganttDrawables.contains(object)){
this.ganttDrawables.remove(object);
}
object.removeNotify(this);
}
repaint();
}
public IGanttObject[] getGanttObjects(){
return this.ganttObjects.toArray(new IGanttObject[0]);
}
public void addGanttResource(IGanttResource resource){
if (!this.ganttResources.contains(resource))
this.ganttResources.add(resource);
}
public void removeGanttResource(IGanttResource resource){
this.ganttResources.remove(resource);
}
public IGanttResource[] getGanttResources(){
return this.ganttResources.toArray(new IGanttResource[0]);
}
public Date getFirstDate() {
return new Date(firstDate);
}
public void setFirstDate(Date firstDate) {
this.firstDate = new Date(firstDate);
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public void setTimeVisible(boolean timeVisible) {
this.timeVisible = timeVisible;
}
public boolean isTimeVisible(){
return this.timeVisible;
}
public IGanttObject getSelectedObject() {
return selectedObject;
}
public void setSelectedObject(IGanttObject selectedObject) {
this.selectedObject = selectedObject;
repaint();
}
public IGanttObject findObjectAt(IGanttResource resource,DateTime dateTime){
System.err.println(String.format("JGantt: Find Object on Resource %s at %s",resource.toString(),dateTime.toString()));
for (IGanttObject o: ganttObjects){
if (o.getStartTime().isBefore(dateTime) && o.getEndTime().isAfter(dateTime) && Arrays.asList(o.getResources()).contains(resource)){
return o;
}
}
return null;
}
public IGanttResource getResourceAt(int y){
if (y > minHeight)
return null;
IGanttResource res = ganttResources.get((y-6) / lineHeight);
return res;
}
public DateTime getDateTimeAt(int x){
Date date = new Date(firstDate);
date.addDays(x / dayColumnWidth);
TimeOfDay time = new TimeOfDay( TimeOfDay.SECONDSPERDAY * (x % dayColumnWidth) / dayColumnWidth );
return new DateTime(date, time);
}
private IGanttObject getObjectAt(IGanttResource resource,DateTime dateTime){
IGanttObject o = findObjectAt(resource,dateTime);
return o;
}
private IGanttObject[] findParallelObjects(IGanttObject object,IGanttResource resource){
LinkedList<IGanttObject> rl = new LinkedList<IGanttObject>();
/* for (IGanttObject o:ganttObjects)
if (Arrays.asList(o.getResources()).contains(o)
*/
return rl.toArray(new IGanttObject[0]);
}
public IGanttObject[] findDependedObjects(IGanttObject object){
LinkedList<IGanttObject> rl = new LinkedList<IGanttObject>();
for (IGanttObject o:ganttObjects)
if (Arrays.asList(o.getDependencies()).contains(object))
rl.add(o);
return rl.toArray(new IGanttObject[0]);
}
public IGanttObject[] findDependedObjects(IGanttObject object,IGanttResource resource){
LinkedList<IGanttObject> rl = new LinkedList<IGanttObject>();
for (IGanttObject o:ganttObjects)
if (Arrays.asList(o.getDependencies()).contains(object) && Arrays.asList(o.getResources()).contains(resource))
rl.add(o);
return rl.toArray(new IGanttObject[0]);
}
/*********
* Layout variables...
*/
int resourceLines;
int lineHeight,
headerLineHeight;
int resourceBaseHeight;
int leftColumnWidth;
int dayColumnWidth;
int minHeight;
int minWidth;
void paintObject(Graphics2D g,Rectangle rect,IGanttObject object){
if (ganttDrawables.contains(object)){
((IGanttDrawable)object).paint(g, rect);
} else {
if (selectedObject == object)
g.setColor(Color.RED);
else
g.setColor(new Color(255,192,192));
g.fillRoundRect(rect.x,rect.y,rect.width,rect.height, 8, 8);
g.drawRoundRect(rect.x,rect.y,rect.width,rect.height, 8, 8);
if (selectedObject == object)
g.setColor(Color.WHITE);
else
g.setColor(Color.BLACK);
g.drawString(object.getShortLabel(), rect.x + 4, rect.y + lineHeight - 8);
}
}
@Override
public void paint(Graphics _g) {
Graphics2D g = (Graphics2D)_g;
int n;
updateSizes();
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
// g.drawLine(leftColumnWidth, 0, leftColumnWidth, getHeight());
Date lastDate = getFirstDate();
lastDate.addDays(days-1);
for (n = 0; n < days; n++){
int l = ((n) * dayColumnWidth);
g.drawLine(((n+1) * dayColumnWidth), 0, ((n+1) * dayColumnWidth), minHeight);
}
n = 0;
for (IGanttResource resource: this.ganttResources){
n += resource.getMaxParallelUsage();
g.setColor(Color.LIGHT_GRAY);
g.drawLine(0, 4 + (n * lineHeight), minWidth, 4 + (n * lineHeight));
}
for (IGanttObject object: ganttObjects){
if (object.getEndTime().getDate().isBefore(firstDate) || object.getStartTime().getDate().isAfter(lastDate))
continue;
int pos = 2 + (object.getStartTime().getDate().daysAfter(firstDate) * dayColumnWidth);
int width = (object.getEndTime().getDate().daysAfter(object.getStartTime().getDate()) * dayColumnWidth) + dayColumnWidth - 4;
int posOffset = dayColumnWidth * object.getStartTime().getTime().getSecondsOfTheDay() / TimeOfDay.SECONDSPERDAY;
pos += posOffset;
width -= posOffset + dayColumnWidth * (TimeOfDay.SECONDSPERDAY - object.getEndTime().getTime().getSecondsOfTheDay()) / TimeOfDay.SECONDSPERDAY;
for (IGanttResource res: object.getResources()){
int vpos = 6 + (ganttResources.indexOf(res) * lineHeight);
Rectangle rect = new Rectangle(pos, vpos, width, lineHeight - 4);
paintObject(g, rect, object);
}
}
}
private void updateSizes(){
if (!relevantChange)
return;
Graphics2D g = (Graphics2D)getGraphics();
FontMetrics fm = getFontMetrics(getFont());
//lineHeight = (int)(getFont().getSize2D()*72) + 4;
lineHeight = getFont().getSize() + 8;
headerLineHeight = getFont().getSize() + 2;
resourceBaseHeight = headerLineHeight * 4;
if (isTimeVisible())
dayColumnWidth = 96;
else
dayColumnWidth = ((int)fm.getStringBounds("WWW", g).getWidth()) + 10;
dayColumnWidth *= zoom;
resourceLines = 0;
leftColumnWidth = 0;
for (IGanttResource resource: this.ganttResources){
int lw = (int)fm.getStringBounds(resource.getLabel(), g).getWidth();
if (lw > leftColumnWidth)
leftColumnWidth = lw;
resourceLines += resource.getMaxParallelUsage();
}
leftColumnWidth += 15;
minHeight = 4 + (lineHeight * resourceLines);
minWidth = ( dayColumnWidth * days );
setPreferredSize(new Dimension(minWidth, minHeight));
leftPane.setSize(new Dimension(leftColumnWidth,minHeight));
topPane.setSize(new Dimension(minWidth, resourceBaseHeight));
relevantChange = false;
}
public class TopPane extends JComponent {
@Override
public Dimension getPreferredSize() {
return new Dimension(minWidth,resourceBaseHeight);
}
@Override
public void paint(Graphics _g) {
Graphics2D g = (Graphics2D)_g;
int n;
int ayear = 0;
int aweek = 0;
updateSizes();
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
// g.drawLine(leftColumnWidth, 0, leftColumnWidth, getHeight());
g.drawLine(0, resourceBaseHeight, getWidth(), resourceBaseHeight);
g.drawLine(0, headerLineHeight, minWidth, headerLineHeight);
g.drawLine(0, 2 * headerLineHeight, minWidth, 2 * headerLineHeight);
Date date = getFirstDate();
for (n = 0; n < days; n++){
int l = ((n) * dayColumnWidth);
g.drawLine(((n+1) * dayColumnWidth), resourceBaseHeight - (2 * headerLineHeight), ((n+1) * dayColumnWidth), resourceBaseHeight * 4);
g.drawString(String.format("%02d.%02d", date.getDay(),date.getMonth()), l + 2, resourceBaseHeight - headerLineHeight - 2);
g.drawString(String.format("%s", date.weekdays[date.getWeekDay()]), l + 2, resourceBaseHeight - 2);
if (ayear != date.getYear()){
g.drawString(String.format("%02d", date.getYear()), l + 2, resourceBaseHeight - (3 * headerLineHeight) - 2);
if (ayear != 0){
g.drawLine(((n) * dayColumnWidth), resourceBaseHeight - (4 * headerLineHeight), ((n) * dayColumnWidth), resourceBaseHeight - (3 * headerLineHeight));
}
ayear = date.getYear();
}
int w = date.getWeek();
if (aweek != w){
g.drawString(String.format("%02d", w), l + 2, resourceBaseHeight - (2 * headerLineHeight) - 2);
if (aweek != 0){
g.drawLine(((n) * dayColumnWidth), resourceBaseHeight - (3 * headerLineHeight), ((n) * dayColumnWidth), resourceBaseHeight - (2 * headerLineHeight));
}
aweek = w;
}
date.addDays(1);
}
}
}
public class Leftpane extends JComponent {
public Leftpane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(leftColumnWidth,minHeight);
}
@Override
public void paint(Graphics _g) {
Graphics2D g = (Graphics2D)_g;
int n;
updateSizes();
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
g.drawLine(leftColumnWidth - 1, 0, leftColumnWidth - 1, getHeight());
// g.drawLine(0, 0, getWidth(), 0);
n = 0;
for (IGanttResource resource: ganttResources){
n += resource.getMaxParallelUsage();
g.setColor(Color.BLACK);
g.drawString(resource.getLabel(), 2, 1 + (n * lineHeight));
g.setColor(Color.LIGHT_GRAY);
g.drawLine(0, 4 + (n * lineHeight), getWidth(), 4 + (n * lineHeight));
}
}
}
@Override
public void addNotify() {
super.addNotify();
if (JViewport.class.isInstance(getParent()) && JScrollPane.class.isInstance(getParent().getParent()))
{
JScrollPane sp = (JScrollPane)getParent().getParent();
sp.setColumnHeader(topPane);
sp.setRowHeader(leftPane);
}
}
@Override
public void removeNotify() {
super.removeNotify();
}
}

View File

@ -1,4 +1,4 @@
package org.hwo.ui.netplan;
package org.hwo.ui.gantt;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
@ -26,17 +26,17 @@ import org.hwo.datetime.TimeOfDay;
import java.awt.Color;
import java.awt.Font;
public class JNetPlanTestDialog extends JDialog {
public class JGanttTestDialog extends JDialog {
private final JPanel contentPanel = new JPanel();
private JNetPlan netPlan;
private JGantt netPlan;
/**
* Create the dialog.
*/
public JNetPlanTestDialog() {
public JGanttTestDialog() {
setModal(true);
setTitle("JNetPlan Test Dialog");
setTitle("JGantt Test Dialog");
setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setBounds(100, 100, 975, 481);
@ -59,8 +59,8 @@ public class JNetPlanTestDialog extends JDialog {
gbc_scrollPane.gridy = 0;
contentPanel.add(scrollPane, gbc_scrollPane);
{
netPlan = new JNetPlan();
netPlan.setDays(45);
netPlan = new JGantt();
netPlan.setDays(230);
netPlan.setFont(new Font("DejaVu Sans", Font.PLAIN, 16));
netPlan.setBackground(Color.WHITE);
scrollPane.setViewportView(netPlan);
@ -94,8 +94,8 @@ public class JNetPlanTestDialog extends JDialog {
private void initialize(){
for (int i=0;i<10;i++){
BaseNetPlanResource res = new BaseNetPlanResource(String.format("Resource %d",i), "-");
netPlan.addNetPlanResource(res);
BaseGanttResource res = new BaseGanttResource(String.format("Resource %d",i), "-");
netPlan.addGanttResource(res);
}
Date d = new Date();
@ -105,17 +105,38 @@ public class JNetPlanTestDialog extends JDialog {
Date d2 = new Date(d);
d2.addDays(4);
BaseNetPlanObject o = new BaseNetPlanObject();
BaseGanttObject o = new BaseGanttObject();
o.setStartTime(new DateTime(d, new TimeOfDay()));
o.setEndTime(new DateTime(d2, TimeOfDay.beforeMidnight()));
o.setEndTime(new DateTime(d2, TimeOfDay.beforeMidnight()));
o.setShortLabel("Eine Aufgabe");
o.addResource(netPlan.getNetPlanResources()[0]);
o.addResource(netPlan.getNetPlanResources()[3]);
o.addResource(netPlan.getNetPlanResources()[7]);
netPlan.addNetPlanObject(o);
o.addResource(netPlan.getGanttResources()[0]);
o.addResource(netPlan.getGanttResources()[3]);
o.addResource(netPlan.getGanttResources()[7]);
netPlan.addGanttObject(o);
d.addDays(2);
d2.addDays(6);
o = new BaseGanttObject();
o.setStartTime(new DateTime(d, new TimeOfDay()));
o.setEndTime(new DateTime(d2, TimeOfDay.beforeMidnight()));
o.setShortLabel("Eine Aufgabe");
o.addResource(netPlan.getGanttResources()[1]);
o.addResource(netPlan.getGanttResources()[2]);
netPlan.addGanttObject(o);
d.addDays(3);
d2.addDays(-2);
o = new BaseGanttObject();
o.setStartTime(new DateTime(d, new TimeOfDay()));
o.setEndTime(new DateTime(d2, TimeOfDay.beforeMidnight()));
o.setShortLabel("Eine Aufgabe");
o.addResource(netPlan.getGanttResources()[0]);
o.addResource(netPlan.getGanttResources()[7]);
netPlan.addGanttObject(o);
//netPlan.setSelectedObject(o);
}

View File

@ -1,4 +1,4 @@
package org.hwo.ui.netplan;
package org.hwo.ui.gantt;
import org.hwo.datetime.Date;
import org.hwo.datetime.DateTime;
@ -142,6 +142,13 @@ public class ResourceAvailability {
return null;
}
public int getSeconds(){
return startTime.secondsBefore(endTime);
}
public int getSeconds(DateTime from){
return from.secondsBefore(endTime);
}
@Override
public String toString() {
@ -149,7 +156,7 @@ public class ResourceAvailability {
ResourceAvailability ra = this;
while (ra != null){
sb.append(String.format("%s %s - %s %s\n",Date.weekdays[ra.getStartTime().getDate().getWeekDay()],ra.getStartTime().toString(),Date.weekdays[ra.getEndTime().getDate().getWeekDay()],ra.getEndTime().toString()));
sb.append(String.format("%s %s - %s %s (%d seconds)\n",Date.weekdays[ra.getStartTime().getDate().getWeekDay()],ra.getStartTime().toString(),Date.weekdays[ra.getEndTime().getDate().getWeekDay()],ra.getEndTime().toString(),ra.getSeconds()));
ra = ra.getNext();
}
@ -161,19 +168,27 @@ public class ResourceAvailability {
return generateWeekly(from, days, available,new TimeOfDay(),TimeOfDay.beforeMidnight());
}
public static ResourceAvailability generateWeekly(Date from,int days,boolean[] available,TimeOfDay timeStart,TimeOfDay timeEnd){
Date to;
from.addDays(-1);
ResourceAvailability head = new ResourceAvailability(new DateTime(from, new TimeOfDay()));
head.setEndTime(new DateTime(from, TimeOfDay.beforeMidnight()));
for (int i=0;i<days;i++){
from.addDays(1);
from.addDays(1);
for (int i=0;i<days;i++){
DateTime aStart = new DateTime(from, timeStart);
DateTime aEnd = new DateTime(from, timeEnd);
to = new Date(from);
if (timeEnd.isEarlierThan(timeStart))
to.addDays(1);
DateTime aEnd = new DateTime(to, timeEnd);
if (available[from.getWeekDay()])
head.makeAvailable(aStart, aEnd, Date.weekdays[from.getWeekDay()]);
from.addDays(1);
}
return head.getNext();
}

View File

@ -1,4 +1,4 @@
package org.hwo.ui.netplan;
package org.hwo.ui.gantt;
import java.io.Console;
@ -10,7 +10,7 @@ import org.hwo.datetime.Date;
import org.hwo.datetime.DateTime;
import org.hwo.datetime.TimeOfDay;
public class TestNetPlan {
public class TestGantt {
public static void main(String[] args) {
@ -24,7 +24,7 @@ public class TestNetPlan {
System.err.println(ra.toString());
JNetPlanTestDialog dialog = new JNetPlanTestDialog();
JGanttTestDialog dialog = new JGanttTestDialog();
dialog.setVisible(true);

View File

@ -1,49 +0,0 @@
package org.hwo.ui.netplan;
import org.hwo.datetime.DateTime;
public class BaseNetPlanResource implements INetPlanResource {
private String shortLabel;
private String detailedLabel;
private int maxParallelUsage;
private ResourceAvailability resourceAvailability;
public BaseNetPlanResource(String shortLabel,String detailedLabel) {
this.shortLabel = shortLabel;
this.detailedLabel = detailedLabel;
this.maxParallelUsage = 1;
}
@Override
public String getLabel() {
return this.shortLabel;
}
@Override
public String getDetailedLabel() {
return this.detailedLabel;
}
@Override
public ResourceAvailability getAvailability() {
return resourceAvailability;
}
@Override
public ResourceAvailability getAvailability(DateTime fromDateTime) {
return resourceAvailability.findAvailableAfter(fromDateTime);
}
@Override
public int getMaxParallelUsage() {
return this.maxParallelUsage;
}
public void setMaxParallelUsage(int maxParallelUsage) {
this.maxParallelUsage = maxParallelUsage;
}
}

View File

@ -1,346 +0,0 @@
package org.hwo.ui.netplan;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
import org.hwo.datetime.Date;
public class JNetPlan extends JComponent {
List<INetPlanObject> netPlanObjects;
List<INetPlanResource> netPlanResources;
Date firstDate;
int days;
boolean timeVisible;
boolean relevantChange;
JViewport topPane,
leftPane;
public JNetPlan() {
netPlanObjects = new ArrayList<INetPlanObject>();
netPlanResources = new ArrayList<INetPlanResource>();
firstDate = new Date();
days = 31;
timeVisible = false;
relevantChange = true;
setDoubleBuffered(true);
topPane = new JViewport();
topPane.add(new TopPane());
leftPane = new JViewport();
leftPane.add(new Leftpane());
}
public void addNetPlanObject(INetPlanObject object){
if (!this.netPlanObjects.contains(object))
this.netPlanObjects.add(object);
for (INetPlanResource res: object.getResources()){
addNetPlanResource(res);
}
}
public void removeNetPlanObject(INetPlanObject object){
this.netPlanObjects.remove(object);
}
public INetPlanObject[] getNetPlanObjects(){
return this.netPlanObjects.toArray(new INetPlanObject[0]);
}
public void addNetPlanResource(INetPlanResource resource){
if (!this.netPlanResources.contains(resource))
this.netPlanResources.add(resource);
}
public void removeNetPlanResource(INetPlanResource resource){
this.netPlanResources.remove(resource);
}
public INetPlanResource[] getNetPlanResources(){
return this.netPlanResources.toArray(new INetPlanResource[0]);
}
public Date getFirstDate() {
return new Date(firstDate);
}
public void setFirstDate(Date firstDate) {
this.firstDate = new Date(firstDate);
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public void setTimeVisible(boolean timeVisible) {
this.timeVisible = timeVisible;
}
public boolean isTimeVisible(){
return this.timeVisible;
}
/*********
* Layout variables...
*/
int resourceLines;
int lineHeight;
int resourceBaseHeight;
int leftColumnWidth;
int dayColumnWidth;
int minHeight;
int minWidth;
@Override
public void paint(Graphics _g) {
Graphics2D g = (Graphics2D)_g;
int n;
updateSizes();
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
// g.drawLine(leftColumnWidth, 0, leftColumnWidth, getHeight());
Date date = getFirstDate();
for (n = 0; n < days; n++){
int l = ((n) * dayColumnWidth);
g.drawLine(((n+1) * dayColumnWidth), 0, ((n+1) * dayColumnWidth), minHeight);
}
n = 0;
for (INetPlanResource resource: this.netPlanResources){
n += resource.getMaxParallelUsage();
g.setColor(Color.LIGHT_GRAY);
g.drawLine(0, 4 + (n * lineHeight), minWidth, 4 + (n * lineHeight));
}
for (INetPlanObject object: netPlanObjects){
int pos = 2 + (object.getStartTime().getDate().daysAfter(firstDate) * dayColumnWidth);
int width = (object.getEndTime().getDate().daysAfter(object.getStartTime().getDate()) * dayColumnWidth) + dayColumnWidth - 4;
for (INetPlanResource res: object.getResources()){
int vpos = 6 + (netPlanResources.indexOf(res) * lineHeight);
g.setColor(Color.RED);
g.fillRoundRect(pos, vpos, width, lineHeight - 4, 8, 8);
g.drawRoundRect(pos, vpos, width, lineHeight - 4, 8, 8);
g.setColor(Color.WHITE);
g.drawString(object.getShortLabel(), pos + 4, vpos + lineHeight - 8);
//System.err.println(String.format("[%d/%d] [%d/%d]",pos,vpos,width,lineHeight - 4));
}
}
}
private void updateSizes(){
if (!relevantChange)
return;
Graphics2D g = (Graphics2D)getGraphics();
FontMetrics fm = getFontMetrics(getFont());
//lineHeight = (int)(getFont().getSize2D()*72) + 4;
lineHeight = getFont().getSize() + 8;
resourceBaseHeight = lineHeight * 3;
if (isTimeVisible())
dayColumnWidth = 96;
else
dayColumnWidth = ((int)fm.getStringBounds("WWW", g).getWidth()) + 10;
resourceLines = 0;
leftColumnWidth = 0;
for (INetPlanResource resource: this.netPlanResources){
int lw = (int)fm.getStringBounds(resource.getLabel(), g).getWidth();
if (lw > leftColumnWidth)
leftColumnWidth = lw;
resourceLines += resource.getMaxParallelUsage();
}
leftColumnWidth += 5;
minHeight = 4 + (lineHeight * resourceLines);
minWidth = ( dayColumnWidth * days );
setPreferredSize(new Dimension(minWidth, minHeight));
leftPane.setSize(new Dimension(leftColumnWidth,minHeight));
topPane.setSize(new Dimension(minWidth, 4 * lineHeight));
relevantChange = false;
}
public class TopPane extends JComponent {
@Override
public Dimension getPreferredSize() {
return new Dimension(minWidth,4 * lineHeight);
}
@Override
public void paint(Graphics _g) {
Graphics2D g = (Graphics2D)_g;
int n;
updateSizes();
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
// g.drawLine(leftColumnWidth, 0, leftColumnWidth, getHeight());
g.drawLine(0, resourceBaseHeight, getWidth(), resourceBaseHeight);
Date date = getFirstDate();
for (n = 0; n < days; n++){
int l = ((n) * dayColumnWidth);
g.drawLine(((n+1) * dayColumnWidth), resourceBaseHeight - (2 * lineHeight), ((n+1) * dayColumnWidth), minHeight);
g.drawString(String.format("%d", date.getDay()), l + 2, resourceBaseHeight - lineHeight - 2);
g.drawString(String.format("%s", date.weekdays[date.getWeekDay()]), l + 2, resourceBaseHeight - 2);
date.addDays(1);
}
}
}
public class Leftpane extends JComponent {
public Leftpane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(leftColumnWidth,minHeight);
}
@Override
public void paint(Graphics _g) {
Graphics2D g = (Graphics2D)_g;
int n;
updateSizes();
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
// g.drawLine(leftColumnWidth, 0, leftColumnWidth, getHeight());
// g.drawLine(0, 0, getWidth(), 0);
n = 0;
for (INetPlanResource resource: netPlanResources){
n += resource.getMaxParallelUsage();
g.setColor(Color.BLACK);
g.drawString(resource.getLabel(), 2, 1 + (n * lineHeight));
g.setColor(Color.LIGHT_GRAY);
g.drawLine(0, 4 + (n * lineHeight), getWidth(), 4 + (n * lineHeight));
}
}
}
/*
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation, int direction) {
if (orientation == SwingConstants.HORIZONTAL)
return visibleRect.width / 2;
else
return visibleRect.height / 2;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation, int direction) {
if (orientation == SwingConstants.HORIZONTAL)
return 10;
else
return lineHeight;
}
*/
@Override
public void addNotify() {
super.addNotify();
if (JViewport.class.isInstance(getParent()) && JScrollPane.class.isInstance(getParent().getParent()))
{
JScrollPane sp = (JScrollPane)getParent().getParent();
sp.setColumnHeader(topPane);
sp.setRowHeader(leftPane);
}
}
@Override
public void removeNotify() {
super.removeNotify();
}
}

View File

@ -1,5 +0,0 @@
package org.hwo.ui.netplan;
public class NetPlanException extends Exception {
}