From 29888379c63c89ecdde2e51e58ff6d4bf02fe24f Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Tue, 22 Sep 2020 10:27:13 +0200 Subject: [PATCH] implemented Locomotive and Train management --- pom.xml | 2 +- resources/css/style.css | 6 ++ .../java/de/srsoftware/web4rail/Plan.java | 45 +++++++++++++-- .../de/srsoftware/web4rail/moving/Car.java | 35 +++++++++--- .../web4rail/moving/Locomotive.java | 24 ++++++++ .../de/srsoftware/web4rail/moving/Train.java | 55 ++++++++++++++----- .../de/srsoftware/web4rail/tags/Button.java | 15 +++++ .../de/srsoftware/web4rail/tags/Fieldset.java | 13 +++++ .../de/srsoftware/web4rail/tags/Input.java | 22 ++++++++ .../de/srsoftware/web4rail/tags/Label.java | 13 +++++ .../de/srsoftware/web4rail/tags/Select.java | 18 ++++++ .../de/srsoftware/web4rail/tiles/Block.java | 31 ++++++++--- .../web4rail/tiles/StretchableTile.java | 4 +- .../de/srsoftware/web4rail/tiles/Tile.java | 13 +++-- 14 files changed, 254 insertions(+), 42 deletions(-) create mode 100644 src/main/java/de/srsoftware/web4rail/tags/Button.java create mode 100644 src/main/java/de/srsoftware/web4rail/tags/Fieldset.java create mode 100644 src/main/java/de/srsoftware/web4rail/tags/Input.java create mode 100644 src/main/java/de/srsoftware/web4rail/tags/Label.java create mode 100644 src/main/java/de/srsoftware/web4rail/tags/Select.java diff --git a/pom.xml b/pom.xml index 837427f..c4baaa8 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 0.3.8 + 0.4.0 Web4Rail Java Model Railway Control https://github.com/StephanRichter/Web4Rail diff --git a/resources/css/style.css b/resources/css/style.css index b107d79..4b833ef 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -188,4 +188,10 @@ svg.straight .right{ polygon.oneway{ fill: lime; stroke-width:0; +} + +fieldset{ + float: left; + border: 1px solid black; + border-radius: 5px; } \ No newline at end of file diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index a3567ed..e24ab06 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -88,7 +88,7 @@ public class Plan { } } - private static final String ACTION = "action"; + public static final String ACTION = "action"; private static final String ACTION_ADD = "add"; private static final String ACTION_ANALYZE = "analyze"; private static final String ACTION_MOVE = "move"; @@ -108,6 +108,9 @@ public class Plan { private static final String ACTION_TRAIN = "train"; private static final String ACTION_LOCOS = "locos"; private static final String ACTION_TRAINS = "trains"; + private static final String ACTION_CAR = "car"; + public static final String ACTION_ADD_LOCO = "addLoco"; + public static final String ACTION_ADD_TRAIN = "addTrain"; public HashMap tiles = new HashMap(); private HashSet blocks = new HashSet(); @@ -169,6 +172,12 @@ public class Plan { return blocks; } + private Object carAction(HashMap params) { + Car car = Car.get(params.get(Car.ID)); + if (car == null) return t("No car with id {} found!",params.get(Car.ID)); + return car.properties(); + } + private Object click(Tile tile) throws IOException { if (tile == null) return null; return tile.click(); @@ -260,6 +269,16 @@ public class Plan { return plan; } + private Object locoAction(HashMap params) throws IOException { + switch (params.get(ACTION)) { + case ACTION_ADD_LOCO: + new Locomotive(params.get(Locomotive.NAME)); + break; + } + + return html(); + } + private Tag menu() throws IOException { Tag menu = new Tag("div").clazz("menu"); actionMenu().addTo(menu); @@ -350,6 +369,13 @@ public class Plan { switch (action) { case ACTION_ADD: return addTile(params.get(TILE),params.get(X),params.get(Y),null); + case ACTION_ADD_LOCO: + return locoAction(params); + case ACTION_ADD_TRAIN: + case ACTION_TRAIN: + return trainAction(params); + case ACTION_CAR: + return carAction(params); case ACTION_CLICK: return click(get(params.get(Tile.ID),true)); case ACTION_ANALYZE: @@ -362,8 +388,6 @@ public class Plan { return routeProperties(Integer.parseInt(params.get(ID))); case ACTION_SAVE: return saveTo(params.get(FILE)); - case ACTION_TRAIN: - return trainAction(params); case ACTION_TRAINS: return Train.manager(); case ACTION_UPDATE: @@ -381,8 +405,19 @@ public class Plan { } private Object trainAction(HashMap params) throws IOException { - Object result = Train.action(params); - return result instanceof Train ? html() : result; + LOG.debug("Params: {}",params); + switch (params.get(ACTION)) { + case ACTION_ADD_TRAIN: + Locomotive loco = (Locomotive) Locomotive.get(params.get(Train.LOCO_ID)); + if (loco == null) return t("unknown locomotive: {}",params.get(Locomotive.ID)); + new Train(loco); + break; + case ACTION_TRAIN: + Object result = Train.action(params); + if (!(result instanceof Train)) return result; + break; + } + return html(); } public Route route(int routeId) { diff --git a/src/main/java/de/srsoftware/web4rail/moving/Car.java b/src/main/java/de/srsoftware/web4rail/moving/Car.java index e131089..f8b3e13 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Car.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Car.java @@ -14,16 +14,18 @@ import org.json.JSONObject; import de.keawe.tools.translations.Translation; import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Application; +import de.srsoftware.web4rail.Window; public class Car { - private static final String ID = "id"; - private static final String NAME = "name"; + public static final String ID = "id"; + public static final String NAME = "name"; private static final String LENGTH = "length"; private static final String SHOW = "show"; static HashMap cars = new HashMap(); public int length; private String name; private String id; + private Train train; public Car(String name) { this(name,null); @@ -67,11 +69,7 @@ public class Car { public Tag link(String tagClass) { return new Tag(tagClass).clazz("link").attr("onclick","car("+id+",'"+Car.SHOW+"')").content(name()); } - - String name(){ - return name; - } - + public static void loadAll(String filename) throws IOException { cars.clear(); BufferedReader file = new BufferedReader(new FileReader(filename)); @@ -93,6 +91,20 @@ public class Car { if (json.has(LENGTH)) length = json.getInt(LENGTH); } + String name(){ + return name; + } + + public Object properties() { + Window win = new Window("car-props", t("Properties of {}",this)); + Tag list = new Tag("ul"); + if (train != null) { + train.link("span").addTo(new Tag("li").content(t("Train:")+" ")).addTo(list); + } + list.addTo(win); + return win; + } + public static void saveAll(String filename) throws IOException { BufferedWriter file = new BufferedWriter(new FileWriter(filename)); for (Entry entry: cars.entrySet()) { @@ -105,4 +117,13 @@ public class Car { protected static String t(String txt, Object...fills) { return Translation.get(Application.class, txt, fills); } + + @Override + public String toString() { + return getClass().getSimpleName()+"("+name()+")"; + } + + public void train(Train train) { + this.train = train; + } } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java b/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java index 3f2656d..925476b 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java @@ -1,9 +1,17 @@ package de.srsoftware.web4rail.moving; +import java.util.Vector; + import org.json.JSONObject; import de.srsoftware.tools.Tag; +import de.srsoftware.web4rail.Plan; import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.tags.Button; +import de.srsoftware.web4rail.tags.Fieldset; +import de.srsoftware.web4rail.tags.Form; +import de.srsoftware.web4rail.tags.Input; +import de.srsoftware.web4rail.tags.Label; public class Locomotive extends Car { @@ -28,6 +36,14 @@ public class Locomotive extends Car { return json; } + static Vector list() { + Vector locos = new Vector(); + for (Car car : Car.cars.values()) { + if (car instanceof Locomotive) locos.add((Locomotive) car); + } + return locos; + } + @Override protected void load(JSONObject json) { super.load(json); @@ -50,6 +66,14 @@ public class Locomotive extends Car { } } list.addTo(win); + + Form form = new Form(); + new Input(Plan.ACTION, Plan.ACTION_ADD_LOCO).hideIn(form); + Fieldset fieldset = new Fieldset(t("add new locomotive")); + new Input(Locomotive.NAME, t("new locomotive")).addTo(new Label(t("Name:")+" ")).addTo(fieldset); + new Button(t("save")).addTo(fieldset); + fieldset.addTo(form).addTo(win); return win; } + } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index 1e08c6b..edd984c 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -5,6 +5,7 @@ import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -19,11 +20,17 @@ import org.slf4j.LoggerFactory; import de.keawe.tools.translations.Translation; import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Application; +import de.srsoftware.web4rail.Plan; import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.tags.Button; import de.srsoftware.web4rail.tags.Checkbox; +import de.srsoftware.web4rail.tags.Fieldset; import de.srsoftware.web4rail.tags.Form; +import de.srsoftware.web4rail.tags.Input; +import de.srsoftware.web4rail.tags.Label; +import de.srsoftware.web4rail.tags.Select; import de.srsoftware.web4rail.tiles.Block; import de.srsoftware.web4rail.tiles.Contact; import de.srsoftware.web4rail.tiles.Signal; @@ -93,6 +100,8 @@ public class Train { private static final String MODE_STOP = "stop"; + public static final String LOCO_ID = "locoId"; + public int speed = 0; private Autopilot autopilot = null; @@ -135,7 +144,8 @@ public class Train { if (car == null) return; if (car instanceof Locomotive) { locos.add((Locomotive) car); - } else cars.add(car); + } else cars.add(car); + car.train(this); } private String automatic() { @@ -146,7 +156,7 @@ public class Train { return t("{} now in auto-mode",this); } - public void block(Block block) { + public void block(Block block) throws IOException { this.block = block; } @@ -187,6 +197,10 @@ public class Train { return new Tag(tagClass).clazz("link").attr("onclick","train("+id+",'"+Train.MODE_SHOW+"')").content(name()); } + public static Collection list() { + return trains.values(); + } + public static void loadAll(String filename) throws IOException { BufferedReader file = new BufferedReader(new FileReader(filename)); String line = file.readLine(); @@ -217,6 +231,20 @@ public class Train { train.link("li").addTo(list); } list.addTo(win); + + Form form = new Form(); + new Input(Plan.ACTION, Plan.ACTION_ADD_TRAIN).hideIn(form); + Fieldset fieldset = new Fieldset(t("add new train")); + new Input(Train.NAME, t("new train")).addTo(new Label(t("Name:")+" ")).addTo(fieldset); + + Select select = new Select(LOCO_ID); + for (Locomotive loco : Locomotive.list()) select.addOption(loco.id(),loco.name()); + select.addTo(new Label(t("Locomotive:")+" ")).addTo(fieldset); + + new Button(t("save")).addTo(fieldset); + fieldset.addTo(form).addTo(win); + + return win; } @@ -238,19 +266,20 @@ public class Train { Window window = new Window("train-properties",t("Properties of {}",getClass().getSimpleName())); Form form = new Form(); - new Tag("input").attr("type", "hidden").attr("name","action").attr("value", "train").addTo(form); - new Tag("input").attr("type", "hidden").attr("name",ID).attr("value", ""+id).addTo(form); - new Tag("input").attr("type", "hidden").attr("name","mode").attr("value", MODE_UPDATE).addTo(form); + new Input("action","train").hideIn(form); + new Input(ID,id).hideIn(form); + new Input("mode",MODE_UPDATE).hideIn(form); - Checkbox pp = new Checkbox(PUSH_PULL, t("Push-pull train"), pushPull); - pp.addTo(form); - new Tag("button").attr("type", "submit").content(t("save")).addTo(form).addTo(window); + new Checkbox(PUSH_PULL, t("Push-pull train"), pushPull).addTo(form); + new Button(t("save")).addTo(form).addTo(window); Tag list = new Tag("ul"); - Tag locos = new Tag("li").content(t("Locomotives:")); - Tag l2 = new Tag("ul"); - for (Locomotive loco : this.locos) new Tag("li").content(loco.name()).addTo(l2); - l2.addTo(locos).addTo(list); + if (!locos.isEmpty()) { + Tag locos = new Tag("li").content(t("Locomotives:")); + Tag l2 = new Tag("ul"); + for (Locomotive loco : this.locos) loco.link("li").addTo(l2); + l2.addTo(locos).addTo(list); + } if (block != null) { new Tag("li").content(t("Current location: {}",block)).addTo(list); @@ -317,7 +346,7 @@ public class Train { private Object stop() { autopilot.stop = true; autopilot = null; - return t("{} stopping at next block {}"); + return t("{} stopping at next block.",this); } private static String t(String message, Object...fills) { diff --git a/src/main/java/de/srsoftware/web4rail/tags/Button.java b/src/main/java/de/srsoftware/web4rail/tags/Button.java new file mode 100644 index 0000000..7d237ad --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/tags/Button.java @@ -0,0 +1,15 @@ +package de.srsoftware.web4rail.tags; + +import de.srsoftware.tools.Tag; + +public class Button extends Tag { + + private static final long serialVersionUID = -7785030725633284515L; + + public Button(String text) { + super("button"); + attr("type", "submit"); + content(text); + } + +} diff --git a/src/main/java/de/srsoftware/web4rail/tags/Fieldset.java b/src/main/java/de/srsoftware/web4rail/tags/Fieldset.java new file mode 100644 index 0000000..53ae9f7 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/tags/Fieldset.java @@ -0,0 +1,13 @@ +package de.srsoftware.web4rail.tags; + +import de.srsoftware.tools.Tag; + +public class Fieldset extends Tag { + + private static final long serialVersionUID = -1643025934527173421L; + + public Fieldset(String title) { + super("fieldset"); + if (title != null) new Tag("legend").content(title).addTo(this); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/tags/Input.java b/src/main/java/de/srsoftware/web4rail/tags/Input.java new file mode 100644 index 0000000..3bbd63d --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/tags/Input.java @@ -0,0 +1,22 @@ +package de.srsoftware.web4rail.tags; + +import de.srsoftware.tools.Tag; + +public class Input extends Tag{ + + private static final long serialVersionUID = -330127933233033028L; + + public Input(String name) { + super("input"); + attr("type","text").attr("name", name); + } + + public Input(String name, Object value) { + super("input"); + attr("type","text").attr("name", name).attr("value", value.toString()); + } + + public Tag hideIn(Tag form) { + return this.attr("type", "hidden").addTo(form); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/tags/Label.java b/src/main/java/de/srsoftware/web4rail/tags/Label.java new file mode 100644 index 0000000..88c03f4 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/tags/Label.java @@ -0,0 +1,13 @@ +package de.srsoftware.web4rail.tags; + +import de.srsoftware.tools.Tag; + +public class Label extends Tag { + + private static final long serialVersionUID = -2483427530977586755L; + + public Label(String label) { + super("label"); + content(label); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/tags/Select.java b/src/main/java/de/srsoftware/web4rail/tags/Select.java new file mode 100644 index 0000000..25c0312 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/tags/Select.java @@ -0,0 +1,18 @@ +package de.srsoftware.web4rail.tags; + +import de.srsoftware.tools.Tag; + +public class Select extends Tag { + private static final long serialVersionUID = -2168654457876014503L; + + public Select(String name) { + super("select"); + attr("name",name); + } + + public Tag addOption(Object value, Object text) { + Tag option = new Tag("option").attr("value", value.toString()).content(text.toString()); + option.addTo(this); + return option; + } +} diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index 8d68597..9523e25 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -11,6 +11,8 @@ import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Connector; import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.tags.Checkbox; +import de.srsoftware.web4rail.tags.Input; +import de.srsoftware.web4rail.tags.Label; public abstract class Block extends StretchableTile{ private static final String NAME = "name"; @@ -58,11 +60,18 @@ public abstract class Block extends StretchableTile{ public Tag propForm() { Tag form = super.propForm(); - Tag label = new Tag("label").content(t("name:")); - new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name).addTo(label); - label.addTo(form); + new Input(NAME, name).addTo(new Label(t("name:")+" ")).addTo(new Tag("p")).addTo(form); + + new Checkbox(ALLOW_TURN,t("Turn allowed"),turnAllowed).addTo(new Tag("p")).addTo(form); - new Checkbox(ALLOW_TURN,t("Turn allowed"),turnAllowed).addTo(form); + Tag select = new Tag("select").attr("name", TRAIN); + new Tag("option").attr("value","0").content(t("unset")).addTo(select); + for (Train train : Train.list()) { + Tag opt = new Tag("option").attr("value", ""+train.id); + if (this.train == train) opt.attr("selected", "selected"); + opt.content(train.toString()).addTo(select); + } + select.addTo(new Label(t("Trains:")+" ")).addTo(new Tag("p")).addTo(form); return form; } @@ -95,15 +104,21 @@ public abstract class Block extends StretchableTile{ return getClass().getSimpleName()+"("+name+") @ ("+x+","+y+")"; } - public void train(Train train) throws IOException { - if (train != null) train.block(this); - super.train(train); + public void train(Train newTrain) throws IOException { + if (train == newTrain) return; + if (train != null) train.block(null); // vorherigen Zug rauswerfen + if (newTrain != null) newTrain.block(this); + super.train(newTrain); } @Override - public Tile update(HashMap params) { + public Tile update(HashMap params) throws IOException { super.update(params); if (params.containsKey(NAME)) name=params.get(NAME); + if (params.containsKey(TRAIN)) { + long trainId = Long.parseLong(params.get(TRAIN)); + train(trainId == 0 ? null : Train.get(trainId)); + } turnAllowed = params.containsKey(ALLOW_TURN) && params.get(ALLOW_TURN).equals("on"); return this; } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java b/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java index 32a501b..aecbe77 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java @@ -39,7 +39,7 @@ public abstract class StretchableTile extends Tile { Tag label = new Tag("label").content(t("length:")); new Tag("input").attr("type", "number").attr("name","length").attr("value", length).addTo(label); - label.addTo(form); + label.addTo(new Tag("p")).addTo(form); return form; } @@ -57,7 +57,7 @@ public abstract class StretchableTile extends Tile { } @Override - public Tile update(HashMap params) { + public Tile update(HashMap params) throws IOException { super.update(params); for (Entry entry : params.entrySet()) { switch (entry.getKey()) { diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java index 03122f7..819ed3a 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java @@ -29,7 +29,9 @@ import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Window; import de.srsoftware.web4rail.moving.Train; +import de.srsoftware.web4rail.tags.Button; import de.srsoftware.web4rail.tags.Form; +import de.srsoftware.web4rail.tags.Input; import de.srsoftware.web4rail.tags.Radio; public abstract class Tile { @@ -177,16 +179,15 @@ public abstract class Tile { public Tag propForm() { Form form = new Form(); - new Tag("input").attr("type", "hidden").attr("name","action").attr("value", "update").addTo(form); - new Tag("input").attr("type", "hidden").attr("name",ID).attr("value", id()).addTo(form); + new Input("action", "update").hideIn(form); + new Input(ID,id()).hideIn(form); List pd = possibleDirections(); if (!pd.isEmpty()) { new Tag("h4").content(t("One way:")).addTo(form); new Radio("oneway","none",t("No"),oneWay == null).addTo(form); for (Direction d:pd) { - Radio radio = new Radio("oneway",d.toString(),t(d.toString()),d == oneWay); - radio.addTo(form); + new Radio("oneway",d.toString(),t(d.toString()),d == oneWay).addTo(form); } } return form; @@ -196,7 +197,7 @@ public abstract class Tile { Window window = new Window("tile-properties",t("Properties of {} @ ({},{})",getClass().getSimpleName(),x,y)); Tag form = propForm(); if (form!=null && form.children().size()>3) { - new Tag("button").attr("type", "submit").content(t("save")).addTo(form); + new Button(t("save")).addTo(form); form.addTo(window); } else { window.content(t("This tile ({}) has no properties",getClass().getSimpleName())); @@ -335,7 +336,7 @@ public abstract class Tile { plan.place(this); } - public Tile update(HashMap params) { + public Tile update(HashMap params) throws IOException { LOG.debug("{}.update({})",getClass().getSimpleName(),params); String oneWayDir = params.get("oneway"); if (oneWayDir != null) {