Browse Source

implemented signal functions

lookup-tables
Stephan Richter 5 years ago
parent
commit
e50bc039cd
  1. 2
      pom.xml
  2. 11
      resources/css/style.css
  3. 6
      resources/translations/Application.de.translation
  4. 97
      src/main/java/de/srsoftware/web4rail/Plan.java
  5. 13
      src/main/java/de/srsoftware/web4rail/Route.java
  6. 2
      src/main/java/de/srsoftware/web4rail/actions/SetSignal.java
  7. 187
      src/main/java/de/srsoftware/web4rail/tiles/Signal.java
  8. 2
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java

2
pom.xml

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>de.srsoftware</groupId> <groupId>de.srsoftware</groupId>
<artifactId>web4rail</artifactId> <artifactId>web4rail</artifactId>
<version>1.2.66</version> <version>1.3.1</version>
<name>Web4Rail</name> <name>Web4Rail</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<description>Java Model Railway Control</description> <description>Java Model Railway Control</description>

11
resources/css/style.css

@ -191,12 +191,15 @@ h2{
stroke: red; stroke: red;
} }
.signal.stop .sig_a{ .signal.red .sig_a{
fill: red; fill: red;
} }
.signal.go .sig_a{ .signal.green .sig_a{
fill: lime; fill: lime;
} }
.signal.HL2 .sig_a{
fill: yellow;
}
.sig_b{ .sig_b{
fill: black; fill: black;
@ -373,3 +376,7 @@ svg.Block text{
clear:both; clear:both;
border-radius: 0 5px 5px 5px; border-radius: 0 5px 5px 5px;
} }
#aspect-form td{
text-align: center;
}

6
resources/translations/Application.de.translation

@ -6,12 +6,14 @@ Action type\: : Aktions-Typ
Actions will only fire, if all conditions are fullfilled. : Aktionen werden nur ausgeführt, wenn alle Bedingungen erfüllt sind. Actions will only fire, if all conditions are fullfilled. : Aktionen werden nur ausgeführt, wenn alle Bedingungen erfüllt sind.
ActivateRoute : Route aktivieren ActivateRoute : Route aktivieren
add : hinzufügen add : hinzufügen
add command for {} : Kommando für {} hinzufügen
Added {} : {} hinzugefügt Added {} : {} hinzugefügt
add action : Aktion hinzufügen add action : Aktion hinzufügen
Add action to action list : Aktion zur Liste hinzufügen Add action to action list : Aktion zur Liste hinzufügen
add car\: : Waggon hinzufügen: add car\: : Waggon hinzufügen:
Add condition : Bedingung hinzufügen Add condition : Bedingung hinzufügen
add locomotive\: : Lok hinzufügen: add locomotive\: : Lok hinzufügen:
add new aspect : neues Signalbild hinzufügen
add new car : neuen Waggon anlegen add new car : neuen Waggon anlegen
Add new custom field : neues benutzerdefiniertes Feld hinzufügen Add new custom field : neues benutzerdefiniertes Feld hinzufügen
add new locomotive : neue Lok anlegen add new locomotive : neue Lok anlegen
@ -27,6 +29,8 @@ Analyze may overwrite these routes! : Durch die Analyse können diese Fahrstraß
and : und and : und
AndCondition : Und-Bedingung AndCondition : Und-Bedingung
Apply : Übernehmen Apply : Übernehmen
Aspect : Signalbild
Aspects : Signalbilder
Auto pilot : Autopilot Auto pilot : Autopilot
AutopilotActive : Autopilot aktiv AutopilotActive : Autopilot aktiv
autopilot active for train : Autopilot für Zug aktiviert autopilot active for train : Autopilot für Zug aktiviert
@ -57,6 +61,7 @@ Click here to select display! : Hier klicken, um Anzeige auszuwählen!
Click here to select train! : Hier klicken, um Zug auszuwählen! Click here to select train! : Hier klicken, um Zug auszuwählen!
click here to setup contact : Hier klicken, um Kontakt auszuwählen click here to setup contact : Hier klicken, um Kontakt auszuwählen
click here to setup relay : Hier klicken, um Relais einzurichten click here to setup relay : Hier klicken, um Relais einzurichten
click here to setup signal : Hier klicken, um Signal einzurichten
Click here to setup tag : Hier klicken, um Markierung anzugeben Click here to setup tag : Hier klicken, um Markierung anzugeben
click here to setup turnout : Hier klicken, um Weiche einzurichten click here to setup turnout : Hier klicken, um Weiche einzurichten
Click on a name to edit the entry. : Klicke auf einen Namen, um einen Eintrag zu bearbeiten. Click on a name to edit the entry. : Klicke auf einen Namen, um einen Eintrag zu bearbeiten.
@ -118,6 +123,7 @@ Function : Funktion
Hardware settings : Hardware-Einstellungen Hardware settings : Hardware-Einstellungen
Height : Höhe Height : Höhe
Help : Hilfe Help : Hilfe
Hold : an lassen
(id\: {}, length\: {}) : (Id: {}, Länge: {}) (id\: {}, length\: {}) : (Id: {}, Länge: {})
if ({})\: : falls ({}): if ({})\: : falls ({}):
If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished. If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished.

