refurbishing route.save
This commit is contained in:
2
pom.xml
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>0.7.13</version>
|
<version>0.7.14</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>
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public class Application implements Constants{
|
|||||||
case REALM_PLAN:
|
case REALM_PLAN:
|
||||||
return plan.action(params);
|
return plan.action(params);
|
||||||
case REALM_ROUTE:
|
case REALM_ROUTE:
|
||||||
return plan.routeAction(params);
|
return Route.action(params,plan);
|
||||||
case REALM_TRAIN:
|
case REALM_TRAIN:
|
||||||
return Train.action(params,plan);
|
return Train.action(params,plan);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package de.srsoftware.web4rail;
|
|||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import de.keawe.tools.translations.Translation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this interface collects constants inherited to other classes of this application
|
* this interface collects constants inherited to other classes of this application
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -606,19 +606,6 @@ public class Plan implements Constants{
|
|||||||
return routes.get(routeId);
|
return routes.get(routeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object routeAction(HashMap<String, String> params) throws IOException {
|
|
||||||
Route route = route(Integer.parseInt(params.get(ID)));
|
|
||||||
if (route == null) return t("Unknown route: {}",params.get(ID));
|
|
||||||
switch (params.get(ACTION)) {
|
|
||||||
case ACTION_PROPS:
|
|
||||||
return route.properties();
|
|
||||||
case ACTION_UPDATE:
|
|
||||||
route.update(params);
|
|
||||||
return html();
|
|
||||||
}
|
|
||||||
return t("Unknown action: {}",params.get(ACTION));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* saves the plan to a set of files, along with its cars, tiles, trains, routes and control unit settings
|
* saves the plan to a set of files, along with its cars, tiles, trains, routes and control unit settings
|
||||||
* @param name
|
* @param name
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import de.srsoftware.web4rail.actions.ActionList;
|
|||||||
import de.srsoftware.web4rail.actions.ActivateRoute;
|
import de.srsoftware.web4rail.actions.ActivateRoute;
|
||||||
import de.srsoftware.web4rail.actions.FinishRoute;
|
import de.srsoftware.web4rail.actions.FinishRoute;
|
||||||
import de.srsoftware.web4rail.actions.SetSignalsToStop;
|
import de.srsoftware.web4rail.actions.SetSignalsToStop;
|
||||||
import de.srsoftware.web4rail.actions.SpeedReduction;
|
import de.srsoftware.web4rail.actions.SetSpeed;
|
||||||
import de.srsoftware.web4rail.moving.Train;
|
import de.srsoftware.web4rail.moving.Train;
|
||||||
import de.srsoftware.web4rail.tags.Form;
|
import de.srsoftware.web4rail.tags.Form;
|
||||||
import de.srsoftware.web4rail.tags.Input;
|
import de.srsoftware.web4rail.tags.Input;
|
||||||
@@ -41,6 +41,12 @@ import de.srsoftware.web4rail.tiles.Tile;
|
|||||||
import de.srsoftware.web4rail.tiles.Turnout;
|
import de.srsoftware.web4rail.tiles.Turnout;
|
||||||
import de.srsoftware.web4rail.tiles.Turnout.State;
|
import de.srsoftware.web4rail.tiles.Turnout.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A route is a vector of tiles that leads from one block to another.
|
||||||
|
*
|
||||||
|
* @author Stephan Richter, SRSoftware
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class Route implements Constants{
|
public class Route implements Constants{
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Route.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Route.class);
|
||||||
static final String NAME = "name";
|
static final String NAME = "name";
|
||||||
@@ -64,6 +70,26 @@ public class Route implements Constants{
|
|||||||
|
|
||||||
private static final String TRIGGER = "trigger";
|
private static final String TRIGGER = "trigger";
|
||||||
private static final String ACTIONS = "actions";
|
private static final String ACTIONS = "actions";
|
||||||
|
private static final String ACTION_LISTS = "action_lists";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process commands from the client
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static Object action(HashMap<String, String> params,Plan plan) throws IOException {
|
||||||
|
Route route = plan.route(Integer.parseInt(params.get(ID)));
|
||||||
|
if (route == null) return t("Unknown route: {}",params.get(ID));
|
||||||
|
switch (params.get(ACTION)) {
|
||||||
|
case ACTION_PROPS:
|
||||||
|
return route.properties();
|
||||||
|
case ACTION_UPDATE:
|
||||||
|
route.update(params);
|
||||||
|
return plan.html();
|
||||||
|
}
|
||||||
|
return t("Unknown action: {}",params.get(ACTION));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route wurde von Zug betreten
|
* Route wurde von Zug betreten
|
||||||
@@ -74,6 +100,12 @@ public class Route implements Constants{
|
|||||||
for (Tile tile : path) tile.train(train);
|
for (Tile tile : path) tile.train(train);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a tile to the route
|
||||||
|
* @param tile
|
||||||
|
* @param direrction
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Tile add(Tile tile, Direction direrction) {
|
public Tile add(Tile tile, Direction direrction) {
|
||||||
if (tile instanceof Shadow) tile = ((Shadow)tile).overlay();
|
if (tile instanceof Shadow) tile = ((Shadow)tile).overlay();
|
||||||
if (tile instanceof Block) {
|
if (tile instanceof Block) {
|
||||||
@@ -90,7 +122,12 @@ public class Route implements Constants{
|
|||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAction(String trigger, Action action) {
|
/**
|
||||||
|
* adds a action to the action list of the given trigger
|
||||||
|
* @param trigger
|
||||||
|
* @param action
|
||||||
|
*/
|
||||||
|
public void add(String trigger, Action action) {
|
||||||
ActionList actions = triggers.get(trigger);
|
ActionList actions = triggers.get(trigger);
|
||||||
if (actions == null) {
|
if (actions == null) {
|
||||||
actions = new ActionList();
|
actions = new ActionList();
|
||||||
@@ -180,15 +217,15 @@ public class Route implements Constants{
|
|||||||
|
|
||||||
public void complete() {
|
public void complete() {
|
||||||
if (contacts.size()>1) { // mindestens 2 Kontakte: erster Kontakt aktiviert Block, vorletzter Kontakt leitet Bremsung ein
|
if (contacts.size()>1) { // mindestens 2 Kontakte: erster Kontakt aktiviert Block, vorletzter Kontakt leitet Bremsung ein
|
||||||
addAction(contacts.firstElement().trigger(),new ActivateRoute());
|
add(contacts.firstElement().trigger(),new ActivateRoute());
|
||||||
Contact nextToLastContact = contacts.get(contacts.size()-2);
|
Contact nextToLastContact = contacts.get(contacts.size()-2);
|
||||||
addAction(nextToLastContact.trigger(),new SpeedReduction(30));
|
add(nextToLastContact.trigger(),new SetSpeed(30));
|
||||||
addAction(nextToLastContact.trigger(),new SetSignalsToStop());
|
add(nextToLastContact.trigger(),new SetSignalsToStop());
|
||||||
}
|
}
|
||||||
if (!contacts.isEmpty()) {
|
if (!contacts.isEmpty()) {
|
||||||
Contact lastContact = contacts.lastElement();
|
Contact lastContact = contacts.lastElement();
|
||||||
addAction(lastContact.trigger(), new SpeedReduction(0));
|
add(lastContact.trigger(), new SetSpeed(0));
|
||||||
addAction(lastContact.trigger(), new FinishRoute());
|
add(lastContact.trigger(), new FinishRoute());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +285,10 @@ public class Route implements Constants{
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a json representation of this route
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String json() {
|
public String json() {
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
@@ -273,17 +314,13 @@ public class Route implements Constants{
|
|||||||
for (Entry<String, ActionList> entry : triggers.entrySet()) {
|
for (Entry<String, ActionList> entry : triggers.entrySet()) {
|
||||||
JSONObject trigger = new JSONObject();
|
JSONObject trigger = new JSONObject();
|
||||||
trigger.put(TRIGGER, entry.getKey());
|
trigger.put(TRIGGER, entry.getKey());
|
||||||
|
ActionList actionList = entry.getValue();
|
||||||
JSONArray jActions = new JSONArray();
|
trigger.put(ACTIONS, actionList.json());
|
||||||
for (Action action : entry.getValue()) {
|
|
||||||
jActions.put(action.json());
|
|
||||||
}
|
|
||||||
trigger.put(ACTIONS, jActions);
|
|
||||||
|
|
||||||
jTriggers.put(trigger);
|
jTriggers.put(trigger);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!jTriggers.isEmpty()) json.put(ACTIONS, jTriggers);
|
if (!jTriggers.isEmpty()) json.put(ACTION_LISTS, jTriggers);
|
||||||
|
|
||||||
String name = name();
|
String name = name();
|
||||||
if (name != null) json.put(NAME, name);
|
if (name != null) json.put(NAME, name);
|
||||||
@@ -319,6 +356,7 @@ public class Route implements Constants{
|
|||||||
for (Object signalId : json.getJSONArray(SIGNALS)) addSignal((Signal) plan.get((String) signalId, false));
|
for (Object signalId : json.getJSONArray(SIGNALS)) addSignal((Signal) plan.get((String) signalId, false));
|
||||||
}
|
}
|
||||||
if (json.has(ACTIONS)) loadActions(json.getJSONArray(ACTIONS));
|
if (json.has(ACTIONS)) loadActions(json.getJSONArray(ACTIONS));
|
||||||
|
if (json.has(ACTION_LISTS)) loadActions(json.getJSONArray(ACTION_LISTS));
|
||||||
return plan.registerRoute(this);
|
return plan.registerRoute(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,12 +364,12 @@ public class Route implements Constants{
|
|||||||
for (int i=0; i<arr.length(); i++) {
|
for (int i=0; i<arr.length(); i++) {
|
||||||
JSONObject json = arr.getJSONObject(i);
|
JSONObject json = arr.getJSONObject(i);
|
||||||
String trigger = json.getString(TRIGGER);
|
String trigger = json.getString(TRIGGER);
|
||||||
JSONArray actions = json.getJSONArray(ACTIONS);
|
JSONArray actions = json.getJSONArray("actions");
|
||||||
for (int k=0; k<actions.length(); k++) {
|
for (int k=0; k<actions.length(); k++) {
|
||||||
try {
|
try {
|
||||||
Action action = Action.load(actions.getJSONObject(k));
|
Action action = Action.load(actions.getJSONObject(k));
|
||||||
LOG.debug("Loaded {}",action);
|
LOG.debug("Loaded {}",action);
|
||||||
addAction(trigger, action);
|
add(trigger, action);
|
||||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException| InvocationTargetException | NoSuchMethodException | SecurityException | ClassNotFoundException | JSONException e) {
|
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException| InvocationTargetException | NoSuchMethodException | SecurityException | ClassNotFoundException | JSONException e) {
|
||||||
LOG.warn("Was not able to load action: ",e);
|
LOG.warn("Was not able to load action: ",e);
|
||||||
}
|
}
|
||||||
@@ -404,7 +442,14 @@ public class Route implements Constants{
|
|||||||
|
|
||||||
public static void saveAll(Collection<Route> routes, String filename) throws IOException {
|
public static void saveAll(Collection<Route> routes, String filename) throws IOException {
|
||||||
BufferedWriter file = new BufferedWriter(new FileWriter(filename));
|
BufferedWriter file = new BufferedWriter(new FileWriter(filename));
|
||||||
for (Route route : routes) file.write(route.json()+"\n");
|
file.write("[\n");
|
||||||
|
int count = 0;
|
||||||
|
for (Route route : routes) {
|
||||||
|
file.write(route.json());
|
||||||
|
if (++count < routes.size()) file.write(",");
|
||||||
|
file.write("\n");
|
||||||
|
}
|
||||||
|
file.write("]");
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,9 +48,7 @@ public abstract class Action implements Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject json() {
|
public JSONObject json() {
|
||||||
JSONObject json = new JSONObject();
|
return new JSONObject().put(TYPE, getClass().getSimpleName());
|
||||||
json.put(TYPE, getClass().getSimpleName());
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Tag link(int actionId, String context) {
|
protected Tag link(int actionId, String context) {
|
||||||
@@ -69,7 +67,7 @@ public abstract class Action implements Constants {
|
|||||||
case "SetSignalsToStop":
|
case "SetSignalsToStop":
|
||||||
return new SetSignalsToStop();
|
return new SetSignalsToStop();
|
||||||
case "SpeedReduction":
|
case "SpeedReduction":
|
||||||
return new SpeedReduction(json.getInt(SpeedReduction.MAX_SPEED));
|
return new SetSpeed(json.getInt(SetSpeed.MAX_SPEED));
|
||||||
case "TurnTrain":
|
case "TurnTrain":
|
||||||
return new TurnTrain();
|
return new TurnTrain();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ public class ActionList extends Vector<Action> implements Constants{
|
|||||||
Select select = new Select(TYPE);
|
Select select = new Select(TYPE);
|
||||||
List<Class<? extends Action>> classes = List.of(
|
List<Class<? extends Action>> classes = List.of(
|
||||||
ConditionalAction.class,
|
ConditionalAction.class,
|
||||||
SpeedReduction.class,
|
SetSpeed.class,
|
||||||
SetSignalsToStop.class,
|
SetSignalsToStop.class,
|
||||||
FinishRoute.class,
|
FinishRoute.class,
|
||||||
TurnTrain.class,
|
TurnTrain.class,
|
||||||
@@ -85,8 +86,8 @@ public class ActionList extends Vector<Action> implements Constants{
|
|||||||
case "SetSignalsToStop":
|
case "SetSignalsToStop":
|
||||||
add(new SetSignalsToStop());
|
add(new SetSignalsToStop());
|
||||||
break;
|
break;
|
||||||
case "SpeedReduction":
|
case "SetSpeed":
|
||||||
add(new SpeedReduction(0));
|
add(new SetSpeed(0));
|
||||||
break;
|
break;
|
||||||
case "TurnTrain":
|
case "TurnTrain":
|
||||||
add(new TurnTrain());
|
add(new TurnTrain());
|
||||||
@@ -170,6 +171,12 @@ public class ActionList extends Vector<Action> implements Constants{
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONArray json() {
|
||||||
|
JSONArray result = new JSONArray();
|
||||||
|
for (Action action : this) result.put(action.json());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean moveUp(int actionId) {
|
public boolean moveUp(int actionId) {
|
||||||
for (int i=1; i<size(); i++) {
|
for (int i=1; i<size(); i++) {
|
||||||
if (actionId == elementAt(i).id()) {
|
if (actionId == elementAt(i).id()) {
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import de.srsoftware.tools.Tag;
|
import de.srsoftware.tools.Tag;
|
||||||
import de.srsoftware.web4rail.Window;
|
import de.srsoftware.web4rail.Window;
|
||||||
import de.srsoftware.web4rail.conditions.Condition;
|
import de.srsoftware.web4rail.conditions.Condition;
|
||||||
@@ -17,6 +20,8 @@ import de.srsoftware.web4rail.tags.Select;
|
|||||||
|
|
||||||
public class ConditionalAction extends Action {
|
public class ConditionalAction extends Action {
|
||||||
|
|
||||||
|
private static final String CONDITIONS = "conditions";
|
||||||
|
private static final String ACTIONS = "actions";
|
||||||
private Vector<Condition> conditions = new Vector<Condition>();
|
private Vector<Condition> conditions = new Vector<Condition>();
|
||||||
private ActionList actions = new ActionList();
|
private ActionList actions = new ActionList();
|
||||||
|
|
||||||
@@ -26,6 +31,10 @@ public class ConditionalAction extends Action {
|
|||||||
return fieldset;
|
return fieldset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ActionList children() {
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
private Tag conditionForm(HashMap<String, String> params) {
|
private Tag conditionForm(HashMap<String, String> params) {
|
||||||
Fieldset fieldset = new Fieldset(t("Conditions"));
|
Fieldset fieldset = new Fieldset(t("Conditions"));
|
||||||
|
|
||||||
@@ -64,6 +73,16 @@ public class ConditionalAction extends Action {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject json() {
|
||||||
|
JSONObject json = super.json();
|
||||||
|
JSONArray conditions = new JSONArray();
|
||||||
|
for (Condition condition : this.conditions) conditions.put(condition.json());
|
||||||
|
json.put(CONDITIONS, conditions);
|
||||||
|
json.put(ACTIONS, actions.json());
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Window properties(HashMap<String, String> params) {
|
public Window properties(HashMap<String, String> params) {
|
||||||
@@ -99,8 +118,4 @@ public class ConditionalAction extends Action {
|
|||||||
}
|
}
|
||||||
return super.update(params);
|
return super.update(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionList children() {
|
|
||||||
return actions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import de.srsoftware.web4rail.tags.Form;
|
|||||||
import de.srsoftware.web4rail.tags.Input;
|
import de.srsoftware.web4rail.tags.Input;
|
||||||
import de.srsoftware.web4rail.tags.Label;
|
import de.srsoftware.web4rail.tags.Label;
|
||||||
|
|
||||||
public class SpeedReduction extends Action{
|
public class SetSpeed extends Action{
|
||||||
|
|
||||||
public static final String MAX_SPEED = "max_speed";
|
public static final String MAX_SPEED = "max_speed";
|
||||||
private int maxSpeed = -1;
|
private int maxSpeed = -1;
|
||||||
|
|
||||||
public SpeedReduction(int kmh) {
|
public SetSpeed(int kmh) {
|
||||||
super();
|
super();
|
||||||
maxSpeed = kmh;
|
maxSpeed = kmh;
|
||||||
}
|
}
|
||||||
@@ -48,6 +48,10 @@ public abstract class Condition implements Constants {
|
|||||||
return t("Unknown action: {}",action);
|
return t("Unknown action: {}",action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject json() {
|
||||||
|
return new JSONObject().put(TYPE, getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
public Tag link(String tagClass,String context) {
|
public Tag link(String tagClass,String context) {
|
||||||
String json = new JSONObject(Map.of(REALM,REALM_CONDITION,ID,id,ACTION,ACTION_PROPS,CONTEXT,context)).toString().replace("\"", "'");
|
String json = new JSONObject(Map.of(REALM,REALM_CONDITION,ID,id,ACTION,ACTION_PROPS,CONTEXT,context)).toString().replace("\"", "'");
|
||||||
return new Tag(tagClass).clazz("link").attr("onclick","request("+json+")").content(toString());
|
return new Tag(tagClass).clazz("link").attr("onclick","request("+json+")").content(toString());
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package de.srsoftware.web4rail.conditions;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import de.srsoftware.web4rail.Window;
|
import de.srsoftware.web4rail.Window;
|
||||||
import de.srsoftware.web4rail.actions.Action.Context;
|
import de.srsoftware.web4rail.actions.Action.Context;
|
||||||
import de.srsoftware.web4rail.moving.Train;
|
import de.srsoftware.web4rail.moving.Train;
|
||||||
@@ -20,6 +22,11 @@ public class TrainSelect extends Condition {
|
|||||||
return context.train == train;
|
return context.train == train;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject json() {
|
||||||
|
return super.json().put(REALM_TRAIN, train.id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Window properties(HashMap<String, String> params) {
|
protected Window properties(HashMap<String, String> params) {
|
||||||
Window win = new Window("condition-props", t("Properties of {}",getClass().getSimpleName()));
|
Window win = new Window("condition-props", t("Properties of {}",getClass().getSimpleName()));
|
||||||
|
|||||||
Reference in New Issue
Block a user