Java tutorial
/* * Copyright 2014 Tomi Virtanen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.pms.component.ganttchart; import com.pms.DashboardUI; import com.pms.dao.UserStoryDAO; import com.pms.domain.Project; import com.pms.domain.Task; import com.pms.domain.User; import com.pms.domain.UserStory; import com.vaadin.annotations.Theme; import com.vaadin.annotations.Title; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.fieldgroup.FieldGroup; import com.vaadin.data.fieldgroup.FieldGroup.CommitException; import com.vaadin.data.util.BeanItem; import com.vaadin.data.util.converter.DateToLongConverter; import com.vaadin.server.ClientConnector; import com.vaadin.server.Sizeable; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.shared.ui.datefield.Resolution; import com.vaadin.ui.*; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.MenuBar.Command; import com.vaadin.ui.MenuBar.MenuItem; import com.vaadin.ui.Notification.Type; import org.tltv.gantt.Gantt; import org.tltv.gantt.Gantt.MoveEvent; import org.tltv.gantt.Gantt.ResizeEvent; import org.tltv.gantt.client.shared.AbstractStep; import org.tltv.gantt.client.shared.Step; import org.tltv.gantt.client.shared.SubStep; import com.pms.component.ganttchart.util.UriFragmentWrapperFactory; import com.pms.component.ganttchart.util.Util; import javax.servlet.annotation.WebServlet; import java.text.SimpleDateFormat; import java.util.*; import java.util.Calendar; public class GanttChart { private Gantt gantt; private NativeSelect localeSelect; private NativeSelect reso; private DateField start; private DateField end; private SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss zzz yyyy"); private HorizontalLayout controls; private GanttListener ganttListener; private ClientConnector.AttachListener ganttAttachListener = new ClientConnector.AttachListener() { @Override public void attach(ClientConnector.AttachEvent event) { syncLocaleAndTimezone(); } }; private ClickListener createStepClickListener = new ClickListener() { @Override public void buttonClick(ClickEvent event) { Step newStep = new Step(); Date now = new Date(); newStep.setStartDate(now.getTime()); newStep.setEndDate(now.getTime() + (7 * 24 * 3600000)); openStepEditor(newStep); } }; private ValueChangeListener startDateValueChangeListener = new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { gantt.setStartDate((Date) event.getProperty().getValue()); } }; private ValueChangeListener endDateValueChangeListener = new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { gantt.setEndDate((Date) event.getProperty().getValue()); } }; private ValueChangeListener resolutionValueChangeListener = new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { org.tltv.gantt.client.shared.Resolution res = (org.tltv.gantt.client.shared.Resolution) event .getProperty().getValue(); if (validateResolutionChange(res)) { gantt.setResolution(res); } } }; private ValueChangeListener localeValueChangeListener = new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { gantt.setLocale((Locale) event.getProperty().getValue()); syncLocaleAndTimezone(); } }; private ValueChangeListener timezoneValueChangeListener = new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { String tzId = (String) event.getProperty().getValue(); if ("Default".equals(tzId)) { gantt.setTimeZone(null); } else { gantt.setTimeZone(TimeZone.getTimeZone(tzId)); } syncLocaleAndTimezone(); } }; public Component init(Project project) { ganttListener = null; createGantt(project); MenuBar menu = controlsMenuBar(); Panel controls = createControls(); TabSheet tabsheet = new TabSheet(); tabsheet.setSizeFull(); Component wrapper = UriFragmentWrapperFactory.wrapByUriFragment(UI.getCurrent().getPage().getUriFragment(), gantt); if (wrapper instanceof GanttListener) { ganttListener = (GanttListener) wrapper; } final VerticalLayout layout = new VerticalLayout(); layout.setStyleName("demoContentLayout"); layout.setSizeFull(); //layout.addComponent(menu); layout.addComponent(controls); layout.addComponent(wrapper); layout.setExpandRatio(wrapper, 1); return layout; } private void createGantt(Project project) { gantt = new Gantt(); gantt.setWidth(100, Sizeable.Unit.PERCENTAGE); gantt.setHeight(400, Sizeable.Unit.PIXELS); gantt.setResizableSteps(true); gantt.setMovableSteps(true); gantt.addAttachListener(ganttAttachListener); Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); gantt.setStartDate(cal.getTime()); cal.add(Calendar.YEAR, 1); gantt.setEndDate(cal.getTime()); cal.setTime(new Date()); Step step1 = new Step("First step"); step1.setDescription("Description tooltip"); step1.setStartDate(cal.getTime().getTime()); cal.add(Calendar.MONTH, 2); step1.setEndDate(cal.getTime().getTime()); Step step2 = new Step("Second step"); step2.setDescription("Description tooltip for second step"); cal.add(Calendar.DATE, 1); step2.setStartDate(cal.getTime().getTime()); cal.add(Calendar.MONTH, 4); step2.setEndDate(cal.getTime().getTime()); step2.setPredecessor(step1); Step step3 = new Step("Third step"); step3.setDescription("<b>HTML</b> <i>content</i> is <u>supported</u> in tooltips."); cal.add(Calendar.DATE, 1); step3.setStartDate(cal.getTime().getTime()); cal.add(Calendar.MONTH, 12); step3.setEndDate(cal.getTime().getTime()); step3.setPredecessor(step2); Step step4 = new Step("Fourth step"); step4.setDescription("Tooltip is <b>VTooltip</b>. <p>Looks same for all Vaadin components."); step4.setStartDate(step2.getStartDate()); step4.setEndDate(step2.getEndDate()); step4.setPredecessor(step1); Step stepWithSubSteps = new Step("Step with sub-steps"); stepWithSubSteps.setDescription("Tooltip for Step with sub-steps"); cal.setTime(new Date(step1.getStartDate())); cal.add(Calendar.DATE, 7); SubStep subStep1 = new SubStep("Sub-step A"); subStep1.setDescription("Tooltip for Sub-step A"); subStep1.setBackgroundColor("A8D9DD"); subStep1.setStartDate(step1.getStartDate()); subStep1.setEndDate(cal.getTime()); SubStep subStep2 = new SubStep("Sub-step B"); subStep2.setDescription("Tooltip for Sub-step B"); subStep2.setBackgroundColor("A8D9BB"); subStep2.setStartDate(cal.getTime()); cal.add(Calendar.MONTH, 1); subStep2.setEndDate(cal.getTime()); SubStep subStep3 = new SubStep("Sub-step C"); subStep3.setDescription("Tooltip for Sub-step C"); subStep3.setBackgroundColor("A8D999"); subStep3.setStartDate(cal.getTime()); cal.add(Calendar.MONTH, 1); subStep3.setEndDate(step1.getEndDate()); stepWithSubSteps.addSubStep(subStep1); stepWithSubSteps.addSubStep(subStep2); stepWithSubSteps.addSubStep(subStep3); gantt.addStep(step1); gantt.addStep(step2); gantt.addStep(step3); gantt.addStep(step4); gantt.addStep(stepWithSubSteps); String[] colors = new String[] { "11FF11", "33FF33", "55FF55", "77FF77", "99FF99", "BBFFBB", "DDFFDD" }; cal.setTime(new Date()); for (int i = 0; i < 10; i++) { Step step = new Step("Step " + i); step.setStartDate(cal.getTime().getTime()); cal.add(Calendar.DATE, 14); step.setEndDate(cal.getTime().getTime()); step.setBackgroundColor(colors[i % colors.length]); gantt.addStep(step); } gantt.addClickListener(new Gantt.ClickListener() { @Override public void onGanttClick(Gantt.ClickEvent event) { openStepEditor(event.getStep()); } }); gantt.addMoveListener(new Gantt.MoveListener() { @Override public void onGanttMove(MoveEvent event) { Date start = new Date(event.getStartDate()); Date end = new Date(event.getEndDate()); dateFormat.setTimeZone(gantt.getTimeZone()); Notification.show("Moved " + event.getStep().getCaption() + " to Start Date: " + dateFormat.format(start) + " End Date: " + dateFormat.format(end), Type.TRAY_NOTIFICATION); } }); gantt.addResizeListener(new Gantt.ResizeListener() { @Override public void onGanttResize(ResizeEvent event) { Date start = new Date(event.getStartDate()); Date end = new Date(event.getEndDate()); dateFormat.setTimeZone(gantt.getTimeZone()); Notification.show("Resized " + event.getStep().getCaption() + " to Start Date: " + dateFormat.format(start) + " End Date: " + dateFormat.format(end), Type.TRAY_NOTIFICATION); } }); } private void syncLocaleAndTimezone() { start.removeValueChangeListener(startDateValueChangeListener); end.removeValueChangeListener(endDateValueChangeListener); try { start.setLocale(gantt.getLocale()); start.setTimeZone(gantt.getTimeZone()); start.setValue(gantt.getStartDate()); end.setLocale(gantt.getLocale()); end.setTimeZone(gantt.getTimeZone()); end.setValue(gantt.getEndDate()); } finally { start.addValueChangeListener(startDateValueChangeListener); end.addValueChangeListener(endDateValueChangeListener); } dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss zzz yyyy", gantt.getLocale()); } private Panel createControls() { Panel panel = new Panel(); panel.setWidth(100, Sizeable.Unit.PERCENTAGE); controls = new HorizontalLayout(); controls.setSpacing(true); controls.setMargin(true); panel.setContent(controls); start = createStartDateField(); end = createEndDateField(); Button createStep = new Button("Create New Step...", createStepClickListener); HorizontalLayout heightAndUnit = new HorizontalLayout(Util.createHeightEditor(gantt), Util.createHeightUnitEditor(gantt)); HorizontalLayout widthAndUnit = new HorizontalLayout(Util.createWidthEditor(gantt), Util.createWidthUnitEditor(gantt)); reso = new NativeSelect("Resolution"); reso.setNullSelectionAllowed(false); reso.addItem(org.tltv.gantt.client.shared.Resolution.Hour); reso.addItem(org.tltv.gantt.client.shared.Resolution.Day); reso.addItem(org.tltv.gantt.client.shared.Resolution.Week); reso.setValue(gantt.getResolution()); reso.setImmediate(true); reso.addValueChangeListener(resolutionValueChangeListener); localeSelect = new NativeSelect("Locale") { @Override public void attach() { super.attach(); if (getValue() == null) { // use default locale setValue(gantt.getLocale()); addValueChangeListener(localeValueChangeListener); } } }; localeSelect.setNullSelectionAllowed(false); for (Locale l : Locale.getAvailableLocales()) { localeSelect.addItem(l); localeSelect.setItemCaption(l, l.getDisplayName(DashboardUI.getCurrent().getUI().getLocale())); } localeSelect.setImmediate(true); String[] zones = new String[] { "GMT-0", "GMT-1", "GMT-2", "GMT-3", "GMT-4", "GMT-5", "GMT-6", "GMT-7", "GMT-8", "GMT-9", "GMT-10", "GMT-11", "GMT-12", "GMT+1", "GMT+2", "GMT+3", "GMT+4", "GMT+5", "GMT+6", "GMT+7", "GMT+8", "GMT+9", "GMT+10", "GMT+11", "GMT+12", "GMT+13", "GMT+14" }; NativeSelect timezoneSelect = new NativeSelect("Timezone"); timezoneSelect.setNullSelectionAllowed(false); timezoneSelect.addItem("Default"); timezoneSelect.setItemCaption("Default", "Default (" + TimeZone.getDefault().getDisplayName() + ")"); for (String timezoneId : zones) { TimeZone tz = TimeZone.getTimeZone(timezoneId); timezoneSelect.addItem(timezoneId); timezoneSelect.setItemCaption(timezoneId, tz.getDisplayName(DashboardUI.getCurrent().getUI().getLocale())); } timezoneSelect.setValue("Default"); timezoneSelect.setImmediate(true); timezoneSelect.addValueChangeListener(timezoneValueChangeListener); controls.addComponent(start); controls.addComponent(end); controls.addComponent(reso); //controls.addComponent(localeSelect); //controls.addComponent(timezoneSelect); controls.addComponent(heightAndUnit); controls.addComponent(widthAndUnit); //controls.addComponent(createStep); // controls.setComponentAlignment(createStep, Alignment.MIDDLE_LEFT); //controls.setComponentAlignment(widthAndUnit, Alignment.MIDDLE_LEFT); return panel; } private DateField createStartDateField() { DateField f = new DateField("Start date"); f.setResolution(Resolution.SECOND); f.setImmediate(true); f.addValueChangeListener(startDateValueChangeListener); return f; } private DateField createEndDateField() { DateField f = new DateField("End date"); f.setResolution(Resolution.SECOND); f.setImmediate(true); f.addValueChangeListener(endDateValueChangeListener); return f; } private boolean validateResolutionChange(final org.tltv.gantt.client.shared.Resolution res) { long max = 5 * 12 * 4 * 7 * 24 * 3600000L; if (res == org.tltv.gantt.client.shared.Resolution.Hour && (gantt.getEndDate().getTime() - gantt.getStartDate().getTime()) > max) { // revert to previous resolution setResolution(gantt.getResolution()); // make user to confirm hour resolution, if the timeline range is // more than one week long. Util.showConfirmationPopup( "Timeline range is a quite long for hour resolution. Rendering may be slow. Continue anyway?", new Runnable() { @Override public void run() { setResolution(res); gantt.setResolution(res); } }); return false; } return true; } private void setResolution(org.tltv.gantt.client.shared.Resolution resolution) { reso.removeValueChangeListener(resolutionValueChangeListener); try { reso.setValue(resolution); } finally { reso.addValueChangeListener(resolutionValueChangeListener); } } private MenuBar controlsMenuBar() { MenuBar menu = new MenuBar(); MenuItem editItem = menu.addItem("Edit", null); MenuItem formatItem = menu.addItem("Format", null); MenuItem viewItem = menu.addItem("View", null); MenuItem item = editItem.addItem("Enabled", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setEnabled(!gantt.isEnabled()); selectedItem.setChecked(gantt.isEnabled()); } }); item.setCheckable(true); item.setChecked(gantt.isEnabled()); item = editItem.addItem("Read-only", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setReadOnly(!gantt.isReadOnly()); selectedItem.setChecked(gantt.isReadOnly()); } }); item.setCheckable(true); item.setChecked(gantt.isReadOnly()); item = formatItem.addItem("Set 'MMM' month format", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setTimelineMonthFormat("MMM"); } }); item = formatItem.addItem("Set 'MMMM' month format", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setTimelineMonthFormat("MMMM"); } }); item = formatItem.addItem("Set 'yyyy MMMM' month format", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setTimelineMonthFormat("yyyy MMMM"); } }); item = formatItem.addItem("Set 'dd.' week format", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setTimelineWeekFormat("dd."); } }); item = formatItem.addItem("Set week number week format", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setTimelineWeekFormat(null); } }); item = formatItem.addItem("Set 'dd. EEEE' day format for Hour resolution", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setTimelineDayFormat("dd. EEEE"); } }); item = viewItem.addItem("Show years", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setYearsVisible(!gantt.isYearsVisible()); selectedItem.setChecked(gantt.isYearsVisible()); } }); item.setCheckable(true); item.setChecked(gantt.isYearsVisible()); item = viewItem.addItem("Show months", new Command() { @Override public void menuSelected(MenuItem selectedItem) { gantt.setMonthsVisible(!gantt.isMonthsVisible()); selectedItem.setChecked(gantt.isMonthsVisible()); } }); item.setCheckable(true); item.setChecked(gantt.isMonthsVisible()); item = viewItem.addItem("Show Gantt with Table", new Command() { @Override public void menuSelected(MenuItem selectedItem) { DashboardUI.getCurrent().getUI().getPage().setLocation("#table"); DashboardUI.getCurrent().getUI().getPage().reload(); } }); item = viewItem.addItem("Show Gantt with TreeTable", new Command() { @Override public void menuSelected(MenuItem selectedItem) { DashboardUI.getCurrent().getUI().getPage().setLocation("#treetable"); DashboardUI.getCurrent().getUI().getPage().reload(); } }); item = viewItem.addItem("Show Gantt alone", new Command() { @Override public void menuSelected(MenuItem selectedItem) { DashboardUI.getCurrent().getUI().getPage().setLocation("#"); DashboardUI.getCurrent().getUI().getPage().reload(); } }); return menu; } private void openStepEditor(AbstractStep step) { final Window win = new Window("Step Editor"); win.setResizable(false); win.center(); final Collection<Component> hidden = new ArrayList<Component>(); BeanItem<AbstractStep> item = new BeanItem<AbstractStep>(step); final FieldGroup group = new FieldGroup(item); group.setBuffered(true); TextField captionField = new TextField("Caption"); captionField.setNullRepresentation(""); group.bind(captionField, "caption"); TextField descriptionField = new TextField("Description"); descriptionField.setNullRepresentation(""); group.bind(descriptionField, "description"); descriptionField.setVisible(false); hidden.add(descriptionField); NativeSelect captionMode = new NativeSelect("Caption Mode"); captionMode.addItem(Step.CaptionMode.TEXT); captionMode.addItem(Step.CaptionMode.HTML); group.bind(captionMode, "captionMode"); captionMode.setVisible(false); hidden.add(captionMode); final NativeSelect parentStepSelect = new NativeSelect("Parent Step"); parentStepSelect.setEnabled(false); if (!gantt.getSteps().contains(step)) { // new step parentStepSelect.setEnabled(true); for (Step parentStepCanditate : gantt.getSteps()) { parentStepSelect.addItem(parentStepCanditate); parentStepSelect.setItemCaption(parentStepCanditate, parentStepCanditate.getCaption()); if (step instanceof SubStep) { if (parentStepCanditate.getSubSteps().contains(step)) { parentStepSelect.setValue(parentStepCanditate); parentStepSelect.setEnabled(false); break; } } } } parentStepSelect.setVisible(false); hidden.add(parentStepSelect); TextField bgField = new TextField("Background color"); bgField.setNullRepresentation(""); group.bind(bgField, "backgroundColor"); bgField.setVisible(false); hidden.add(bgField); DateField startDate = new DateField("Start date"); startDate.setLocale(gantt.getLocale()); startDate.setTimeZone(gantt.getTimeZone()); startDate.setResolution(Resolution.SECOND); startDate.setConverter(new DateToLongConverter()); group.bind(startDate, "startDate"); DateField endDate = new DateField("End date"); endDate.setLocale(gantt.getLocale()); endDate.setTimeZone(gantt.getTimeZone()); endDate.setResolution(Resolution.SECOND); endDate.setConverter(new DateToLongConverter()); group.bind(endDate, "endDate"); CheckBox showMore = new CheckBox("Show all settings"); showMore.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { for (Component c : hidden) { c.setVisible((Boolean) event.getProperty().getValue()); } win.center(); } }); VerticalLayout content = new VerticalLayout(); content.setMargin(true); content.setSpacing(true); win.setContent(content); content.addComponent(captionField); content.addComponent(captionMode); content.addComponent(descriptionField); content.addComponent(parentStepSelect); content.addComponent(bgField); content.addComponent(startDate); content.addComponent(endDate); content.addComponent(showMore); HorizontalLayout buttons = new HorizontalLayout(); content.addComponent(buttons); Button ok = new Button("Ok", new ClickListener() { @Override public void buttonClick(ClickEvent event) { try { group.commit(); AbstractStep step = ((BeanItem<AbstractStep>) group.getItemDataSource()).getBean(); gantt.markStepDirty(step); if (parentStepSelect.isEnabled() && parentStepSelect.getValue() != null) { SubStep subStep = addSubStep(parentStepSelect, step); step = subStep; } if (step instanceof Step && !gantt.getSteps().contains(step)) { gantt.addStep((Step) step); } if (ganttListener != null && step instanceof Step) { ganttListener.stepModified((Step) step); } win.close(); } catch (CommitException e) { Notification.show("Commit failed", e.getMessage(), Type.ERROR_MESSAGE); e.printStackTrace(); } } private SubStep addSubStep(final NativeSelect parentStepSelect, AbstractStep dataSource) { SubStep subStep = new SubStep(); subStep.setCaption(dataSource.getCaption()); subStep.setCaptionMode(dataSource.getCaptionMode()); subStep.setStartDate(dataSource.getStartDate()); subStep.setEndDate(dataSource.getEndDate()); subStep.setBackgroundColor(dataSource.getBackgroundColor()); subStep.setDescription(dataSource.getDescription()); subStep.setStyleName(dataSource.getStyleName()); ((Step) parentStepSelect.getValue()).addSubStep(subStep); return subStep; } }); Button cancel = new Button("Cancel", new ClickListener() { @Override public void buttonClick(ClickEvent event) { group.discard(); win.close(); } }); Button delete = new Button("Delete", new ClickListener() { @Override public void buttonClick(ClickEvent event) { AbstractStep step = ((BeanItem<AbstractStep>) group.getItemDataSource()).getBean(); if (step instanceof SubStep) { SubStep substep = (SubStep) step; substep.getOwner().removeSubStep(substep); } else { gantt.removeStep((Step) step); if (ganttListener != null) { ganttListener.stepDeleted((Step) step); } } win.close(); } }); buttons.addComponent(ok); buttons.addComponent(cancel); buttons.addComponent(delete); win.setClosable(true); DashboardUI.getCurrent().getUI().addWindow(win); } }