97
src/main/java/de/srsoftware/web4rail/Plan.java

@ -60,6 +60,7 @@ import de.srsoftware.web4rail.tiles.EndW;
import de.srsoftware.web4rail.tiles.Eraser; import de.srsoftware.web4rail.tiles.Eraser;
import de.srsoftware.web4rail.tiles.Relay; import de.srsoftware.web4rail.tiles.Relay;
import de.srsoftware.web4rail.tiles.Shadow; import de.srsoftware.web4rail.tiles.Shadow;
import de.srsoftware.web4rail.tiles.Signal;
import de.srsoftware.web4rail.tiles.SignalE; import de.srsoftware.web4rail.tiles.SignalE;
import de.srsoftware.web4rail.tiles.SignalN; import de.srsoftware.web4rail.tiles.SignalN;
import de.srsoftware.web4rail.tiles.SignalS; import de.srsoftware.web4rail.tiles.SignalS;
@ -186,6 +187,13 @@ public class Plan extends BaseClass{
return moveTile(params.get(DIRECTION),Id.from(params)); return moveTile(params.get(DIRECTION),Id.from(params));
case ACTION_PROPS: case ACTION_PROPS:
return properties(params); return properties(params);
case ACTION_POWER:
Signal signal = get(Id.from(params));
if (isSet(signal)) {
signal.state(params.get(Signal.STATE));
return signal.properties();
}
return null;
case ACTION_SAVE: case ACTION_SAVE:
return saveTo(DEFAULT_NAME); return saveTo(DEFAULT_NAME);
case ACTION_TIMES: case ACTION_TIMES:
@ -317,6 +325,22 @@ public class Plan extends BaseClass{
tile.unregister(); tile.unregister();
stream("remove "+tile.id()); stream("remove "+tile.id());
} }
Fieldset editableProperties() {
Fieldset fieldset = new Fieldset(t("Editable properties"));
//new Tag("h4").content(t("Editable properties")).addTo(win);
Form form = new Form("plan-properties-form");
new Input(REALM,REALM_PLAN).hideIn(form);
new Input(ACTION,ACTION_UPDATE).hideIn(form);
new Input(LENGTH_UNIT, lengthUnit).addTo(new Label(t("Length unit")+":"+NBSP)).addTo(form);
new Input(SPEED_UNIT, speedUnit).addTo(new Label(t("Speed unit")+":"+NBSP)).addTo(form);
new Input(FINAL_SPEED, Route.endSpeed).addTo(new Label(t("Lower speed limit")+":"+NBSP)).attr("title", t("Final speed after breaking, before halting")).addTo(form);
new Checkbox(FREE_BEHIND_TRAIN, t("Free tiles behind train"), Route.freeBehindTrain).attr("title", t("If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished.")).addTo(form);
new Button(t("Save"), form).addTo(form);
form.addTo(fieldset);
return fieldset;
}
/** /**
* completes a given route during a call to {@link #analyze()}. * completes a given route during a call to {@link #analyze()}.
@ -634,43 +658,10 @@ public class Plan extends BaseClass{
Window win = new Window("plan-properties", t("Properties of {}",t("Plan"))); Window win = new Window("plan-properties", t("Properties of {}",t("Plan")));
Fieldset fieldset = new Fieldset(t("Editable properties")); editableProperties().addTo(win);
//new Tag("h4").content(t("Editable properties")).addTo(win); relayProperties().addTo(win);
Form form = new Form("plan-properties-form"); routeProperties().addTo(win);
new Input(REALM,REALM_PLAN).hideIn(form);
new Input(ACTION,ACTION_UPDATE).hideIn(form);
new Input(LENGTH_UNIT, lengthUnit).addTo(new Label(t("Length unit")+":"+NBSP)).addTo(form);
new Input(SPEED_UNIT, speedUnit).addTo(new Label(t("Speed unit")+":"+NBSP)).addTo(form);
new Input(FINAL_SPEED, Route.endSpeed).addTo(new Label(t("Lower speed limit")+":"+NBSP)).attr("title", t("Final speed after breaking, before halting")).addTo(form);
new Checkbox(FREE_BEHIND_TRAIN, t("Free tiles behind train"), Route.freeBehindTrain).attr("title", t("If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished.")).addTo(form);
new Button(t("Save"), form).addTo(form);
form.addTo(fieldset).addTo(win);
fieldset = new Fieldset(t("Relays and Turnouts"));
Table table = new Table();
table.addHead(t("Address"),t("Relay/Turnout"));
List<Device> devices = BaseClass.listElements(Tile.class)
.stream()
.filter(tile -> tile instanceof Device )
.map(tile -> (Device) tile)
.sorted(Comparator.comparing(Device::address))
.collect(Collectors.toList());
for (Device device : devices) {
Tile tile = (Tile) device;
table.addRow(device.address(),tile.link(tile.toString()));
if (device.address() % 4 == 1) table.children().lastElement().clazz("group");
}
table.clazz("turnouts").addTo(fieldset).addTo(win);
fieldset = new Fieldset(t("Routes"));
table = new Table();
table.addHead(t("Name"),t("Start"),t("End"),t("Actions"));
List<Route> routes = BaseClass.listElements(Route.class);
for (Route route : routes) {
table.addRow(route.link("span",route.name()),route.link("span", route.startBlock()),route.link("span", route.endBlock()),plan.button(t("simplify name"), Map.of(ACTION,ACTION_AUTO,ROUTE,route.id().toString())));
}
table.clazz("turnouts").addTo(fieldset).addTo(win);
return win; return win;
} }
@ -697,11 +688,43 @@ public class Plan extends BaseClass{
return newRoute; return newRoute;
} }
private Fieldset relayProperties() {
Fieldset fieldset = new Fieldset(t("Relays and Turnouts"));
Table table = new Table();
table.addHead(t("Address"),t("Relay/Turnout"));
List<Device> devices = BaseClass.listElements(Tile.class)
.stream()
.filter(tile -> tile instanceof Device )
.map(tile -> (Device) tile)
.sorted(Comparator.comparing(Device::address))
.collect(Collectors.toList());
for (Device device : devices) {
Tile tile = (Tile) device;
table.addRow(device.address(),tile.link(tile.toString()));
if (device.address() % 4 == 1) table.children().lastElement().clazz("group");
}
table.clazz("turnouts").addTo(fieldset);
return fieldset;
}
@Override @Override
protected void removeChild(BaseClass child) { protected void removeChild(BaseClass child) {
if (child instanceof Tile) drop((Tile) child); if (child instanceof Tile) drop((Tile) child);
super.removeChild(child); super.removeChild(child);
} }
private Tag routeProperties() {
Fieldset fieldset = new Fieldset(t("Routes"));
Table table = new Table();
table.addHead(t("Name"),t("Start"),t("End"),t("Actions"));
List<Route> routes = BaseClass.listElements(Route.class);
for (Route route : routes) {
table.addRow(route.link("span",route.name()),route.link("span", route.startBlock()),route.link("span", route.endBlock()),plan.button(t("simplify name"), Map.of(ACTION,ACTION_AUTO,ROUTE,route.id().toString())));
}
table.clazz("turnouts").addTo(fieldset);
return fieldset;
}
public void save() throws IOException { public void save() throws IOException {
plan.stream(plan.saveTo("default")); plan.stream(plan.saveTo("default"));
@ -864,7 +887,7 @@ public class Plan extends BaseClass{
public Object update(HashMap<String, String> params) { public Object update(HashMap<String, String> params) {
super.update(params); super.update(params);
Tile tile = get(Id.from(params),true); Tile tile = get(Id.from(params),true);
if (isSet(tile)) return tile.update(params); if (isSet(tile)) return tile.update(params).properties();
if (params.containsKey(LENGTH_UNIT)) lengthUnit = params.get(LENGTH_UNIT); if (params.containsKey(LENGTH_UNIT)) lengthUnit = params.get(LENGTH_UNIT);
if (params.containsKey(SPEED_UNIT)) speedUnit = params.get(SPEED_UNIT); if (params.containsKey(SPEED_UNIT)) speedUnit = params.get(SPEED_UNIT);

13
src/main/java/de/srsoftware/web4rail/Route.java

@ -344,7 +344,10 @@ public class Route extends BaseClass {
String trigger = nextToLastContact.trigger(); String trigger = nextToLastContact.trigger();
add(trigger,new BrakeStart(this)); add(trigger,new BrakeStart(this));
add(trigger,new PreserveRoute(this)); add(trigger,new PreserveRoute(this));
for (Signal signal : signals) add(trigger,new SetSignal(this).set(signal).to(Signal.STOP));
Contact secondContact = contacts.get(1);
trigger = secondContact.trigger();
for (Signal signal : signals) add(trigger,new SetSignal(this).set(signal).to(Signal.RED));
} }
if (!contacts.isEmpty()) { if (!contacts.isEmpty()) {
Contact lastContact = contacts.lastElement(); Contact lastContact = contacts.lastElement();
@ -356,7 +359,7 @@ public class Route extends BaseClass {
Turnout.State state = entry.getValue(); Turnout.State state = entry.getValue();
add(ROUTE_SETUP,new SetTurnout(this).setTurnout(turnout).setState(state)); add(ROUTE_SETUP,new SetTurnout(this).setTurnout(turnout).setState(state));
} }
for (Signal signal : signals) add(ROUTE_START,new SetSignal(this).set(signal).to(Signal.GO)); for (Signal signal : signals) add(ROUTE_START,new SetSignal(this).set(signal).to(Signal.GREEN));
add(ROUTE_START,new SetSpeed(this).to(999)); add(ROUTE_START,new SetSpeed(this).to(999));
return this; return this;
} }
@ -425,7 +428,7 @@ public class Route extends BaseClass {
public void finish() { public void finish() {
context.clear(); // prevent delayed actions from firing after route has finished context.clear(); // prevent delayed actions from firing after route has finished
setSignals(Signal.STOP); setSignals(Signal.RED);
for (Tile tile : path) try { for (Tile tile : path) try {
tile.unset(this); tile.unset(this);
} catch (IllegalArgumentException e) {} } catch (IllegalArgumentException e) {}
@ -808,7 +811,7 @@ public class Route extends BaseClass {
public boolean reset() { public boolean reset() {
LOG.debug("{}.reset()",this); LOG.debug("{}.reset()",this);
setSignals(Signal.STOP); setSignals(Signal.RED);
for (Tile tile : path) { for (Tile tile : path) {
try { try {
tile.unset(this); tile.unset(this);
@ -859,7 +862,7 @@ public class Route extends BaseClass {
public boolean setSignals(String state) { public boolean setSignals(String state) {
LOG.debug("{}.setSignals({})",this,state); LOG.debug("{}.setSignals({})",this,state);
for (Signal signal : signals) { for (Signal signal : signals) {
if (!signal.state(isNull(state) ? Signal.GO : state)) return false; if (!signal.state(isNull(state) ? Signal.GREEN : state)) return false;
} }
return true; return true;
} }

2
src/main/java/de/srsoftware/web4rail/actions/SetSignal.java

@ -21,7 +21,7 @@ public class SetSignal extends Action {
private static final String SIGNAL = "signal"; private static final String SIGNAL = "signal";
private Signal signal = null; private Signal signal = null;
private String state = Signal.STOP; private String state = Signal.RED;
@Override @Override
public boolean fire(Context context) { public boolean fire(Context context) {

187
src/main/java/de/srsoftware/web4rail/tiles/Signal.java

@ -1,22 +1,41 @@
package de.srsoftware.web4rail.tiles; package de.srsoftware.web4rail.tiles;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.Vector; import java.util.Vector;
import de.srsoftware.tools.Tag; import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Command;
import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.Plan.Direction;
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.Table;
public abstract class Signal extends Tile { public abstract class Signal extends Tile {
public static final String STATE = "state"; public static final String STATE = "state";
public static final String STOP = "stop"; public static final String RED = "red";
public static final String GO = "go"; public static final String GREEN = "green";
public static final TreeSet<String> knownStates = new TreeSet<String>(List.of(RED, GREEN));
private final HashMap<String,HashSet<int[]>> aspects = new HashMap<String, HashSet<int[]>>();
private static final String ADDRESS = "addr";
private static final String HOLD = "hold";
private static final String NEW_ASPECT = "new_aspect";
private static final String ASPECTS = "aspects";
public static final TreeSet<String> knownStates = new TreeSet<String>(List.of(STOP, GO)); private String state = RED;
private String state = STOP;
public Signal() { public Signal() {
super(); super();
@ -30,10 +49,104 @@ public abstract class Signal extends Tile {
} }
public abstract boolean isAffectedFrom(Direction dir); public abstract boolean isAffectedFrom(Direction dir);
@Override
public JSONObject json() {
JSONObject json = super.json();
if (!aspects.isEmpty()) {
JSONObject jAspects = new JSONObject();
for (Entry<String, HashSet<int[]>> entry : aspects.entrySet()) {
String aspect = entry.getKey();
HashSet<int[]> commands = entry.getValue();
if (isSet(commands)) {
JSONArray jCommands = new JSONArray();
for (int[] data : commands) {
JSONObject jData = new JSONObject();
jData.put(ADDRESS, data[0]);
jData.put(PORT, data[1]);
jData.put(STATE, data[2]);
jData.put(HOLD, data[3]>0);
jCommands.put(jData);
}
jAspects.put(aspect, jCommands);
}
}
json.put(ASPECTS, jAspects);
}
return json;
}
@Override
public Tile load(JSONObject json) {
if (json.has(ASPECTS)) {
JSONObject jAspects = json.getJSONObject(ASPECTS);
for (String aspect : jAspects.keySet()) {
knownStates.add(aspect);
JSONArray jCommands = jAspects.getJSONArray(aspect);
jCommands.forEach(o -> {
if (o instanceof JSONObject) {
JSONObject d = (JSONObject) o;
int[] data = new int[] {d.getInt(ADDRESS),d.getInt(PORT),d.getInt(STATE),d.getBoolean(HOLD)?1:0};
HashSet<int[]> commands = aspects.get(aspect);
if (isNull(commands)) {
commands = new HashSet<int[]>();
aspects.put(aspect, commands);
}
commands.add(data);
}
});
}
}
return super.load(json);
}
@Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
Fieldset aspectEditor = new Fieldset(t("Aspects"));
aspectEditor.attr(ID, "aspect-editor");
Form form = new Form("aspect-form");
new Input(REALM,REALM_PLAN).hideIn(form);
new Input(ACTION,ACTION_UPDATE).hideIn(form);
new Input(ID,id()).hideIn(form);
Table table = new Table();
table.addHead(t("Aspect"),t("Address"),t("Port"),t("State"),t("Hold"),t("Actions"));
for (String aspect : knownStates) {
HashSet<int[]> commands = aspects.get(aspect);
if (isSet(commands)) {
Tag link = this.link("span", (Object)aspect, Map.of(ACTION,ACTION_POWER,STATE,aspect));
for (int[] command : aspects.get(aspect)) {
Button delete = this.button(t("delete"), Map.of(ACTION,ACTION_UPDATE,ACTION_DROP+"-"+aspect,command[0]+"-"+command[1]+"-"+command[2]));
table.addRow(link,command[0],command[1],command[2],command[3]==1?"✓":"",delete);
}
}
}
for (String aspect : knownStates) {
table.addRow(t("add command for {}",aspect),new Input(ADDRESS+"-"+aspect, 0).numeric(),new Input(PORT+"-"+aspect,0).numeric(),new Input(STATE+"-"+aspect,0).numeric(),new Checkbox(HOLD+"-"+aspect, "", true));
}
Tag buttons = new Tag("div");
new Button(t("Save"), form).addTo(buttons);
table.addRow(t("add new aspect"),new Input(NEW_ASPECT),"","","",buttons);
table.addTo(form);
form.addTo(aspectEditor);
postForm.add(aspectEditor);
return super.properties(preForm, formInputs, postForm);
}
public boolean state(String state) { public boolean state(String aspect) {
LOG.debug("{}.state({})",this,state); LOG.debug("{}.state({})",this,aspect);
this.state = state; this.state = aspect;
HashSet<int[]> commands = aspects.get(aspect);
if (isSet(commands)) {
for (int[] data : commands) {
Command cmd = new Command("SET {} GA "+data[0]+" "+data[1]+" "+data[2]+" "+(data[3]==1?-1:200));
LOG.debug("new Command: {}",cmd);
plan.controlUnit().queue(cmd);
}
}
plan.place(this); plan.place(this);
return true; return true;
} }
@ -44,4 +157,62 @@ public abstract class Signal extends Tile {
tag.clazz(tag.get("class")+" "+state); tag.clazz(tag.get("class")+" "+state);
return tag; return tag;
} }
@Override
public Tile update(HashMap<String, String> params) {
HashMap<String,int[]> newAspects = new HashMap<String, int[]>();
for (Entry<String, String> entry : params.entrySet()) {
String key = entry.getKey();
String val = entry.getValue().trim();
String[] parts = key.split("-");
if (parts.length>1) {
String subject = parts[0];
String aspect = parts[1];
int[] data = newAspects.get(aspect);
if (isNull(data)) {
data = new int[] {0,0,0,0};
newAspects.put(aspect,data);
}
switch (subject) {
case ADDRESS:
data[0] = Integer.parseInt(val); break;
case ACTION_DROP:
parts = val.split("-");
HashSet<int[]> commands = aspects.get(aspect);
if (isSet(commands)) for (int[] d : commands) {
if (d[0] != Integer.parseInt(parts[0])) continue;
if (d[1] != Integer.parseInt(parts[1])) continue;
if (d[2] != Integer.parseInt(parts[2])) continue;
commands.remove(d);
break;
}
break;
case HOLD:
data[3] = "on".equalsIgnoreCase(val)?1:0; break;
case PORT:
data[1] = Integer.parseInt(val); break;
case STATE:
data[2] = Integer.parseInt(val); break;
}
} else switch (key) {
case NEW_ASPECT:
if (!val.isEmpty()) knownStates.add(val); break;
}
}
for (Entry<String, int[]> entry : newAspects.entrySet()) {
String aspect = entry.getKey();
int[] data = entry.getValue();
if (data[0]==0) continue;
LOG.debug("{} : {} / {} / {}",entry.getKey(),data[0],data[1],data[2]);
HashSet<int[]> dataSet = aspects.get(aspect);
if (isNull(dataSet)) {
dataSet = new HashSet<int[]>();
aspects.put(aspect, dataSet);
}
aspects.get(aspect).add(data);
}
return super.update(params);
}
} }

2
src/main/java/de/srsoftware/web4rail/tiles/Tile.java

@ -187,7 +187,7 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
public Tag link(String...args) { public Tag link(String...args) {
String tx = args.length<1 ? id()+NBSP : args[0]; String tx = args.length<1 ? id()+NBSP : args[0];
String type = args.length<2 ? "span" : args[1]; String type = args.length<2 ? "span" : args[1];
return super.link(type, tx, Map.of(ACTION,ACTION_CLICK)); return super.link(type, (Object)tx, Map.of(ACTION,ACTION_CLICK));
} }

Loading…
Cancel
Save