feat(editor): F4.5e a router's connections in the device sheet
SheetRun now clicks through Java's JConnectionsDialog with a router, a computer and a switch cabled in the GUIContainer: a click marks a card, the same click unmarks it, another card swaps the cables or moves the one; "+" adds 192.168.0.10/24 up to eight cards, "-" removes the last card with its cable down to none, and a router without a card keeps no gateway. The document adds, removes and swaps a router's cards (the same cables, the same devices), Java's click logic is one function for the test and the page, and the sheet names the address at a cable's far end. The page "Verbindungen verwalten" shows Java's RJ45 buttons in Java's colours with each card's far end below. Not adopted: the last card stays. A card tab or a mark whose card is undone away falls back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1211,3 +1211,31 @@ Gemessen (03.10.2026):
|
||||
Ports“; „080“ wird 80.
|
||||
* rauf/runter: Die erste Regel geht nicht höher, die letzte nicht tiefer
|
||||
(`moveUp`/`moveDown` antworten `false`).
|
||||
|
||||
### Verbindungen verwalten (F4.5e)
|
||||
|
||||
`SheetRun` bedient auch `JConnectionsDialog` eines Vermittlungsrechners
|
||||
(`connections`): drei Karten (10.0.0.1, 10.1.0.1, 10.2.0.1), Rechner A an
|
||||
der ersten, Switch S an der zweiten, beide Kabel wie `GUIEvents`
|
||||
(`createConnection`) sie in den `GUIContainer` legt; dann Klicks auf die
|
||||
Knöpfe der Karten, „+“ und „-“, nach jedem Klick, was der Dialog zeigt
|
||||
(Beschriftungen, Knopffarben, ob „+“/„-“ frei sind) und woran die Karten
|
||||
hängen; bei einer und keiner Karte, ob das Router-Panel noch zeichnet und ob
|
||||
der Router ein Gateway behält.
|
||||
|
||||
Gemessen (03.10.2026):
|
||||
|
||||
* Ein Klick markiert eine Karte gelb, ein zweiter auf dieselbe hebt das auf,
|
||||
ein Klick auf eine andere tauscht die Kabel (beide belegt) oder steckt das
|
||||
eine um (eine frei, auch eine markierte freie Karte); zwei freie: nichts.
|
||||
Danach ist keine Karte markiert, ebenso nach „+“ und „-“.
|
||||
* Beschriftungen: lokal „NIC n: Adresse“, Gegenstelle „Name (Adresse)“ bei
|
||||
einem Rechner oder Router (die Adresse seiner Karte am Kabel), beim Switch
|
||||
nur der Name.
|
||||
* „+“: eine Karte mit 192.168.0.10/255.255.255.0 und neuer MAC, auch
|
||||
mehrfach dieselbe Adresse; bei acht Karten gesperrt.
|
||||
* „-“: die letzte Karte samt Kabel; der Port am anderen Ende wird frei.
|
||||
Gesperrt erst bei null Karten. Das Panel zeichnet mit einer und mit keiner
|
||||
Karte; ohne Karte behält der Router kein Gateway (`setStandardGateway`
|
||||
schreibt es in die Karten, `getStandardGateway` liest `null`).
|
||||
|
||||
|
||||
@@ -30,18 +30,30 @@
|
||||
// (JPortForwardingDialog, "forwarding"). Last, a router's firewall dialog
|
||||
// (JFirewallDialog, "firewall"): a new rule, a cell of a rule edited in its
|
||||
// table as the table takes it (GatewayFirewallConfigTable.closeEditor), the
|
||||
// rules moved and removed with the dialog's buttons.
|
||||
// rules moved and removed with the dialog's buttons. Then a router's
|
||||
// connections dialog (JConnectionsDialog, "connections"): its cards and what
|
||||
// their cables join, cables swapped with two clicks, cards added up to the
|
||||
// last and removed down to none, and the router's panel and gateway with one
|
||||
// card and with none.
|
||||
//
|
||||
// Usage: java -cp filius.jar:lib/*:classes SheetRun <cases txt> <output json>
|
||||
|
||||
import filius.gui.GUIContainer;
|
||||
import filius.gui.JMainFrame;
|
||||
import filius.gui.netzwerksicht.GUIDesignSidebar;
|
||||
import filius.gui.netzwerksicht.GUIKabelItem;
|
||||
import filius.gui.netzwerksicht.GUIKnotenItem;
|
||||
import filius.gui.netzwerksicht.JConnectionsDialog;
|
||||
import filius.gui.netzwerksicht.JDHCPKonfiguration;
|
||||
import filius.gui.netzwerksicht.JSidebarButton;
|
||||
import filius.gui.netzwerksicht.JFirewallDialog;
|
||||
import filius.gui.netzwerksicht.JKonfiguration;
|
||||
import filius.gui.netzwerksicht.JPortForwardingDialog;
|
||||
import filius.gui.netzwerksicht.JWeiterleitungsTabelle;
|
||||
import filius.hardware.Kabel;
|
||||
import filius.hardware.NetzwerkInterface;
|
||||
import filius.hardware.Port;
|
||||
import filius.hardware.knoten.Knoten;
|
||||
import filius.hardware.knoten.Gateway;
|
||||
import filius.hardware.knoten.Host;
|
||||
import filius.hardware.knoten.Modem;
|
||||
@@ -73,7 +85,11 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import java.awt.Color;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import java.util.LinkedList;
|
||||
@@ -471,6 +487,126 @@ public class SheetRun {
|
||||
return flows;
|
||||
}
|
||||
|
||||
/** A device on the design surface, as GUIContainer keeps it (NewDeviceRun.add). */
|
||||
static GUIKnotenItem item(Knoten device, String icon) {
|
||||
JSidebarButton label = new JSidebarButton(new ImageIcon(SheetRun.class.getResource("/" + icon + ".png")), device.holeHardwareTyp());
|
||||
label.initTextAndUpdateLocation(device.holeAnzeigeName());
|
||||
GUIKnotenItem item = new GUIKnotenItem();
|
||||
item.setKnoten(device);
|
||||
item.setImageLabel(label);
|
||||
GUIContainer.getGUIContainer().getKnotenItems().add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
/** A cable as GUIEvents.createConnection plugs it, from the first device's port to the second's. */
|
||||
static void cable(GUIKnotenItem one, Port first, GUIKnotenItem two, Port second) {
|
||||
GUIKabelItem item = new GUIKabelItem();
|
||||
item.getKabelpanel().setZiel1(one);
|
||||
item.getKabelpanel().setZiel2(two);
|
||||
item.setDasKabel(new Kabel(first, second));
|
||||
GUIContainer.getGUIContainer().getCableItems().add(item);
|
||||
}
|
||||
|
||||
/** What the dialog shows and what the router's cards are joined to. */
|
||||
static Map<String, Object> connectionsState(JConnectionsDialog dialog, Vermittlungsrechner router) throws Exception {
|
||||
Map<String, Object> state = new LinkedHashMap<>();
|
||||
List<Object> local = new ArrayList<>();
|
||||
List<Object> remote = new ArrayList<>();
|
||||
List<Object> colours = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
local.add(((JLabel) get(dialog, "lblLocal#" + i)).getText());
|
||||
remote.add(((JLabel) get(dialog, "lblRemote#" + i)).getText());
|
||||
JButton button = (JButton) get(dialog, "btnLocal#" + i);
|
||||
Color colour = button.getBackground();
|
||||
colours.add(!button.isEnabled() ? "off" : colour.equals(Color.YELLOW) ? "marked" : colour.equals(Color.GREEN) ? "plugged" : colour.equals(Color.RED) ? "free" : "other");
|
||||
}
|
||||
state.put("local", local);
|
||||
state.put("remote", remote);
|
||||
state.put("buttons", colours);
|
||||
state.put("add", ((JButton) get(dialog, "btnAddInterface")).isEnabled());
|
||||
state.put("remove", ((JButton) get(dialog, "btnRemoveInterface")).isEnabled());
|
||||
// Each card: its address, mask, and the device its cable joins ("" for none).
|
||||
List<Object> cards = new ArrayList<>();
|
||||
for (NetzwerkInterface nic : router.getNetzwerkInterfaces()) {
|
||||
String joined = "";
|
||||
if (nic.getPort().getVerbindung() != null) {
|
||||
for (Port port : nic.getPort().getVerbindung().getAnschluesse()) {
|
||||
if (port != nic.getPort()) {
|
||||
for (GUIKnotenItem each : GUIContainer.getGUIContainer().getKnotenItems()) {
|
||||
Knoten node = each.getKnoten();
|
||||
boolean owns = node instanceof Switch ? ((Switch) node).getAnschluesse().contains(port)
|
||||
: node instanceof filius.hardware.knoten.InternetKnoten && ((filius.hardware.knoten.InternetKnoten) node).getNetzwerkInterfaces().stream().anyMatch(other -> other.getPort() == port);
|
||||
if (owns) joined = node.holeAnzeigeName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cards.add(Arrays.asList(nic.getIp(), nic.getSubnetzMaske(), joined));
|
||||
}
|
||||
state.put("cards", cards);
|
||||
state.put("cables", GUIContainer.getGUIContainer().getCableItems().size());
|
||||
return state;
|
||||
}
|
||||
|
||||
static Map<String, Object> connectionsFlows() throws Exception {
|
||||
GUIContainer.getGUIContainer().getKnotenItems().clear();
|
||||
GUIContainer.getGUIContainer().getCableItems().clear();
|
||||
Vermittlungsrechner router = new Vermittlungsrechner();
|
||||
router.setzeAnzahlAnschluesse(3);
|
||||
router.setName("R");
|
||||
String[] addresses = { "10.0.0.1", "10.1.0.1", "10.2.0.1" };
|
||||
for (int i = 0; i < 3; i++) router.getNetzwerkInterfaces().get(i).setIp(addresses[i]);
|
||||
Rechner host = new Rechner();
|
||||
host.setName("A");
|
||||
host.getNetzwerkInterfaces().get(0).setIp("10.0.0.2");
|
||||
Switch sw = new Switch();
|
||||
sw.setName("S");
|
||||
GUIKnotenItem routerItem = item(router, GUIDesignSidebar.VERMITTLUNGSRECHNER);
|
||||
GUIKnotenItem hostItem = item(host, GUIDesignSidebar.RECHNER);
|
||||
GUIKnotenItem switchItem = item(sw, GUIDesignSidebar.SWITCH);
|
||||
// The host plugs into the router (the host first), the router into the switch.
|
||||
cable(hostItem, host.getNetzwerkInterfaces().get(0).getPort(), routerItem, router.getNetzwerkInterfaces().get(0).getPort());
|
||||
cable(routerItem, router.getNetzwerkInterfaces().get(1).getPort(), switchItem, sw.holeFreienPort());
|
||||
JConnectionsDialog dialog = new JConnectionsDialog(JMainFrame.getJMainFrame(), router);
|
||||
List<Object> steps = new ArrayList<>();
|
||||
// A click on a card's button ("c<i>"), "+" and "-".
|
||||
String[] clicks = { "start", "c0", "c0", "c0", "c2", "c2", "c1", "c1", "c1", "c0", "+", "c2", "c3", "-", "-", "+", "c0", "c2", "c0", "c1", "+", "+", "+", "+", "+", "+", "-", "-", "-", "-", "-", "-", "-", "-" };
|
||||
for (String click : clicks) {
|
||||
if (click.startsWith("c")) ((JButton) get(dialog, "btnLocal#" + click.substring(1))).doClick();
|
||||
else if (click.equals("+")) ((JButton) get(dialog, "btnAddInterface")).doClick();
|
||||
else if (click.equals("-")) ((JButton) get(dialog, "btnRemoveInterface")).doClick();
|
||||
Map<String, Object> step = new LinkedHashMap<>();
|
||||
step.put("click", click);
|
||||
step.putAll(connectionsState(dialog, router));
|
||||
// The router's panel with this many cards: does it still draw?
|
||||
if (router.getNetzwerkInterfaces().size() <= 1) {
|
||||
String error = null;
|
||||
try {
|
||||
JKonfiguration panel = JKonfiguration.getInstance(router);
|
||||
panel.updateAttribute();
|
||||
} catch (RuntimeException thrown) {
|
||||
error = thrown.getClass().getSimpleName();
|
||||
}
|
||||
step.put("panelError", error);
|
||||
// Java keeps the gateway in the cards: does a router without one keep it?
|
||||
VermittlungsrechnerBetriebssystem os = (VermittlungsrechnerBetriebssystem) router.getSystemSoftware();
|
||||
os.setStandardGateway("10.0.0.254");
|
||||
step.put("gateway", os.getStandardGateway());
|
||||
os.setStandardGateway("");
|
||||
}
|
||||
steps.add(step);
|
||||
}
|
||||
// New cards: their MAC addresses differ from each other and from the first cards'.
|
||||
List<String> macs = new ArrayList<>();
|
||||
for (NetzwerkInterface nic : router.getNetzwerkInterfaces()) macs.add(nic.getMac());
|
||||
Map<String, Object> flows = new LinkedHashMap<>();
|
||||
flows.put("steps", steps);
|
||||
flows.put("hostPortFree", host.getNetzwerkInterfaces().get(0).getPort().getVerbindung() == null);
|
||||
flows.put("switchPortsFree", sw.getAnschluesse().stream().allMatch(port -> port.getVerbindung() == null));
|
||||
dialog.dispose();
|
||||
return flows;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// FILIUS' window keeps the JVM alive: end it on any failure too.
|
||||
try {
|
||||
@@ -596,6 +732,7 @@ public class SheetRun {
|
||||
output.put("dhcp", dhcpFlows());
|
||||
output.put("forwarding", forwardingFlows());
|
||||
output.put("firewall", firewallFlows());
|
||||
output.put("connections", connectionsFlows());
|
||||
output.put("edits", edits);
|
||||
try (FileOutputStream out = new FileOutputStream(args[1])) {
|
||||
out.write((FlsOracle.Json.write(output, "") + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
Reference in New Issue
Block a user