Java tutorial
/******************************************************************************* * Copyright (c) 2014 Ministry of Transport and Communications (Finland). * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Semantum Oy - initial API and implementation *******************************************************************************/ package fi.semantum.strategia.widget; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.event.LayoutEvents.LayoutClickEvent; import com.vaadin.event.LayoutEvents.LayoutClickListener; import com.vaadin.event.MouseEvents; import com.vaadin.server.Page; import com.vaadin.server.Page.Styles; import com.vaadin.server.ThemeResource; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.AbsoluteLayout; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Image; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.Table; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; import fi.semantum.strategia.Dialogs; import fi.semantum.strategia.Main; import fi.semantum.strategia.Updates; import fi.semantum.strategia.Utils; import fi.semantum.strategia.Wiki; public class Meter extends Base { private static final long serialVersionUID = 7697435820705311629L; private TrafficValuation trafficValuation; @Deprecated final public double[] limits; @Deprecated private double userValue = 0; @Deprecated private boolean userDefined = false; private boolean showInMap = true; public boolean isPrincipal = false; public String link = ""; //public String description = ""; private boolean isTransient = false; public static Meter transientMeter(String id, String link, double value) { Meter result = new Meter(id, "", new ContinuousTrafficValuation()); result.userDefined = true; result.userValue = value; result.link = link; result.isTransient = true; return result; } public static Meter create(Database database, String id, String text, TrafficValuation trafficValuation) { Meter p = new Meter(id, text, trafficValuation); database.register(p); return p; } public static Meter create(Database database, Base container, String id, String text, TrafficValuation valuation) { Meter result = create(database, id, text, valuation); container.addMeter(result); return result; } private Meter(String id, String text, TrafficValuation valuation) { super(UUID.randomUUID().toString(), id, text); this.trafficValuation = valuation; limits = null; } public boolean isTransient() { return isTransient; } @Override public Base getOwner(Database database) { for (Base b : database.enumerate()) { if (b.getMeters(database).contains(this)) return b; } return null; } public static Map<Base, List<Meter>> metersByParent(Database database, Collection<Meter> meters) { Map<Base, List<Meter>> result = new HashMap<Base, List<Meter>>(); for (Meter m : meters) { Base owner = m.getOwner(database); List<Meter> exist = result.get(owner); if (exist == null) { exist = new ArrayList<Meter>(); result.put(owner, exist); } exist.add(m); } return result; } public List<Meter> getSubmeters(Database database) { // User-defined meter if (userDefined) return Collections.emptyList(); // Indicator-defined meter if (limits != null) return Collections.emptyList(); Base owner = getOwner(database); if (owner == null) return Collections.emptyList(); ArrayList<Meter> result = new ArrayList<Meter>(); collectSubmeters(database, owner, result); return result; } private static void collectSubmeters(Database db, Base b, List<Meter> result) { Relation implementsRelation = Relation.find(db, Relation.IMPLEMENTS); for (Base implementor : db.getInverse(b, implementsRelation)) { Collection<Meter> meters = implementor.getMeters(db); if (meters.isEmpty()) { collectSubmeters(db, implementor, result); } else { result.addAll(meters); } } } public Indicator getPossibleIndicator(Database database) { Indicator result = null; Relation measures = Relation.find(database, Relation.MEASURES); for (Pair p : measures.getRelations(this)) { Base b = database.find(p.second); if (b instanceof Indicator) { if (result != null) return null; result = (Indicator) b; } } return result; } public String explain(Database database) { Indicator i = getPossibleIndicator(database); if (i != null) return "" + i.getValue(); else return "" + (int) (100.0 * value(database)) + "%"; } public String describe(Database database, boolean forecast) { Indicator i = getPossibleIndicator(database); if (i != null) { Object value = i.getValue(forecast); if (value == null) return "arvoa ei ole annettu"; Datatype datatype = i.getDatatype(database); return datatype.format(value) + " " + i.getUnit(); } else { if (userDefined) { if (userValue < 0.4) return "Ei toteutunut"; else if (userValue > 0.6) return "Toteutunut"; else return "Osittain toteutunut"; } else { Collection<Meter> ms = getSubmeters(database); double value = value(database); int pct = (int) (100.0 * value); if (ms.size() == 0) { return "" + pct + "% (ei mittareita)"; } else if (ms.size() == 1) { return "" + pct + "% (1 mittari)"; } else { return "" + pct + "% (" + ms.size() + " mittaria)"; } } } } public double value(Database database) { return value(database, true); } public double value(Database database, boolean forecast) { if (userDefined) return userValue; Indicator indicator = getPossibleIndicator(database); if (indicator != null) { String color = getTrafficColor(database, forecast); if (TrafficValuation.GREEN.equals(color)) return 1.0; else if (TrafficValuation.YELLOW.equals(color)) return 0.5; else return 0.0; } double result = 0.0; int contributions = 0; Collection<Meter> submeters = getSubmeters(database); if (submeters.isEmpty()) return 0.0; for (Meter m : submeters) { result += m.value(database, forecast); contributions++; } if (contributions > 0) result /= contributions; return result; } public static List<Meter> enumerate(Database database) { ArrayList<Meter> result = new ArrayList<Meter>(); for (Base b : database.objects.values()) { if (b instanceof Meter) result.add((Meter) b); } return result; } public void setUserValue(Main main, double value) { userDefined = true; userValue = value; if (main != null) { Base b = getOwner(main.getDatabase()); if (b != null) { b.modified(main); } } } public boolean isUserDefined() { return userDefined; } public double getUserValue() { return userValue; } @Override public boolean modifyId(Main main, Account account, String id) { Database database = main.getDatabase(); Indicator indicator = getPossibleIndicator(database); if (indicator != null) { if (getOwner(database).equals(indicator.getOwner(database))) { indicator.modifyId(main, account, id); } } return super.modifyId(main, account, id); } @Override public boolean modifyText(Main main, Account account, String text) { Database database = main.getDatabase(); Indicator indicator = getPossibleIndicator(database); if (indicator != null) { if (getOwner(database).equals(indicator.getOwner(database))) { indicator.modifyText(main, account, text); } } return super.modifyText(main, account, text); } @Override public boolean modifyDescription(Main main, Account account, String text) { Database database = main.getDatabase(); Indicator indicator = getPossibleIndicator(database); if (indicator != null) { if (getOwner(database).equals(indicator.getOwner(database))) { indicator.modifyDescription(main, account, text); } } return super.modifyDescription(main, account, text); } public String getTrafficColor(Database database) { return getTrafficColor(database, true); } public String getTrafficColor(Database database, boolean forecast) { Indicator indicator = getPossibleIndicator(database); if (indicator != null) { Object value = indicator.getValue(forecast); if (value == null) return TrafficValuation.RED; String s = trafficValuation.getTrafficValue(value); if (s != null) return s; return TrafficValuation.RED; } return Utils.trafficColor(value(database, forecast)); } @Override public boolean migrate(Main main) { boolean result = false; Database database = main.getDatabase(); if (getOwner(database) == null) { remove(database); return true; } Property aika = Property.find(database, Property.AIKAVALI); Indicator indicator = getPossibleIndicator(database); if (indicator != null) { result |= indicator.migrate(main); if (trafficValuation == null && limits != null) { trafficValuation = new NumberTrafficValuation(BigDecimal.valueOf(limits[0]), BigDecimal.valueOf(limits[1])); result = true; } } else { if (userDefined) { Datatype dt = Datatype.find(database, "Toteuma"); Indicator ind = Indicator.create(database, getId(database), dt); String year = aika.getPropertyValue(this); if (year == null) year = Property.AIKAVALI_KAIKKI; Base owner = getOwner(database); addIndicatorMeter(main, owner, ind, year); owner.removeMeter(this); remove(database); result = true; } } if (description == null) { modifyDescription(main, getText(database)); modifyText(main, getId(database)); modifyId(main, ""); result = true; } result |= super.migrate(main); return result; } public static Meter addIndicatorMeter(Main main, Base b, Indicator indicator, String year) { Database database = main.getDatabase(); Relation measures = Relation.find(database, Relation.MEASURES); Datatype type = indicator.getDatatype(database); TrafficValuation defaultValuation = type.getDefaultTrafficValuation(); Meter m = Meter.create(database, b, indicator.getId(database), indicator.getText(database), defaultValuation); m.addRelation(measures, indicator); Utils.modifyValidity(main, m, year); return m; } public static String updateMeterValue(final Main main, HorizontalLayout hl, final Base base, final Meter meter, boolean canWrite) { final Database database = main.getDatabase(); HorizontalLayout hl2 = new HorizontalLayout(); hl2.setWidth("300px"); hl2.setHeight("100%"); hl.addComponent(hl2); hl.setComponentAlignment(hl2, Alignment.MIDDLE_LEFT); final Indicator i = meter.getPossibleIndicator(database); if (i != null) { Datatype datatype = i.getDatatype(database); if (datatype instanceof EnumerationDatatype) { EnumerationDatatype enu = (EnumerationDatatype) datatype; Object value = i.getValue(); AbstractField<?> combo = enu.getEditor(main, base, i, false, null); hl2.addComponent(combo); hl2.setComponentAlignment(combo, Alignment.MIDDLE_CENTER); return value != null ? value.toString() : "null"; } } final Label label = new Label(meter.describe(database, main.getUIState().forecastMeters)); label.setWidthUndefined(); hl2.addComponent(label); hl2.setComponentAlignment(label, Alignment.MIDDLE_CENTER); hl2.setExpandRatio(label, 1.0f); return label.getValue(); } public static void updateMeters(final Main main, boolean canWrite) { if (main.getUIState().currentItem instanceof Strategiakartta) return; final Database database = main.getDatabase(); final Base base = main.getUIState().currentItem; List<MeterDescription> descs = makeMeterDescriptions(main, base, false); if (!descs.isEmpty() || canWrite) { HorizontalLayout meterHeader = new HorizontalLayout(); meterHeader.setSpacing(true); Label header = new Label("Mittarit"); main.propertyCells.add(Utils.excelRow(header.getValue())); header.setHeight("32px"); header.addStyleName(ValoTheme.LABEL_HUGE); header.addStyleName(ValoTheme.LABEL_BOLD); meterHeader.addComponent(header); meterHeader.setComponentAlignment(header, Alignment.BOTTOM_CENTER); if (canWrite) { final Image editMeters = new Image(null, new ThemeResource("chart_bar_edit.png")); editMeters.setHeight("24px"); editMeters.setWidth("24px"); editMeters.addClickListener(new MouseEvents.ClickListener() { private static final long serialVersionUID = 2661060702097338722L; @Override public void click(com.vaadin.event.MouseEvents.ClickEvent event) { Utils.loseFocus(editMeters); manageMeters(main, main.getUIState().currentItem); } }); meterHeader.addComponent(editMeters); meterHeader.setComponentAlignment(editMeters, Alignment.BOTTOM_CENTER); } main.properties.addComponent(meterHeader); main.properties.setComponentAlignment(meterHeader, Alignment.MIDDLE_CENTER); VerticalLayout meters = new VerticalLayout(); boolean showYears = main.getUIState().time.equals(Property.AIKAVALI_KAIKKI); Property time = Property.find(database, Property.AIKAVALI); int index = 0; for (final MeterDescription desc : descs) { ArrayList<String> excelRow = new ArrayList<String>(); final Meter meter = desc.meter; final HorizontalLayout hl = new HorizontalLayout(); hl.addStyleName((((index++) & 1) == 0) ? "evenProperty" : "oddProperty"); hl.setSpacing(true); Label l = new Label(desc.caption); excelRow.add(l.getValue().replace("%nbsp", "")); l.setContentMode(ContentMode.HTML); l.setWidth("450px"); l.addStyleName("propertyName"); l.setData(desc); hl.addComponent(l); hl.setComponentAlignment(l, Alignment.MIDDLE_LEFT); String value = updateMeterValue(main, hl, base, meter, canWrite); excelRow.add(value); String shortComment = ""; Indicator indicator = meter.getPossibleIndicator(database); if (indicator != null) shortComment = indicator.getValueShortComment(); Label comment = new Label(shortComment); comment.setWidth("150px"); hl.addComponent(comment); hl.setComponentAlignment(comment, Alignment.MIDDLE_LEFT); excelRow.add(comment.getValue()); if (showYears) { HorizontalLayout hl2 = new HorizontalLayout(); hl2.setWidth("70px"); hl2.setHeight("100%"); hl.addComponent(hl2); hl.setComponentAlignment(hl2, Alignment.MIDDLE_LEFT); String years = time.getPropertyValue(meter); if (years == null) years = Property.AIKAVALI_KAIKKI; final Label region = new Label(years); region.setWidthUndefined(); excelRow.add(region.getValue()); hl2.addComponent(region); hl2.setComponentAlignment(region, Alignment.MIDDLE_CENTER); } AbsoluteLayout image = new AbsoluteLayout(); image.setWidth("32px"); image.setHeight("32px"); image.addStyleName("meterColor" + index); String color = meter.getTrafficColor(database); Styles styles = Page.getCurrent().getStyles(); styles.add( ".fi_semantum_strategia div." + "meterColor" + index + " { background: " + color + "; }"); hl.addComponent(image); hl.setComponentAlignment(image, Alignment.MIDDLE_CENTER); hl.setExpandRatio(image, 0.0f); meters.addComponent(hl); meters.setComponentAlignment(hl, Alignment.MIDDLE_CENTER); ThemeResource res = desc.meter.showInMap ? new ThemeResource("zoom.png") : new ThemeResource("zoom_out.png"); final Image show = new Image(); show.setSource(res); show.setHeight("24px"); show.setWidth("24px"); if (canWrite) { show.setDescription("Klikkaamalla voit valita, nytetnk mittaria strategiakartassa"); show.addClickListener(new MouseEvents.ClickListener() { private static final long serialVersionUID = 7156984656942915939L; @Override public void click(com.vaadin.event.MouseEvents.ClickEvent event) { desc.meter.setShowInMap(!desc.meter.showInMap); Updates.update(main, true); } }); } hl.addComponent(show); hl.setComponentAlignment(show, Alignment.MIDDLE_CENTER); final Image wiki = new Image(); wiki.setSource(new ThemeResource("table_edit.png")); wiki.setHeight("24px"); wiki.setWidth("24px"); wiki.setDescription("Klikkaamalla voit siirty tausta-asiakirjaan"); wiki.addClickListener(new MouseEvents.ClickListener() { private static final long serialVersionUID = 7156984656942915939L; @Override public void click(com.vaadin.event.MouseEvents.ClickEvent event) { Wiki.openWiki(main, desc.meter); } }); hl.addComponent(wiki); hl.setComponentAlignment(wiki, Alignment.MIDDLE_CENTER); if (canWrite) { final Button principalButton = new Button(); if (meter.isPrincipal) { principalButton.setCaption("Poista kokonaisarvio"); } else { principalButton.setCaption("Aseta kokonaisarvioksi"); } principalButton.setStyleName(ValoTheme.BUTTON_TINY); principalButton.addClickListener(new ClickListener() { private static final long serialVersionUID = 8247560202892661226L; @Override public void buttonClick(ClickEvent event) { if (meter.isPrincipal) { meter.isPrincipal = false; } else { for (Meter m : base.getMeters(database)) m.isPrincipal = false; meter.isPrincipal = true; } Updates.update(main, true); } }); hl.addComponent(principalButton); hl.setComponentAlignment(principalButton, Alignment.MIDDLE_CENTER); } main.propertyCells.add(excelRow); } meters.addLayoutClickListener(new LayoutClickListener() { private static final long serialVersionUID = 3295743025581923380L; private String extractData(Component c) { if (c instanceof AbstractComponent) { Object data = ((AbstractComponent) c).getData(); if (data instanceof MeterDescription) { MeterDescription desc = (MeterDescription) data; return desc.meter.getDescription(database); } } return null; } @Override public void layoutClick(LayoutClickEvent event) { String desc = extractData(event.getClickedComponent()); if (desc == null) return; String content = "<div style=\"width: 700px; border: 2px solid; padding: 5px\">"; content += "<div style=\"text-align: center; white-space:normal; font-size: 36px; padding: 10px\">" + desc + "</div>"; content += "</div>"; Notification n = new Notification(content, Notification.Type.HUMANIZED_MESSAGE); n.setHtmlContentAllowed(true); n.show(Page.getCurrent()); } }); main.properties.addComponent(meters); main.properties.setComponentAlignment(meters, Alignment.MIDDLE_CENTER); } } public static List<MeterDescription> makeMeterDescriptions(Main main, Base base, boolean filterShow) { List<MeterDescription> descs = new ArrayList<MeterDescription>(); fillMeterDescriptions(main, base, "", "", filterShow, descs); return descs; } private static void fillMeterDescriptions(Main main, Base base, String indent, String numbering, boolean filterShow, List<MeterDescription> result) { final Database database = main.getDatabase(); List<Meter> meters = base.getMeters(database); for (int i = 0; i < meters.size(); i++) { Meter meter = meters.get(i); if (!meter.isActive(main)) continue; if (filterShow && !meter.showInMap) continue; String nr = numbering.isEmpty() ? Integer.toString(i + 1) : numbering + "." + Integer.toString(i + 1); String desc = indent + nr + ". " + meter.getCaption(database); result.add(new MeterDescription(meter, nr, desc)); fillMeterDescriptions(main, meter, makeIndent(indent), nr, filterShow, result); } } private static void makeMeterTable(Main main, Base base, final Table table) { @SuppressWarnings("unchecked") Collection<Meter> selection = (Collection<Meter>) table.getValue(); table.removeAllItems(); List<MeterDescription> descs = makeMeterDescriptions(main, base, false); fillMeterTable(main, base, table, descs); for (Meter m : selection) table.select(m); } private static void fillMeterTable(Main main, Base base, final Table table, List<MeterDescription> descs) { boolean showYears = main.getUIState().time.equals(Property.AIKAVALI_KAIKKI); final Database database = main.getDatabase(); Property aika = Property.find(database, Property.AIKAVALI); for (int i = 0; i < descs.size(); i++) { MeterDescription desc = descs.get(i); Meter meter = desc.meter; Label text = new Label(desc.caption); text.setContentMode(ContentMode.HTML); String year = aika.getPropertyValue(meter); if (showYears) table.addItem(new Object[] { text, year }, meter); else table.addItem(new Object[] { text }, meter); } } private static String makeIndent(String indent) { return " " + indent; } static class ImplementationMeter extends Base { private static final long serialVersionUID = 7707700206812885773L; protected ImplementationMeter() { super("", "Toteutuksen tila", ""); } @Override public Base getOwner(Database database) { return null; } } static class MeterSpec { public static Base IMPLEMENTATION = new ImplementationMeter(); private Object source; private String text; public MeterSpec(Database database, Base source) { this.source = source; text = source.getText(database); if (source instanceof Indicator) text = text + " [Indikaattori]"; else if (source instanceof EnumerationDatatype) text = text + " [Monivalinta]"; } public String toString() { return text; } @SuppressWarnings("unchecked") public <T> T getSource() { return (T) source; } } public static void manageMeters(final Main main, final Base base) { String currentTime = main.getUIState().time; boolean showYears = currentTime.equals(Property.AIKAVALI_KAIKKI); final Database database = main.getDatabase(); VerticalLayout content = new VerticalLayout(); content.setSizeFull(); content.setSpacing(true); final Table table = new Table(); table.setSelectable(true); table.setMultiSelect(true); table.addStyleName(ValoTheme.TABLE_SMALL); table.addStyleName(ValoTheme.TABLE_COMPACT); table.addContainerProperty("Mittari", Label.class, null); if (showYears) table.addContainerProperty("Vuosi", String.class, null); table.setWidth("100%"); table.setHeight("100%"); table.setNullSelectionAllowed(true); table.setEditable(false); table.setColumnExpandRatio("Mittari", 2.0f); if (showYears) table.setColumnExpandRatio("Vuosi", 0.0f); makeMeterTable(main, base, table); content.addComponent(table); content.setExpandRatio(table, 1.0f); abstract class MeterButtonListener implements Button.ClickListener { private static final long serialVersionUID = -6640950006518632633L; protected Meter getPossibleSelection() { Object selection = table.getValue(); Collection<?> selected = (Collection<?>) selection; if (selected.size() != 1) return null; return (Meter) selected.iterator().next(); } @SuppressWarnings("unchecked") protected Collection<Meter> getSelection() { return (Collection<Meter>) table.getValue(); } protected Map<Base, List<Meter>> getSelectionByParent(Database database) { return metersByParent(database, getSelection()); } } final Button removeMeters = new Button("Poista", new MeterButtonListener() { private static final long serialVersionUID = 2957964892664902859L; public void buttonClick(ClickEvent event) { for (Meter r : getSelection()) { Base owner = r.getOwner(database); if (owner != null) owner.removeMeter(r); } makeMeterTable(main, base, table); Updates.update(main, true); } }); removeMeters.addStyleName(ValoTheme.BUTTON_TINY); final Button moveUp = new Button("Siirr ylemms", new MeterButtonListener() { private static final long serialVersionUID = 8434251773337788784L; public void buttonClick(ClickEvent event) { Map<Base, List<Meter>> sel = getSelectionByParent(database); if (sel == null) return; for (Map.Entry<Base, List<Meter>> entry : sel.entrySet()) { entry.getKey().moveMetersUp(entry.getValue()); } makeMeterTable(main, base, table); Updates.update(main, true); } }); moveUp.addStyleName(ValoTheme.BUTTON_TINY); final Button moveDown = new Button("Siirr alemmas", new MeterButtonListener() { private static final long serialVersionUID = -5382367112305541842L; public void buttonClick(ClickEvent event) { for (Map.Entry<Base, List<Meter>> entry : getSelectionByParent(database).entrySet()) { entry.getKey().moveMetersDown(entry.getValue()); } makeMeterTable(main, base, table); Updates.update(main, true); } }); moveDown.addStyleName(ValoTheme.BUTTON_TINY); final Button modify = new Button("Mrit"); modify.addClickListener(new MeterButtonListener() { private static final long serialVersionUID = -7109999546516429095L; public void buttonClick(ClickEvent event) { Meter meter = getPossibleSelection(); if (meter == null) return; editMeter(main, base, meter); } }); modify.addStyleName(ValoTheme.BUTTON_TINY); final ComboBox indicatorSelect = new ComboBox(); indicatorSelect.setWidth("100%"); indicatorSelect.setNullSelectionAllowed(false); indicatorSelect.addStyleName(ValoTheme.COMBOBOX_TINY); indicatorSelect.setCaption("Mrittj"); final Strategiakartta map = database.getMap(base); // Indikaattorit for (Indicator i : map.getIndicators(database)) { MeterSpec spec = new MeterSpec(database, i); indicatorSelect.addItem(spec); indicatorSelect.select(spec); } // Enumeraatiot for (Datatype enu : Datatype.enumerate(database)) { if (enu instanceof EnumerationDatatype) { MeterSpec spec = new MeterSpec(database, enu); indicatorSelect.addItem(spec); indicatorSelect.select(spec); } } // Sisnrakennetut { MeterSpec spec = new MeterSpec(database, MeterSpec.IMPLEMENTATION); indicatorSelect.addItem(spec); indicatorSelect.select(spec); } indicatorSelect.setTextInputAllowed(false); final Button addMeter = new Button("Lis ptasolle", new Button.ClickListener() { private static final long serialVersionUID = -5178621686299637238L; public void buttonClick(ClickEvent event) { MeterSpec spec = (MeterSpec) indicatorSelect.getValue(); Object source = spec.getSource(); if (source instanceof Indicator) { Indicator ind = (Indicator) source; Meter.addIndicatorMeter(main, base, ind, Property.AIKAVALI_KAIKKI); } else if (source instanceof EnumerationDatatype) { EnumerationDatatype dt = (EnumerationDatatype) source; Indicator ind = Indicator.create(database, "Uusi " + dt.getId(database), dt); ind.update(main, base, dt.getDefaultValue(), false, "", "Alkuarvo"); ind.update(main, base, dt.getDefaultForecast(), true, "", "Alkuarvo"); Meter.addIndicatorMeter(main, base, ind, Property.AIKAVALI_KAIKKI); } makeMeterTable(main, base, table); Updates.update(main, true); } }); addMeter.addStyleName(ValoTheme.BUTTON_TINY); final Button addSubmeter = new Button("Lis valitun alle", new MeterButtonListener() { private static final long serialVersionUID = -1250285092312682737L; public void buttonClick(ClickEvent event) { Meter meter = getPossibleSelection(); if (meter == null) return; MeterSpec spec = (MeterSpec) indicatorSelect.getValue(); Object source = spec.getSource(); if (source instanceof Indicator) { Indicator ind = (Indicator) source; Meter.addIndicatorMeter(main, meter, ind, Property.AIKAVALI_KAIKKI); } else if (source instanceof EnumerationDatatype) { EnumerationDatatype dt = (EnumerationDatatype) source; Indicator ind = Indicator.create(database, "Uusi " + dt.getId(database), dt); ind.update(main, base, dt.getDefaultValue(), false, "", "Alkuarvo"); ind.update(main, base, dt.getDefaultForecast(), true, "", "Alkuarvo"); Meter.addIndicatorMeter(main, meter, ind, Property.AIKAVALI_KAIKKI); } makeMeterTable(main, base, table); Updates.update(main, true); } }); addSubmeter.addStyleName(ValoTheme.BUTTON_TINY); final Runnable setStates = new Runnable() { @Override public void run() { Object selection = table.getValue(); Collection<?> selected = (Collection<?>) selection; if (!selected.isEmpty()) { removeMeters.setEnabled(true); moveUp.setEnabled(true); moveDown.setEnabled(true); if (selected.size() == 1) { modify.setEnabled(true); addSubmeter.setEnabled(true); } else { addSubmeter.setEnabled(false); modify.setEnabled(false); } } else { moveUp.setEnabled(false); moveDown.setEnabled(false); removeMeters.setEnabled(false); addSubmeter.setEnabled(false); modify.setEnabled(false); } } }; table.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 6439090862804667322L; @Override public void valueChange(ValueChangeEvent event) { setStates.run(); } }); setStates.run(); HorizontalLayout hl2 = new HorizontalLayout(); hl2.setSpacing(true); hl2.setWidthUndefined(); hl2.addComponent(modify); hl2.setComponentAlignment(modify, Alignment.TOP_LEFT); hl2.setExpandRatio(modify, 0.0f); hl2.addComponent(removeMeters); hl2.setComponentAlignment(removeMeters, Alignment.TOP_LEFT); hl2.setExpandRatio(removeMeters, 0.0f); hl2.addComponent(moveUp); hl2.setComponentAlignment(moveUp, Alignment.TOP_LEFT); hl2.setExpandRatio(moveUp, 0.0f); hl2.addComponent(moveDown); hl2.setComponentAlignment(moveDown, Alignment.TOP_LEFT); hl2.setExpandRatio(moveDown, 0.0f); HorizontalLayout hl3 = new HorizontalLayout(); hl3.setSpacing(true); hl3.setWidth("100%"); hl3.addComponent(addMeter); hl3.setComponentAlignment(addMeter, Alignment.BOTTOM_LEFT); hl3.setExpandRatio(addMeter, 0.0f); hl3.addComponent(addSubmeter); hl3.setComponentAlignment(addSubmeter, Alignment.BOTTOM_LEFT); hl3.setExpandRatio(addSubmeter, 0.0f); hl3.addComponent(indicatorSelect); hl3.setComponentAlignment(indicatorSelect, Alignment.BOTTOM_LEFT); hl3.setExpandRatio(indicatorSelect, 1.0f); content.addComponent(hl2); content.setComponentAlignment(hl2, Alignment.MIDDLE_CENTER); content.setExpandRatio(hl2, 0.0f); content.addComponent(hl3); content.setComponentAlignment(hl3, Alignment.BOTTOM_LEFT); content.setExpandRatio(hl3, 0.0f); HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(false); final Window dialog = Dialogs.makeDialog(main, "450px", "600px", "Hallitse mittareita", "Sulje", content, buttons); } public static void editMeter(final Main main, final Base base, final Meter meter) { Database database = main.getDatabase(); final VerticalLayout content = new VerticalLayout(); content.setSizeFull(); content.setHeightUndefined(); content.setSpacing(true); HorizontalLayout hl = new HorizontalLayout(); hl.setWidth("100%"); hl.setSpacing(true); hl.setMargin(false); final TextField tf = new TextField(); tf.setCaption("Lyhytnimi"); tf.setValue(meter.getId(database)); tf.addStyleName(ValoTheme.TEXTFIELD_TINY); tf.setWidth("100%"); hl.addComponent(tf); hl.setComponentAlignment(tf, Alignment.TOP_CENTER); hl.setExpandRatio(tf, 1.0f); final TextField tf1 = new TextField(); tf1.setCaption("Teksti"); tf1.setValue(meter.getText(database)); tf1.addStyleName(ValoTheme.TEXTFIELD_TINY); tf1.setWidth("100%"); hl.addComponent(tf1); hl.setComponentAlignment(tf1, Alignment.TOP_CENTER); hl.setExpandRatio(tf1, 2.0f); content.addComponent(hl); content.setComponentAlignment(hl, Alignment.TOP_CENTER); content.setExpandRatio(hl, 0.0f); final TextField tf2 = new TextField(); tf2.setCaption("Voimassaolo"); tf2.setValue(Utils.getValidity(database, meter)); tf2.addStyleName(ValoTheme.TEXTFIELD_TINY); tf2.setWidth("100%"); content.addComponent(tf2); content.setComponentAlignment(tf2, Alignment.TOP_CENTER); content.setExpandRatio(tf2, 0.0f); final TextArea ta = new TextArea(); ta.setCaption("Mritys"); ta.setValue(meter.getText(database)); ta.addStyleName(ValoTheme.TEXTAREA_TINY); ta.setHeight("100%"); ta.setWidth("100%"); content.addComponent(ta); content.setComponentAlignment(ta, Alignment.TOP_CENTER); content.setExpandRatio(ta, 1.0f); final TrafficValuation valuation = meter.trafficValuation; final Runnable onOK = valuation != null ? valuation.getEditor(content, main, meter) : null; Indicator indicator = meter.getPossibleIndicator(database); if (indicator != null) { final Label ta2 = Indicator.makeHistory(database, indicator, main.getUIState().forecastMeters); content.addComponent(ta2); content.setComponentAlignment(ta2, Alignment.MIDDLE_CENTER); content.setExpandRatio(ta2, 1.0f); } HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(false); Button ok = new Button("Tallenna", new Button.ClickListener() { private static final long serialVersionUID = 1992235622970234624L; public void buttonClick(ClickEvent event) { if (onOK != null) onOK.run(); meter.modifyId(main, tf.getValue()); meter.modifyText(main, tf1.getValue()); Utils.modifyValidity(main, meter, tf2.getValue()); meter.modifyDescription(main, ta.getValue()); Updates.update(main, true); manageMeters(main, main.getUIState().currentItem); } }); buttons.addComponent(ok); Button close = new Button("Sulje"); buttons.addComponent(close); final Window dialog = Dialogs.makeDialog(main, "500px", "800px", "Mrit mittaria", null, content, buttons); close.addClickListener(new Button.ClickListener() { private static final long serialVersionUID = -8065367213523520602L; public void buttonClick(ClickEvent event) { main.removeWindow(dialog); manageMeters(main, main.getUIState().currentItem); } }); } public void setShowInMap(boolean value) { this.showInMap = value; } public String trafficValuationDescription() { return trafficValuation.toString(); } @Override public String getDescription(Database database) { return getDescription(database, true); } public String getDescription(Database database, boolean forecast) { Indicator indicator = getPossibleIndicator(database); if (indicator != null) { double value = value(database, forecast); return "" + (int) (100.0 * value) + "%"; } return super.getDescription(database); } public String getVerboseDescription(Database database, boolean forecast) { Indicator indicator = getPossibleIndicator(database); if (indicator != null) { String result = indicator.getValueShortComment(); if (result == null || result.isEmpty()) { double value = value(database, forecast); return "" + (int) (100.0 * value) + "%"; } else return result; } else if (description != null && !description.isEmpty()) { return description; } return super.getDescription(database); } }