package org.openswing.swing.gantt.client;
import java.beans.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import org.openswing.swing.client.*;
import org.openswing.swing.gantt.java.*;
import org.openswing.swing.message.receive.java.*;
import org.openswing.swing.util.client.*;
import org.openswing.swing.util.java.*;
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Panel that contains a grid on the left side (the gantt legend) and a gantt diagram on the right.
* Each row of the gannt is defined by a GanttRowVO object, that contains the legend values for the row and a set of Appointment objects.
* When the set of Appointment objects are read, this control analyze the objects and
* split an Appointment in more than one, if the Appointment is spreaded on more days, so that each new Appointment is bound inside a day.
* After editing the gantt, the set of changed Appointments of a specified row can be retrieved
* by means of "getAppointments" method that analyzes Appointment objects: if there exists two consecutive Appointments,
* then it joins them in a unique Appointment object, so that the method returns the minimal set of objects.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
*
* <p> This file is part of OpenSwing Framework.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the (LGPL) Lesser General Public
* License as published by the Free Software Foundation;
*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author may be contacted at:
* maurocarniel@tin.it</p>
*
* @author Mauro Carniel
* @version 1.0
*/
public class GanttControl extends JPanel {
/** starting date */
private Date startDate = new Date();
/** end date */
private Date endDate = new Date();
/** rows viewed in this panel */
private ArrayList ganttRows = new ArrayList();
JSplitPane splitPane = new JSplitPane();
BorderLayout borderLayout1 = new BorderLayout();
JScrollPane scrollPane1 = new JScrollPane();
JScrollPane scrollPane2 = new JScrollPane();
Table1Model model1 = new Table1Model();
Table2Model model2 = new Table2Model();
JTable table1 = new JTable();
JTable table2 = new JTable();
/** column width; default value: 150 pixels */
private int columnWidth = 120;
/** gantt data locator */
private GanttDataLocator ganttDataLocator = null;
/** gantt parameters */
private Map ganttParameters = new HashMap();
/** flag used to show the description above the colored rectangle */
private boolean showDescription = true;
/** flag used to show the appointment duration above the colored rectangle */
private boolean showTime = true;
/** flag used to load data the first time */
private boolean firstTime = true;
/** enable deleting of appointments; default value: <code>true</code> */
private boolean enableDelete = true;
/** enable inserting of appointments; default value: <code>true</code> */
private boolean enableInsert = true;
/** enable editing of appointments; default value: <code>true</code> */
private boolean enableEdit = true;
/** list of AppointmentChangeListener objects */
private ArrayList appointmentChangeListeners = new ArrayList();
/** column sizes for the grid (legend area); colleciton of pairs: column index,width */
private Hashtable preferredSize = new Hashtable();
/** collection of columns not visible in the grid (legend area) */
private ArrayList visibility = new ArrayList();
/** flag used to specify if data loading will be automatically performed when the gantt is set to visible; default value: "true". */
private boolean autoLoadData = true;
public GanttControl() {
Calendar cal = Calendar.getInstance();
cal.set(cal.HOUR_OF_DAY,0);
cal.set(cal.MINUTE,0);
cal.set(cal.SECOND,0);
cal.set(cal.MILLISECOND,0);
startDate = cal.getTime();
cal.set(cal.MONTH,cal.get(cal.MONTH)+1);
endDate = cal.getTime();
try {
jbInit();
setRowHeight(35);
// scrollPane1.getViewport().setBackground(ClientSettings.GRID_NOT_EDITABLE_CELL_BACKGROUND);
// scrollPane2.getViewport().setBackground(ClientSettings.GRID_NOT_EDITABLE_CELL_BACKGROUND);
table1.setBackground(ClientSettings.GRID_CELL_BACKGROUND);
table2.setBackground(ClientSettings.GRID_CELL_BACKGROUND);
table1.getTableHeader().setReorderingAllowed(false);
table1.setSelectionBackground(ClientSettings.GRID_SELECTION_BACKGROUND);
table1.setSelectionForeground(ClientSettings.GRID_SELECTION_FOREGROUND);
table1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table2.setShowVerticalLines(false);
table2.setDefaultRenderer(ArrayList.class,new GanttColumnRenderer());
table2.setDefaultEditor(ArrayList.class,new GanttColumnEditor());
table2.getTableHeader().setResizingAllowed(false);
table2.getTableHeader().setReorderingAllowed(false);
table2.getColumnModel().setColumnMargin(0);
// add mouse listener to set focus to the selected cell and to show the pop-up menu
// used to fill in the whole day or remove all day appointments...
table2.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (!model2.isCellEditable(0,0))
return;
if (model2!=null &&
model2.getRowCount()>0) {
table2.setRowSelectionInterval(table2.rowAtPoint(e.getPoint()),table2.rowAtPoint(e.getPoint()));
table2.setColumnSelectionInterval(table2.columnAtPoint(e.getPoint()),table2.columnAtPoint(e.getPoint()));
table2.editCellAt(table2.rowAtPoint(e.getPoint()),table2.columnAtPoint(e.getPoint()));
}
if (model2!=null &&
model2.getRowCount()>0 &&
table2.getSelectedRow()!=-1 &&
table2.getSelectedColumn()!=-1 &&
SwingUtilities.isRightMouseButton(e)) {
JPopupMenu p = new JPopupMenu();
if (enableInsert) {
JMenuItem sel = new JMenuItem(ClientSettings.getInstance().getResources().getResource("fill in the whole day"));
p.add(sel);
sel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// add a new appointment for the selected day...
GanttRowVO ganttRow = (GanttRowVO) ganttRows.get(table2.getSelectedRow());
ArrayList value = (ArrayList)model2.getValueAt(table2.getSelectedRow(),table2.getSelectedColumn());
Appointment a,olda;
if (value!=null) {
long t1 = startDate.getTime()+86400000L*((long)table2.getSelectedColumn());
long t2 = t1+86400000L; // -1 ???
for(int i=0;i<value.size();i++) {
a = (Appointment)value.get(i);
olda = (Appointment)a.clone();
if (a.getStartDate().getTime()<t1 &&
a.getEndDate().getTime()<=t2 &&
enableEdit &&
a.isEnableEdit()) {
a.setEndDate(new java.sql.Timestamp(t1));
a.setDuration(new BigDecimal(getTime(a,table2.getSelectedRow(),table2.getSelectedColumn())));
fireAppointmentChangedEvent(table2.getSelectedRow(),olda,a);
}
else if (a.getEndDate().getTime()>t2 &&
a.getStartDate().getTime()>=t1 &&
enableEdit &&
a.isEnableEdit()) {
a.setStartDate(new java.sql.Timestamp(t2));
a.setDuration(new BigDecimal(getTime(a,table2.getSelectedRow(),table2.getSelectedColumn())));
fireAppointmentChangedEvent(table2.getSelectedRow(),olda,a);
}
else if (a.getEndDate().getTime()<=t2 &&
a.getStartDate().getTime()>=t1 &&
enableDelete &&
a.isEnableDelete()) {
ganttRow.getAppointments().remove(a);
fireAppointmentDeletedEvent(table2.getSelectedRow(),a);
}
}
}
try {
a = (Appointment) ganttRow.getAppointmentClass().newInstance();
a.setDescription("");
Calendar cal = Calendar.getInstance();
GanttWorkingHours whVO = getWhVO(table2.getSelectedRow(),table2.getSelectedColumn());
if (whVO==null || whVO.getMorningStartHour()==null || whVO.getAfternoonStartHour()==null) {
OptionPane.showMessageDialog(
GanttControl.this,
ClientSettings.getInstance().getResources().getResource("no working hours defined for this day"),
ClientSettings.getInstance().getResources().getResource("Attention"),
JOptionPane.ERROR_MESSAGE
);
return;
}
table2.getCellEditor().stopCellEditing();
cal.setTimeInMillis(whVO.getMorningStartHour().getTime());
int h = cal.get(cal.HOUR_OF_DAY);
int m = cal.get(cal.MINUTE);
cal.setTimeInMillis(startDate.getTime()+86400000L*(long)table2.getSelectedColumn());
cal.set(cal.HOUR_OF_DAY,h);
cal.set(cal.MINUTE,m);
cal.set(cal.SECOND,0);
cal.set(cal.MILLISECOND,0);
a.setStartDate(new java.sql.Timestamp(cal.getTimeInMillis()));
cal.setTimeInMillis(whVO.getMorningEndHour().getTime());
h = cal.get(cal.HOUR_OF_DAY);
m = cal.get(cal.MINUTE);
cal.setTimeInMillis(startDate.getTime()+86400000L*(long)table2.getSelectedColumn());
cal.set(cal.HOUR_OF_DAY,h);
cal.set(cal.MINUTE,m);
cal.set(cal.SECOND,0);
cal.set(cal.MILLISECOND,0);
a.setEndDate(new java.sql.Timestamp(cal.getTimeInMillis()));
a.setDuration(new BigDecimal(getTime(a,table2.getSelectedRow(),table2.getSelectedColumn())));
ganttRow.getAppointments().add(a);
fireNewAppointmentEvent(table2.getSelectedRow(),a);
a = (Appointment) ganttRow.getAppointmentClass().newInstance();
a.setDescription("");
cal.setTimeInMillis(whVO.getAfternoonStartHour().getTime());
h = cal.get(cal.HOUR_OF_DAY);
m = cal.get(cal.MINUTE);
cal.setTimeInMillis(startDate.getTime()+86400000L*(long)table2.getSelectedColumn());
cal.set(cal.HOUR_OF_DAY,h);
cal.set(cal.MINUTE,m);
cal.set(cal.SECOND,0);
cal.set(cal.MILLISECOND,0);
a.setStartDate(new java.sql.Timestamp(cal.getTimeInMillis()));
cal.setTimeInMillis(whVO.getAfternoonEndHour().getTime());
h = cal.get(cal.HOUR_OF_DAY);
m = cal.get(cal.MINUTE);
cal.setTimeInMillis(startDate.getTime()+86400000L*(long)table2.getSelectedColumn());
cal.set(cal.HOUR_OF_DAY,h);
cal.set(cal.MINUTE,m);
cal.set(cal.SECOND,0);
cal.set(cal.MILLISECOND,0);
a.setEndDate(new java.sql.Timestamp(cal.getTimeInMillis()));
ganttRow.getAppointments().add(a);
a.setDuration(new BigDecimal(getTime(a,table2.getSelectedRow(),table2.getSelectedColumn())));
fireNewAppointmentEvent(table2.getSelectedRow(),a);
table2.tableChanged(new TableModelEvent(
model2,
table2.getSelectedRow(),
table2.getSelectedRow(),
table2.getSelectedColumn()
));
}
catch (Throwable ex) {
ex.printStackTrace();
}
}
});
}
if (enableDelete) {
JMenuItem desel = new JMenuItem(ClientSettings.getInstance().getResources().getResource("remove all day appointments"));
p.add(desel);
desel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// delete appointments in the selected day...
ArrayList value = (ArrayList)model2.getValueAt(table2.getSelectedRow(),table2.getSelectedColumn());
GanttRowVO ganttRow = (GanttRowVO) ganttRows.get(table2.getSelectedRow());
table2.getCellEditor().stopCellEditing();
Appointment a,olda;
if (value!=null) {
long t1 = startDate.getTime()+86400000L*((long)table2.getSelectedColumn());
long t2 = t1+86400000L; // -1 ???
for(int i=0;i<value.size();i++) {
a = (Appointment)value.get(i);
olda = (Appointment)a.clone();
if (a.getStartDate().getTime()<t1 &&
a.getEndDate().getTime()<=t2 &&
enableEdit &&
a.isEnableEdit()) {
a.setEndDate(new java.sql.Timestamp(t1));
a.setDuration(new BigDecimal(getTime(a,table2.getSelectedRow(),table2.getSelectedColumn())));
fireAppointmentChangedEvent(table2.getSelectedRow(),olda,a);
}
else if (a.getEndDate().getTime()>t2 &&
a.getStartDate().getTime()>=t1 &&
enableEdit &&
a.isEnableEdit()) {
a.setStartDate(new java.sql.Timestamp(t2));
a.setDuration(new BigDecimal(getTime(a,table2.getSelectedRow(),table2.getSelectedColumn())));
fireAppointmentChangedEvent(table2.getSelectedRow(),olda,a);
}
else if (a.getEndDate().getTime()<=t2 &&
a.getStartDate().getTime()>=t1 &&
enableDelete &&
a.isEnableDelete()) {
ganttRow.getAppointments().remove(a);
fireAppointmentDeletedEvent(table2.getSelectedRow(),a);
}
}
}
table2.tableChanged(new TableModelEvent(
model2,
table2.getSelectedRow(),
table2.getSelectedRow(),
table2.getSelectedColumn()
));
}
});
}
p.show(e.getComponent(),e.getX(),e.getY());
}
}
});
init();
scrollPane2.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
table2.repaint();
}
});
scrollPane1.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
if (scrollPane2.getVerticalScrollBar().getValue()!=scrollPane1.getVerticalScrollBar().getValue())
scrollPane2.getVerticalScrollBar().setValue(scrollPane1.getVerticalScrollBar().getValue());
}
});
scrollPane2.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
if (scrollPane1.getVerticalScrollBar().getValue()!=scrollPane2.getVerticalScrollBar().getValue())
scrollPane1.getVerticalScrollBar().setValue(scrollPane2.getVerticalScrollBar().getValue());
}
});
}
catch(Exception e) {
e.printStackTrace();
}
}
/**
* Set start date
* @param startDate start date
*/
public final void setStartDate(Date startDate) {
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
cal.set(cal.HOUR_OF_DAY,0);
cal.set(cal.MINUTE,0);
cal.set(cal.SECOND,0);
cal.set(cal.MILLISECOND,0);
this.startDate = cal.getTime();
init(model1.getColumnNames());
}
/**
* Set end date.
* @param endDate end date
*/
public final void setEndDate(Date endDate) {
Calendar cal = Calendar.getInstance();
cal.setTime(endDate);
cal.set(cal.HOUR_OF_DAY,0);
cal.set(cal.MINUTE,0);
cal.set(cal.SECOND,0);
cal.set(cal.MILLISECOND,0);
this.endDate = cal.getTime();
init(model1.getColumnNames());
}
private void jbInit() throws Exception {
this.setLayout(borderLayout1);
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setDividerSize(1);
table2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
scrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
this.add(splitPane, BorderLayout.CENTER);
splitPane.add(scrollPane1, JSplitPane.TOP);
splitPane.add(scrollPane2, JSplitPane.BOTTOM);
scrollPane2.getViewport().add(table2, null);
scrollPane1.getViewport().add(table1, null);
splitPane.setDividerLocation(150);
}
/**
* Create the grid content with no grid on the left.
*/
private void init() {
init(new String[0]);
}
/**
* Create the grid content.
* @param columnNames column identifiers for the grid on the left
*/
public void init(String[] columnNames) {
ganttRows.clear();
boolean lastEnabled = model1.isEnabled();
model1 = new Table1Model();
model1.resetModel(columnNames);
model1.setEnabled(lastEnabled);
lastEnabled = model2.isEnabled();
model2 = new Table2Model();
model2.resetModel();
model2.setEnabled(lastEnabled);
for(int i=0;i<table2.getColumnModel().getColumnCount();i++)
table2.getColumnModel().getColumn(i).setPreferredWidth(columnWidth);
table1.repaint();
table2.repaint();
if (columnNames.length==0)
splitPane.setDividerLocation(0);
else if (splitPane.getDividerLocation()==0)
splitPane.setDividerLocation(200);
}
/**
* Set columns width.
* @param width column width
*/
public final void setColumnWidth(int width) {
this.columnWidth = columnWidth;
for(int i=0;i<table2.getColumnModel().getColumnCount();i++)
table2.getColumnModel().getColumn(i).setPreferredWidth(columnWidth);
table2.repaint();
}
/**
* @return column width
*/
public final int getColumnWidth() {
return columnWidth;
}
/**
* Method called by the JVM to load gannt.
*/
public final void addNotify() {
super.addNotify();
if (!Beans.isDesignTime() && this.isVisible() && firstTime) {
firstTime = false;
if (autoLoadData)
reloadData();
}
}
/**
* Load data in the gantt panel.
*/
public void reloadData() {
ganttRows.clear();
table1.repaint();
table2.repaint();
Response res = ganttDataLocator.loadData(ganttParameters);
if (res.isError()) {
OptionPane.showMessageDialog(
this,
ClientSettings.getInstance().getResources().getResource("Error while loading data")+":\n"+ClientSettings.getInstance().getResources().getResource(res.getErrorMessage()),
ClientSettings.getInstance().getResources().getResource("Loading Data Error"),
JOptionPane.ERROR_MESSAGE
);
}
else {
java.util.List rows = ( (VOListResponse) res).getRows();
GanttRowVO vo = null;
for(int i=0;i<rows.size();i++) {
vo = (GanttRowVO)rows.get(i);
addRow(vo);
}
}
}
/**
* Add a row to the panel (grid on the left + gantt).
*/
public final void addRow(GanttRowVO ganttRow) {
ganttRows.add(ganttRow);
table1.revalidate();
table2.revalidate();
table1.repaint();
table2.repaint();
}
/**
* Set gantt editability.
* @param enabled <code>true</code> if the gantt is editable, <code>false</code> otherwise
*/
public final void setGanttEnabled(boolean enabled) {
model2.setEnabled(enabled);
table2.repaint();
}
/**
* @return gantt editability
*/
public final boolean isGanttEnabled() {
return model2.isEnabled();
}
/**
* Set editability for the grid on the left.
* @param enabled <code>true</code> if the grid on the left is editable, <code>false</code> otherwise
*/
public final void setGridEnabled(boolean enabled) {
model1.setEnabled(enabled);
if (enabled)
table1.setBackground(ClientSettings.GRID_CELL_BACKGROUND);
else
table1.setBackground(ClientSettings.GRID_NOT_EDITABLE_CELL_BACKGROUND);
table1.repaint();
}
/**
* @return editability for the grid on the left
*/
public final boolean isGridEnabled() {
return model1.isEnabled();
}
/**
* Set row height
* @param height row height
*/
public final void setRowHeight(int height) {
table1.setRowHeight(height);
table2.setRowHeight(height);
}
/**
* @return row height
*/
public final int getRowHeight() {
return table1.getRowHeight();
}
/**
* Set divider location.
* @param location divider location
*/
public final void setDividerLocation(int location) {
splitPane.setDividerLocation(location);
}
/**
* @return divider location
*/
public final int getDividerLocation() {
return splitPane.getDividerLocation();
}
/**
* @return gantt data locator
*/
public final GanttDataLocator getGanttDataLocator() {
return ganttDataLocator;
}
/**
* Set the gantt data locator.
* @param ganttDataLocator gantt data locator
*/
public final void setGanttDataLocator(GanttDataLocator ganttDataLocator) {
this.ganttDataLocator = ganttDataLocator;
}
/**
* @return gantt parameters
*/
public final Map getGanttParameters() {
return ganttParameters;
}
/**
* Set the gantt parameters.
* @param ganttParameters gantt parameters
*/
public final void setGanttParameters(Map ganttParameters) {
this.ganttParameters = ganttParameters;
}
/**
* @param row row in the gantt diagram
* @return set of Appointment objects defined in the specified row
*/
public final HashSet getAppointments(int row) {
GanttRowVO vo = (GanttRowVO)ganttRows.get(row);
return vo.getAppointments();
}
/**
* @return gantt rows number
*/
public final int getRowCount() {
return ganttRows.size();
}
/**
* @return show the description above the colored rectangle
*/
public final boolean isShowDescription() {
return showDescription;
}
/**
* Show the description above the colored rectangle.
* @param showDescription show the description above the colored rectangle
*/
public final void setShowDescription(boolean showDescription) {
this.showDescription = showDescription;
}
/**
* @return start date in the gantt
*/
public final Date getStartDate() {
return startDate;
}
/**
* @return end date in the gantt
*/
public final Date getEndDate() {
return endDate;
}
private GanttWorkingHours getWhVO(int row,int column) {
Calendar cal = Calendar.getInstance();
cal.setTime(new java.util.Date(startDate.getTime()+(long)column*86400000L));
GanttWorkingHours whVO = null;
if (cal.get(cal.DAY_OF_WEEK)==cal.SUNDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getSundayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.MONDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getMondayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.TUESDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getTuesdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.WEDNESDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getWednesdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.THURSDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getThursdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.FRIDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getFridayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.SATURDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getSaturdayWorkingHours();
return whVO;
}
/**
* @return enable deleting of appointments
*/
public final boolean isEnableDelete() {
return enableDelete;
}
/**
* Enable deleting of appointments.
* @param enableDelete enable deleting of appointments
*/
public final void setEnableDelete(boolean enableDelete) {
this.enableDelete = enableDelete;
}
/**
* @return enable inserting of appointments
*/
public final boolean isEnableInsert() {
return enableInsert;
}
/**
* Enable inserting of appointments.
* @param enableInsert enable inserting of appointments
*/
public final void setEnableInsert(boolean enableInsert) {
this.enableInsert = enableInsert;
}
/**
* @return show the appointment duration above the colored rectangle
*/
public final boolean isShowTime() {
return showTime;
}
/**
* Used to show the appointment duration above the colored rectangle.
* @param showTime show the appointment duration above the colored rectangle
*/
public final void setShowTime(boolean showTime) {
this.showTime = showTime;
}
/**
* Add a AppointmentChangeListener listener to the current gantt control.
* @param listener listener to add
*/
public final void addAppointmentChangeListener(AppointmentChangeListener listener) {
appointmentChangeListeners.add(listener);
}
/**
* Remove the specified AppointmentChangeListener listener from the current gantt control.
* @param listener listener to remove
*/
public final void removeAppointmentChangeListener(AppointmentChangeListener listener) {
appointmentChangeListeners.remove(listener);
}
/**
* Fire a new appointment event.
* @param rowNumber row number in the GanttControl
* @param appointment Appointment that fires the event
*/
protected void fireNewAppointmentEvent(int rowNum,Appointment app) {
for(int i=0;i<appointmentChangeListeners.size();i++) {
((AppointmentChangeListener)appointmentChangeListeners.get(i)).appointmentChange(new AppointmentChangeEvent(
AppointmentChangeEvent.NEW_APPOINTMENT,
rowNum,
app,
this
));
}
}
/**
* Fire an appointment changed event.
* @param rowNumber row number in the GanttControl
* @param appointment Appointment that fires the event
*/
protected void fireAppointmentChangedEvent(int rowNum,Appointment oldapp,Appointment newapp) {
for(int i=0;i<appointmentChangeListeners.size();i++) {
((AppointmentChangeListener)appointmentChangeListeners.get(i)).appointmentChange(new AppointmentChangeEvent(
AppointmentChangeEvent.APPOINTMENT_CHANGED,
rowNum,
oldapp,
newapp,
this
));
}
}
/**
* Fire an appointment deleted event.
* @param rowNumber row number in the GanttControl
* @param appointment Appointment that fires the event
*/
protected void fireAppointmentDeletedEvent(int rowNum,Appointment app) {
for(int i=0;i<appointmentChangeListeners.size();i++) {
((AppointmentChangeListener)appointmentChangeListeners.get(i)).appointmentChange(new AppointmentChangeEvent(
AppointmentChangeEvent.APPOINTMENT_DELETED,
rowNum,
app,
this
));
}
}
/**
* @param rowNumber row number
* @param colIndex column index
* @return Object[] grid content (in the legend area), related to the specified row number
*/
public final Object getValueAt(int rowNumber,int colIndex) {
return model1.getValueAt(rowNumber,colIndex);
}
/**
* Set column width.
* @param columnIndex column index in the grid (legend area)
* @param width column width to set
*/
public final void setGridColumnWidth(int columnIndex,int width) {
table1.getColumnModel().getColumn(columnIndex).setPreferredWidth(width);
preferredSize.put(new Integer(columnIndex),new Integer(width));
}
/**
* Set column visibility.
* @param columnIndex column index in the grid (legend area)
* @param visible column visibility
*/
public final void setGridColumnVisible(int columnIndex,boolean visible) {
if (!visible) {
table1.getColumnModel().removeColumn(table1.getColumnModel().getColumn(columnIndex));
visibility.add(new Integer(columnIndex));
}
}
/**
* @return appointment duration (in minutes(
*/
private long getTime(Appointment a,int row,int column) {
Calendar cal = Calendar.getInstance();
cal.setTime(new java.util.Date(startDate.getTime()+(long)column*86400000L));
GanttWorkingHours whVO = null;
if (cal.get(cal.DAY_OF_WEEK)==cal.SUNDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getSundayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.MONDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getMondayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.TUESDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getTuesdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.WEDNESDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getWednesdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.THURSDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getThursdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.FRIDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getFridayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.SATURDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getSaturdayWorkingHours();
long m1 = startDate.getTime()+((long)column)*86400000L;
long m2 = startDate.getTime()+((long)column)*86400000L;
long a1 = startDate.getTime()+((long)column)*86400000L+86400000L;
long a2 = startDate.getTime()+((long)column)*86400000L+86400000L;
if (whVO!=null) {
if (whVO.getMorningStartHour()!=null) {
cal.setTime(whVO.getMorningStartHour());
m1 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:0L);
}
if (whVO.getMorningEndHour()!=null) {
cal.setTime(whVO.getMorningEndHour());
m2 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:0L);
}
if (whVO.getAfternoonStartHour()!=null) {
cal.setTime(whVO.getAfternoonStartHour());
a1 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:86400000L);
}
if (whVO.getAfternoonEndHour()!=null) {
cal.setTime(whVO.getAfternoonEndHour());
a2 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:86400000L);
}
}
long d1 = 0;
long d2 = 0;
long d3 = 0;
long d4 = 0;
long delta = 0;
if (a.getStartDate().getTime()<=m1) {
d1 = m1;
if (a.getEndDate().getTime()<=m2)
d2 = a.getEndDate().getTime();
else {
d2 = m2;
if (a.getEndDate().getTime()>=a1) {
d3 = a1;
if (a.getEndDate().getTime()<=a2)
d4 = a.getEndDate().getTime();
else {
d4 = a2;
delta = getTime(a,row,column+1);
if (delta<0)
delta = 0;
}
}
else {
}
}
}
else {
if (a.getStartDate().getTime()>m2) {
if (a.getStartDate().getTime()>a1) {
d3 = a.getStartDate().getTime();
if (a.getEndDate().getTime()<a2)
d4 = a.getEndDate().getTime();
else {
d4 = a2;
delta = getTime(a,row,column+1);
if (delta<0)
delta = 0;
}
}
else {
if (a1==a2)
d3 = a.getStartDate().getTime();
else
d3 = a1;
if (a.getEndDate().getTime()<a2)
d4 = a.getEndDate().getTime();
else {
d4 = a2;
delta = getTime(a,row,column+1);
if (delta<0)
delta = 0;
}
}
}
else {
d1 = a.getStartDate().getTime();
if (a.getEndDate().getTime()<=m2)
d2 = a.getEndDate().getTime();
else {
if (a.getEndDate().getTime()<a1)
d2 = m2;
else {
d2 = m2;
d3 = a1;
if (a.getEndDate().getTime()<=a2)
d4 = a.getEndDate().getTime();
else {
d4 = a2;
delta = getTime(a,row,column+1);
if (delta<0)
delta = 0;
}
}
}
}
}
return delta+(d2-d1+d4-d3)/60000L;
}
/**
* @return enable editing of appointments
*/
public final boolean isEnableEdit() {
return enableEdit;
}
/**
* enable editing of appointments; default value: <code>true</code>.
* @param enableEdit enable editing of appointments
*/
public final void setEnableEdit(boolean enableEdit) {
this.enableEdit = enableEdit;
}
/**
* @return <code>true</code> to automatically load data when the gantt is showed, <code>false</code> otherwise
*/
public final boolean isAutoLoadData() {
return this.autoLoadData;
}
/**
* Define if grid must be automatically loaded when it is showed.
* @param autoLoadData <code>true</code> to automatically load data when the gantt is showed, <code>false</code> otherwise
*/
public final void setAutoLoadData(boolean autoLoadData) {
this.autoLoadData = autoLoadData;
}
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Inner class used to define the table model linked to the grid on the left.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
* @author Mauro Carniel
* @version 1.0
*/
class Table1Model extends AbstractTableModel {
/** column identifiers */
private String[] cols = new String[0];
/** flag used to set grid editability */
private boolean enabled = true;
public Table1Model() { }
/**
* @return column names
*/
public final String[] getColumnNames() {
return cols;
}
/**
* Set grid editability.
* @param enabled <code>true</code> if the grid is editable, <code>false</code> otherwise
*/
public final void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* return grid editability
*/
public final boolean isEnabled() {
return this.enabled;
}
/**
* Recalculate date interval and rows.
*/
public final void resetModel(String[] cols) {
this.cols = cols;
table1.setModel(this);
Enumeration keys = preferredSize.keys();
Integer colIndex = null;
while(keys.hasMoreElements()) {
colIndex = (Integer)keys.nextElement();
table1.getColumnModel().getColumn(colIndex.intValue()).setPreferredWidth(((Integer)preferredSize.get(colIndex)).intValue());
}
for(int i=0;i<visibility.size();i++)
table1.getColumnModel().removeColumn(table1.getColumnModel().getColumn(((Integer)visibility.get(i)).intValue()));
}
public int getColumnCount() {
return cols.length;
}
public String getColumnName(int columnIndex) {
return cols[columnIndex];
}
public int getRowCount() {
return ganttRows.size();
}
public Class getColumnClass(int columnIndex) {
return ganttRows.size()>0 && getValueAt(0,columnIndex)!=null ?
getValueAt(0,columnIndex).getClass() :
Object.class;
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return enabled;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return ((GanttRowVO)ganttRows.get(rowIndex)).getLegend()[columnIndex];
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
((GanttRowVO)ganttRows.get(rowIndex)).getLegend()[columnIndex] = aValue;
}
} // end Table1Model
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Inner class used to define the table model linked to the gantt grid.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
* @author Mauro Carniel
* @version 1.0
*/
class Table2Model extends AbstractTableModel {
/** column identifiers */
private ArrayList dates = new ArrayList();
/** flag used to set grid editability */
private boolean gridEnabled = true;
public Table2Model() { }
/**
* Set grid editability.
* @param enabled <code>true</code> if the grid is editable, <code>false</code> otherwise
*/
public final void setEnabled(boolean enabled) {
this.gridEnabled = enabled;
}
/**
* return grid editability
*/
public final boolean isEnabled() {
return this.gridEnabled;
}
/**
* Recalculate date interval and rows.
*/
public final void resetModel() {
SimpleDateFormat sdf = new SimpleDateFormat(ClientSettings.getInstance().getResources().getDateMask(Consts.TYPE_DATE));
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
while(cal.getTimeInMillis()<=endDate.getTime()) {
dates.add(sdf.format(cal.getTime()));
cal.set(cal.DAY_OF_MONTH,cal.get(cal.DAY_OF_MONTH)+1);
}
table2.setModel(this);
}
public int getColumnCount() {
return dates.size();
}
public String getColumnName(int columnIndex) {
return (String)dates.get(columnIndex);
}
public int getRowCount() {
return ganttRows.size();
}
public Class getColumnClass(int columnIndex) {
return ganttRows.size()>0 && getValueAt(0,columnIndex)!=null ?
getValueAt(0,columnIndex).getClass() :
Object.class;
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return gridEnabled;
}
/**
* @return ArrayList list of Appointment objects defined inside the specified day
*/
public Object getValueAt(int rowIndex, int columnIndex) {
long t1 = startDate.getTime()+86400000L*((long)columnIndex);
long t2 = t1+86400000L; // -1 ???
ArrayList list = new ArrayList();
HashSet alist = ((GanttRowVO)ganttRows.get(rowIndex)).getAppointments();
Appointment a = null;
Iterator it = alist.iterator();
while(it.hasNext()) {
a = (Appointment)it.next();
if (a.getEndDate().getTime()>=t1 && a.getEndDate().getTime()<=t2 ||
a.getStartDate().getTime()>=t1 && a.getStartDate().getTime()<=t2 ||
a.getStartDate().getTime()<=t1 && a.getEndDate().getTime()>=t2)
list.add(a);
}
return list;
}
/**
* Set the ArrayList of Appointment objects defined inside the specified day.
*/
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
long t1 = startDate.getTime()+86400000L*columnIndex;
long t2 = t1+86400000L; // -1 ???
ArrayList list = (ArrayList)aValue;
HashSet alist = ((GanttRowVO)ganttRows.get(rowIndex)).getAppointments();
Appointment a = null;
Iterator it = alist.iterator();
HashSet toRemove = new HashSet();
while(it.hasNext()) {
a = (Appointment)it.next();
if (a.getEndDate().getTime()>=t1 && a.getEndDate().getTime()<=t2 ||
a.getStartDate().getTime()>=t1 && a.getStartDate().getTime()<=t2 ||
a.getStartDate().getTime()<=t1 && a.getEndDate().getTime()>=t2)
toRemove.add(a);
}
alist.removeAll(toRemove);
alist.addAll(list);
}
} // end Table2Model
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Interface used as callback in GanttCell class.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
* <p> </p>
* @author Mauro Carniel
* @version 1.0
*/
interface OldAppointmentCallback {
public void setLastDescr(String lastDescr);
public String getLastDescr();
public void setLastAppointment(Appointment appointment);
public Appointment getLastAppointment();
}
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Inner class used to render the gantt columns (gantt bar).</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
* @author Mauro Carniel
* @version 1.0
*/
class GanttColumnRenderer extends DefaultTableCellRenderer implements OldAppointmentCallback {
/** cell content */
private GanttCell canvas = new GanttCell();
private Calendar cal = Calendar.getInstance();
/** last description */
private String lastDescr = null;
/** last row */
private int lastRow = -1;
/** last Appointment processed (viewed) */
private Appointment appointment = null;
public void setLastDescr(String lastDescr) {
this.lastDescr = lastDescr;
}
public String getLastDescr() {
return lastDescr;
}
public void setLastAppointment(Appointment appointment) {
this.appointment = appointment;
}
public Appointment getLastAppointment() {
return appointment;
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (row!=lastRow) {
lastDescr = null;
lastRow = row;
}
long width = 86400000L;
cal.setTime(new java.util.Date(startDate.getTime()+(long)column*86400000L));
GanttWorkingHours whVO = null;
if (cal.get(cal.DAY_OF_WEEK)==cal.SUNDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getSundayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.MONDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getMondayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.TUESDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getTuesdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.WEDNESDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getWednesdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.THURSDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getThursdayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.FRIDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getFridayWorkingHours();
else if (cal.get(cal.DAY_OF_WEEK)==cal.SATURDAY)
whVO = ((GanttRowVO)ganttRows.get(row)).getSaturdayWorkingHours();
if (whVO!=null)
width = (whVO.getMorningEndHour()!=null?(whVO.getMorningEndHour().getTime()-whVO.getMorningStartHour().getTime()):0)+
(whVO.getAfternoonEndHour()!=null?(whVO.getAfternoonEndHour().getTime()-whVO.getAfternoonStartHour().getTime()):0);
long m1 = startDate.getTime()+((long)column)*86400000L;
long m2 = startDate.getTime()+((long)column)*86400000L;
long a1 = startDate.getTime()+((long)column)*86400000L+86400000L;
long a2 = startDate.getTime()+((long)column)*86400000L+86400000L;
if (whVO!=null) {
if (whVO.getMorningStartHour()!=null) {
cal.setTime(whVO.getMorningStartHour());
m1 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:0L);
}
if (whVO.getMorningEndHour()!=null) {
cal.setTime(whVO.getMorningEndHour());
m2 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:0L);
}
if (whVO.getAfternoonStartHour()!=null) {
cal.setTime(whVO.getAfternoonStartHour());
a1 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:86400000L);
}
if (whVO.getAfternoonEndHour()!=null) {
cal.setTime(whVO.getAfternoonEndHour());
a2 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:86400000L);
}
}
canvas.setAppointments(
(ArrayList)value,
startDate.getTime()+((long)column)*86400000L,
startDate.getTime()+(((long)column)+1L)*86400000L,
width,
m1,
m2,
a1,
a2,
row,
this,
column
);
return canvas;
}
} // end GanttColumnRenderer
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Gantt Cell viewer, used by cell renderer/editor.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
* @author Mauro Carniel
* @version 1.0
*/
class GanttCell extends JPanel {
private ArrayList appointments = new ArrayList();
private long t1;
private long t2;
private long w;
private long m1;
private long m2;
private long a1;
private long a2;
private int row;
private OldAppointmentCallback callback;
private int column;
public void setAppointments(ArrayList appointments,long t1,long t2,long w,long m1,long m2,long a1,long a2,int row,OldAppointmentCallback callback,int column) {
this.appointments = appointments;
this.t1 = t1;
this.t2 = t2;
this.w = w;
this.m1 = m1;
this.m2 = m2;
this.a1 = a1;
this.a2 = a2;
this.row = row;
this.callback = callback;
this.column = column;
}
public void paint(Graphics g) {
super.paint(g);
Appointment a = null;
int x,len;
long minutes;
int delta;
String time = null;
if (model2.isEnabled())
g.setColor(ClientSettings.GRID_CELL_BACKGROUND);
else
g.setColor(ClientSettings.GRID_NOT_EDITABLE_CELL_BACKGROUND);
g.fillRect(0,0,getWidth(),getHeight());
for(int i=0;i<appointments.size();i++) {
a = (Appointment)appointments.get(i);
if (a.getStartDate().getTime()<m1)
x = 0;
else {
if (a.getStartDate().getTime()>m2)
x = (int)(getWidth()*(m2-m1+a.getStartDate().getTime()-a1)/w);
else
x = (int)(getWidth()*(a.getStartDate().getTime()-m1)/w);
}
if (a.getEndDate().getTime()>a2)
len = getWidth()-x;
else {
if (a.getEndDate().getTime()<=a1)
len = (int) (getWidth() * (a.getEndDate().getTime() - m1) / w);
else
len = (int) (getWidth() * (m2-m1+a.getEndDate().getTime() - a1) / w); // ???
}
if (a.getBackgroundColor()!=null) {
g.setColor(a.getBackgroundColor());
g.fillRect(
x,
0,
len,
getHeight()
);
}
g.setColor(a.getForegroundColor()==null?Color.black:a.getForegroundColor());
g.fillRect(
x,
20,
len,
10
);
delta = 0;
// if (showDescription && a.getDescription()!=null && !a.getDescription().equals(callback.getLastDescr()) && len>0) {
if (showDescription && a.getDescription()!=null && len>0) {
g.setColor(Color.black);
if (!a.getDescription().equals(callback.getLastDescr())) {
callback.setLastDescr(a.getDescription());
g.drawString(
callback.getLastDescr().length()>15?
callback.getLastDescr().substring(0,15):
callback.getLastDescr(),
x+2,
12
);
delta = g.getFontMetrics().stringWidth(
callback.getLastDescr().length()>15?
callback.getLastDescr().substring(0,15):
callback.getLastDescr()
)+2;
}
if (showTime) {
g.setColor(Color.black);
minutes = getTime(a,row,column);
time = (minutes/60)+":"+(minutes%60);
if (!a.equals(callback.getLastAppointment())) {
callback.setLastAppointment(a);
g.drawString("["+time+"]",x+2+delta,12);
}
}
}
if (!showDescription && showTime) {
g.setColor(Color.black);
minutes = getTime(a,row,column);
time = (minutes/60)+":"+(minutes%60);
if (!a.equals(callback.getLastAppointment())) {
callback.setLastAppointment(a);
g.drawString("["+time+"]",x+2+delta,12);
}
}
} // end for
}
} // end GanttCell
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Column editor used to resize the gantt bar.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
* @author Mauro Carniel
* @version 1.0
*/
public class GanttColumnEditor extends AbstractCellEditor implements TableCellEditor,OldAppointmentCallback {
private GanttCell label = new GanttCell();
private JTable table = null;
/** list of Appointment objects stored in the editing cell */
private ArrayList value = null;
/** flag used to store when the mouse is left clicked */
private boolean isLeftMouseButtonPressed = false;
/** x pixel stored when user press the mouse the first time */
private long lastX = -1;
/** column index related to the edited cell */
private int lastCellIndex = -1;
/** flag used to store editing cell selection */
private boolean isSelected = false;
/** temporary variable */
private Calendar cal = Calendar.getInstance();
/** last description */
private String lastDescr = null;
/** last row */
private int lastRow = -1;
/** last Appointment processed (viewed) */
private Appointment appointment = null;
public void setLastDescr(String lastDescr) {
this.lastDescr = lastDescr;
}
public String getLastDescr() {
return lastDescr;
}
public void setLastAppointment(Appointment appointment) {
this.appointment = appointment;
}
public Appointment getLastAppointment() {
return appointment;
}
public GanttColumnEditor() {
label.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (!table.getModel().isCellEditable(0,0))
return;
isLeftMouseButtonPressed = SwingUtilities.isLeftMouseButton(e);
lastX = e.getX();
}
public void mouseReleased(MouseEvent e) {
if (!table.getModel().isCellEditable(0,0))
return;
if (isLeftMouseButtonPressed) {
// int currentCellIndex = table.convertColumnIndexToModel(table.getSelectedColumn());
long width1 = 86400000L;
long m1 = 0;
GanttWorkingHours whVO1 = getWhVO(lastRow,lastCellIndex);
if (whVO1!=null) {
width1 = (whVO1.getMorningEndHour()!=null?(whVO1.getMorningEndHour().getTime()-whVO1.getMorningStartHour().getTime()):0)+
(whVO1.getAfternoonEndHour()!=null?(whVO1.getAfternoonEndHour().getTime()-whVO1.getAfternoonStartHour().getTime()):0);
cal.setTime(whVO1.getMorningStartHour());
m1 = cal.get(cal.HOUR_OF_DAY)*3600000;
}
int currentColIndex = (int)(e.getX()+lastCellIndex*(long)label.getWidth())/label.getWidth();
long width2 = 86400000L;
long m2 = 0;
GanttWorkingHours whVO2 = getWhVO(lastRow,currentColIndex);
if (whVO2!=null) {
width2 = (whVO2.getMorningEndHour()!=null?(whVO2.getMorningEndHour().getTime()-whVO2.getMorningStartHour().getTime()):0)+
(whVO2.getAfternoonEndHour()!=null?(whVO2.getAfternoonEndHour().getTime()-whVO2.getAfternoonStartHour().getTime()):0);
cal.setTime(whVO2.getMorningStartHour());
m2 = cal.get(cal.HOUR_OF_DAY)*3600000;
}
long x = 0;
if (e.getX()>0)
x = e.getX()%label.getWidth();
else
x = label.getWidth()-((-e.getX())%label.getWidth());
if (value!=null && lastX!=e.getX()) {
if (lastX<e.getX()) {
// enlarge appointment width: find out if there exists an appointment at lastX coordinate...
Appointment a,olda;
boolean exists = false;
long t1 = startDate.getTime()+86400000L*lastCellIndex+m1+width1*lastX/(long)label.getWidth();
long t2 = startDate.getTime()+86400000L*currentColIndex+m2+width2*x/(long)label.getWidth();
for(int i=0;i<value.size();i++) {
a = (Appointment)value.get(i);
olda = (Appointment)a.clone();
if (a.getStartDate().getTime()<=t1 && t1<=a.getEndDate().getTime()) {
if (enableEdit && a.isEnableEdit()) {
a.setEndDate(new java.sql.Timestamp(t2));
a.setDuration(new BigDecimal(getTime(a, lastRow, lastCellIndex)));
fireAppointmentChangedEvent(table2.getSelectedRow(),olda,a);
}
exists = true;
break;
}
}
if (!exists && enableInsert) {
// no appointment found: it will be created another one...
try {
GanttRowVO ganttRow = (GanttRowVO) ganttRows.get(lastRow);
a = (Appointment) ganttRow.getAppointmentClass().newInstance();
a.setDescription("");
a.setStartDate(new java.sql.Timestamp(t1));
a.setEndDate(new java.sql.Timestamp(t2));
a.setDuration(new BigDecimal(getTime(a,lastRow,lastCellIndex)));
fireNewAppointmentEvent(table2.getSelectedRow(),a);
value.add(a);
}
catch (Throwable ex) {
ex.printStackTrace();
}
}
}
else {
// reduce appointment width or delete appointment...
Appointment a,olda;
// long t2 = startDate.getTime()+86400000L*x/(long)label.getWidth();
long t2 = startDate.getTime()+86400000L*currentColIndex+m2+width2*x/(long)label.getWidth();
for(int i=0;i<value.size();i++) {
a = (Appointment)value.get(i);
olda = (Appointment)a.clone();
if (a.getStartDate().getTime()<=t2 && t2<=a.getEndDate().getTime()) {
if (enableEdit && a.isEnableEdit()) {
a.setEndDate(new java.sql.Timestamp(t2));
if (a.getStartDate().getTime()>=a.getEndDate().getTime() && enableDelete && a.isEnableDelete()) {
GanttRowVO ganttRow = (GanttRowVO) ganttRows.get(lastRow);
ganttRow.getAppointments().remove(a);
fireAppointmentDeletedEvent(table2.getSelectedRow(),a);
}
else
fireAppointmentChangedEvent(table2.getSelectedRow(),olda,a);
}
break;
}
}
}
if (table!=null)
table.editingStopped(null);
table2.repaint();
}
}
isLeftMouseButtonPressed = false;
}
});
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected,
int row, int column) {
this.table = table;
if (row!=lastRow) {
lastDescr = null;
lastRow = row;
}
long width = 86400000L;
cal.setTime(new java.util.Date(startDate.getTime()+(long)column*86400000L));
GanttWorkingHours whVO = getWhVO(row,column);
if (whVO!=null)
width = (whVO.getMorningEndHour()!=null?(whVO.getMorningEndHour().getTime()-whVO.getMorningStartHour().getTime()):0)+
(whVO.getAfternoonEndHour()!=null?(whVO.getAfternoonEndHour().getTime()-whVO.getAfternoonStartHour().getTime()):0);
this.value = (ArrayList)value;
this.isSelected = isSelected;
lastCellIndex = table.convertColumnIndexToModel(column);
long m1 = startDate.getTime()+((long)column)*86400000L;
long m2 = startDate.getTime()+((long)column)*86400000L;
long a1 = startDate.getTime()+((long)column)*86400000L+86400000L;
long a2 = startDate.getTime()+((long)column)*86400000L+86400000L;
if (whVO!=null) {
if (whVO.getMorningStartHour()!=null) {
cal.setTime(whVO.getMorningStartHour());
m1 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:0L);
}
if (whVO.getMorningEndHour()!=null) {
cal.setTime(whVO.getMorningEndHour());
m2 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:0L);
}
if (whVO.getAfternoonStartHour()!=null) {
cal.setTime(whVO.getAfternoonStartHour());
a1 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:86400000L);
}
if (whVO.getAfternoonEndHour()!=null) {
cal.setTime(whVO.getAfternoonEndHour());
a2 = startDate.getTime()+((long)column)*86400000L+(whVO!=null?cal.get(cal.HOUR_OF_DAY)*3600000L+cal.get(cal.MINUTE)*60000:86400000L);
}
}
label.setAppointments(
(ArrayList)value,
startDate.getTime()+((long)column)*86400000L,
startDate.getTime()+(((long)column)+1L)*86400000L,
width,
m1,
m2,
a1,
a2,
row,
this,
column
);
label.repaint();
return label;
}
public Object getCellEditorValue() {
return value;
}
} // end GanttColumnEditor
}