From 58341902f7a6324cdf4621589a2d79977592ab8b Mon Sep 17 00:00:00 2001 From: Marc Froehlich Date: Tue, 21 Jul 2026 00:26:14 +0200 Subject: [PATCH] added pstrotator options and fixed some ui stuff --- .../controller/ChatController.java | 22 +- .../kst4contest/model/ChatPreferences.java | 49 +++++ .../view/Kst4ContestApplication.java | 201 +++++++++++++++--- 3 files changed, 229 insertions(+), 43 deletions(-) diff --git a/src/main/java/kst4contest/controller/ChatController.java b/src/main/java/kst4contest/controller/ChatController.java index a3bb601..0e1f2cf 100644 --- a/src/main/java/kst4contest/controller/ChatController.java +++ b/src/main/java/kst4contest/controller/ChatController.java @@ -163,14 +163,16 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList - public void initRotor() { - // Beispiel: PSTRotator läuft lokal auf Port 12060 - // Der Client wird automatisch auf 12061 hören. - rotatorClient = new PstRotatorClient("127.0.0.1", 12000, this, this); //TODO: IP anpassen, Port auch aus den prefs holen, default 12000 + public void initRotor() { + rotatorClient = new PstRotatorClient( + chatPreferences.getStn_pstRotatorHost(), + chatPreferences.getStn_pstRotatorPort(), + this, + this + ); - // Startet den Thread und das Polling - rotatorClient.start(); - } + rotatorClient.start(); + } /** * sets rotator to "AZ DEGREE" by button click

@@ -2193,7 +2195,11 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList messageTXBus = new LinkedBlockingQueue(); // socket = new Socket(hostname, port);//socket for the on4kst chat server - socket = new Socket(chatController.chatPreferences.getStn_on4kstServersDns(), port);//socket for the on4kst chat server + socket = new Socket( + chatPreferences.getStn_on4kstServersDns(), + chatPreferences.getStn_on4kstServersPort() + );//socket for the on4kst chat server + System.out.println("Connected to the chat server: " + socket.isConnected()); ByteBuffer buffer = ByteBuffer.allocate(1024); diff --git a/src/main/java/kst4contest/model/ChatPreferences.java b/src/main/java/kst4contest/model/ChatPreferences.java index ad78eb8..26f947a 100644 --- a/src/main/java/kst4contest/model/ChatPreferences.java +++ b/src/main/java/kst4contest/model/ChatPreferences.java @@ -159,6 +159,8 @@ public class ChatPreferences { int stn_on4kstServersPort = 23001; boolean stn_pstRotatorEnabled = false; + String stn_pstRotatorHost = "127.0.0.1"; + int stn_pstRotatorPort = 12000; boolean stn_loginAFKState = false; //always start as here String stn_loginCallSign = "do5amf"; @@ -761,6 +763,30 @@ public class ChatPreferences { this.stn_pstRotatorEnabled = stn_pstRotatorEnabled; } + public String getStn_pstRotatorHost() { + return stn_pstRotatorHost; + } + + public void setStn_pstRotatorHost(String stn_pstRotatorHost) { + if (stn_pstRotatorHost == null || stn_pstRotatorHost.isBlank()) { + this.stn_pstRotatorHost = "127.0.0.1"; + } else { + this.stn_pstRotatorHost = stn_pstRotatorHost.trim(); + } + } + + public int getStn_pstRotatorPort() { + return stn_pstRotatorPort; + } + + public void setStn_pstRotatorPort(int stn_pstRotatorPort) { + if (stn_pstRotatorPort < 1 || stn_pstRotatorPort > 65535) { + this.stn_pstRotatorPort = 12000; + } else { + this.stn_pstRotatorPort = stn_pstRotatorPort; + } + } + public SimpleStringProperty getNotify_optionalFrequencyPrefix() { return notify_optionalFrequencyPrefix; } @@ -1418,6 +1444,13 @@ public class ChatPreferences { stn_pstRotatorEnabled.setTextContent(this.stn_pstRotatorEnabled + ""); station.appendChild(stn_pstRotatorEnabled); + Element stn_pstRotatorHost = doc.createElement("stn_pstRotatorHost"); + stn_pstRotatorHost.setTextContent(this.stn_pstRotatorHost); + station.appendChild(stn_pstRotatorHost); + + Element stn_pstRotatorPort = doc.createElement("stn_pstRotatorPort"); + stn_pstRotatorPort.setTextContent(Integer.toString(this.stn_pstRotatorPort)); + station.appendChild(stn_pstRotatorPort); /** @@ -2092,6 +2125,22 @@ public class ChatPreferences { stn_pstRotatorEnabled = getBoolean(stationEl, stn_pstRotatorEnabled, "stn_pstRotatorEnabled"); + setStn_pstRotatorHost( + getText( + stationEl, + stn_pstRotatorHost, + "stn_pstRotatorHost" + ) + ); + + setStn_pstRotatorPort( + getInt( + stationEl, + stn_pstRotatorPort, + "stn_pstRotatorPort" + ) + ); + } /** diff --git a/src/main/java/kst4contest/view/Kst4ContestApplication.java b/src/main/java/kst4contest/view/Kst4ContestApplication.java index 1ec2dea..49a79d2 100644 --- a/src/main/java/kst4contest/view/Kst4ContestApplication.java +++ b/src/main/java/kst4contest/view/Kst4ContestApplication.java @@ -8658,27 +8658,114 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL HBox hbxDemDirectoryActions = new HBox(8.0, btnUseDefaultDemDirectory, btnImportDemTiles); - Label lbl_station_pstRotatorEnabled = new Label("Enable PSTRotator interface (auto QTF):"); + Label lbl_station_pstRotatorEnabled = + new Label("Enable PSTRotator interface (automatic QTF):"); + + TextField txtFld_station_pstRotatorHost = new TextField( + chatcontroller.getChatPreferences().getStn_pstRotatorHost() + ); + txtFld_station_pstRotatorHost.setFocusTraversable(false); + + TextField txtFld_station_pstRotatorPort = new TextField( + Integer.toString( + chatcontroller.getChatPreferences().getStn_pstRotatorPort() + ) + ); + txtFld_station_pstRotatorPort.setFocusTraversable(false); + CheckBox chkBx_station_pstRotatorEnabled = new CheckBox(); - chkBx_station_pstRotatorEnabled.setSelected(chatcontroller.getChatPreferences().isStn_pstRotatorEnabled()); + chkBx_station_pstRotatorEnabled.setSelected( + chatcontroller.getChatPreferences().isStn_pstRotatorEnabled() + ); chkBx_station_pstRotatorEnabled.setTooltip(new Tooltip( - "If disabled: no PSTRotator connection is started and antenna direction is ignored in priority scoring." + "When enabled, KST4Contest reads the antenna direction from PSTRotator.\n" + + "The connection settings take effect on the next chat connection." )); - chkBx_station_pstRotatorEnabled.selectedProperty().addListener((obs, oldV, newV) -> { - chatcontroller.getChatPreferences().setStn_pstRotatorEnabled(newV); - if (newV) { - txt_myQTF.textProperty().bind(Bindings.createStringBinding( - () -> Double.toString(chatcontroller.getChatPreferences().getActualQTF().get()), - chatcontroller.getChatPreferences().getActualQTF())); - txt_myQTF.setTooltip(new Tooltip("This is your current QTF, read out at PSTRotator")); - txt_myQTF.setFocusTraversable(false); - } else { - txt_myQTF.textProperty().unbind(); - txt_myQTF.setText(Double.toString(chatcontroller.getChatPreferences().getActualQTF().get())); - txt_myQTF.setTooltip(new Tooltip("Enter your antenna heading (QTF) by hand - no rotator sync active")); - txt_myQTF.setFocusTraversable(true); - } - }); + + Runnable updatePstRotatorFields = () -> { + boolean disabled = !chkBx_station_pstRotatorEnabled.isSelected(); + txtFld_station_pstRotatorHost.setDisable(disabled); + txtFld_station_pstRotatorPort.setDisable(disabled); + }; + + updatePstRotatorFields.run(); + + chkBx_station_pstRotatorEnabled.selectedProperty().addListener( + (observable, oldValue, newValue) -> { + chatcontroller.getChatPreferences().setStn_pstRotatorEnabled(newValue); + updatePstRotatorFields.run(); + + if (newValue) { + txt_myQTF.textProperty().bind(Bindings.createStringBinding( + () -> Double.toString( + chatcontroller.getChatPreferences().getActualQTF().get() + ), + chatcontroller.getChatPreferences().getActualQTF() + )); + txt_myQTF.setTooltip( + new Tooltip("Current QTF reported by PSTRotator") + ); + txt_myQTF.setFocusTraversable(false); + } else { + txt_myQTF.textProperty().unbind(); + txt_myQTF.setText( + Double.toString( + chatcontroller.getChatPreferences().getActualQTF().get() + ) + ); + txt_myQTF.setTooltip( + new Tooltip("Enter the current antenna direction manually") + ); + txt_myQTF.setFocusTraversable(true); + } + } + ); + + txtFld_station_pstRotatorHost.focusedProperty().addListener( + (observable, oldValue, newValue) -> { + if (!newValue) { + chatcontroller.getChatPreferences().setStn_pstRotatorHost( + txtFld_station_pstRotatorHost.getText() + ); + txtFld_station_pstRotatorHost.setText( + chatcontroller.getChatPreferences().getStn_pstRotatorHost() + ); + } + } + ); + + txtFld_station_pstRotatorPort.focusedProperty().addListener( + (observable, oldValue, newValue) -> { + if (newValue) { + return; + } + + try { + int configuredPort = Integer.parseInt( + txtFld_station_pstRotatorPort.getText().trim() + ); + + if (configuredPort < 1 || configuredPort > 65535) { + throw new NumberFormatException(); + } + + chatcontroller.getChatPreferences().setStn_pstRotatorPort( + configuredPort + ); + } catch (NumberFormatException exception) { + showUserInputErrorWindow( + "\"" + txtFld_station_pstRotatorPort.getText() + + "\" is not a valid UDP port. Enter a value between 1 and 65535." + ); + } + + txtFld_station_pstRotatorPort.setText( + Integer.toString( + chatcontroller.getChatPreferences().getStn_pstRotatorPort() + ) + ); + } + ); grdPnlStation.add(lblCallSign, 0, 0); @@ -8722,6 +8809,11 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL grdPnlStation.add(lbl_station_pstRotatorEnabled, 0, 12); grdPnlStation.add(chkBx_station_pstRotatorEnabled, 1, 12); + grdPnlStation.add(new Label("PSTRotator host:"), 0, 13); + grdPnlStation.add(txtFld_station_pstRotatorHost, 1, 13); + + grdPnlStation.add(new Label("PSTRotator UDP port:"), 0, 14); + grdPnlStation.add(txtFld_station_pstRotatorPort, 1, 14); VBox vbxStation = new VBox(); @@ -8729,32 +8821,71 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL GridPane grdPanelServerHostName = new GridPane(); - TextField stn_txtServerDNS = new TextField(this.chatcontroller.getChatPreferences().getStn_on4kstServersDns()); - stn_txtServerDNS.focusedProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observableValue, Boolean aBoolean, Boolean t1) { - - System.out.println("[Main.java, Info]: Set the Server DNS property by hand to: " - + stn_txtServerDNS.getText()); - chatcontroller.getChatPreferences().setStn_on4kstServersDns(stn_txtServerDNS.getText()); - } - }); - grdPanelServerHostName.add(new Label("ON4KST Server [www.on4kst.org]: "), 0,1); - grdPanelServerHostName.add(stn_txtServerDNS, 1,1); + TextField stn_txtServerDNS = new TextField( + this.chatcontroller.getChatPreferences().getStn_on4kstServersDns() + ); + stn_txtServerDNS.setFocusTraversable(false); + stn_txtServerDNS.focusedProperty().addListener((observable, oldValue, newValue) -> { + if (!newValue) { + chatcontroller.getChatPreferences().setStn_on4kstServersDns( + stn_txtServerDNS.getText().trim() + ); + } + }); - TextField stn_txtServerPort = new TextField(this.chatcontroller.getChatPreferences().getStn_on4kstServersPort()+""); + grdPanelServerHostName.add( + new Label("ON4KST server [www.on4kst.org]:"), + 0, + 1 + ); + grdPanelServerHostName.add(stn_txtServerDNS, 1, 1); - grdPanelServerHostName.add(new Label(" Port [23001]: "), 2,1); - grdPanelServerHostName.add(stn_txtServerPort, 3,1); + TextField stn_txtServerPort = new TextField( + Integer.toString( + this.chatcontroller.getChatPreferences().getStn_on4kstServersPort() + ) + ); + stn_txtServerPort.setFocusTraversable(false); + stn_txtServerPort.focusedProperty().addListener((observable, oldValue, newValue) -> { + if (newValue) { + return; + } + + try { + int configuredPort = Integer.parseInt(stn_txtServerPort.getText().trim()); + + if (configuredPort < 1 || configuredPort > 65535) { + throw new NumberFormatException(); + } + + chatcontroller.getChatPreferences().setStn_on4kstServersPort( + configuredPort + ); + } catch (NumberFormatException exception) { + showUserInputErrorWindow( + "\"" + stn_txtServerPort.getText() + + "\" is not a valid TCP port. Enter a value between 1 and 65535." + ); + + stn_txtServerPort.setText( + Integer.toString( + chatcontroller.getChatPreferences().getStn_on4kstServersPort() + ) + ); + } + }); + + grdPanelServerHostName.add(new Label("Port [23001]:"), 2, 1); + grdPanelServerHostName.add(stn_txtServerPort, 3, 1); vbxStation.getChildren().addAll(grdPanelServerHostName); vbxStation.getChildren().addAll( generateLabeledSeparator(100, "Set your Login Credentials and Station Parameters here"), grdPnlStation); - vbxStation.getChildren().addAll(generateLabeledSeparator(50, - "! ! ! ! Don´t forget to reset the worked stations information before starting a new contest ! ! ! !")); +// vbxStation.getChildren().addAll(generateLabeledSeparator(50, +// "! ! ! ! Don´t forget to reset the worked stations information before starting a new contest ! ! ! !")); CheckBox settings_chkbx_QRV144 = new CheckBox("My station uses 2m band");