* Add a minimum QRB filter to the station filter bar (#21) Next to "Show only QRB [km] <=" the bar gets "Show only QRB [km] >": it hides every station up to the entered distance. With both switched on the list keeps a range, min < QRB <= max. The minimum is exclusive, as the issue asks, so the two filters split the list without overlap at the same value. A station without a known QRB is hidden while either is on, as the maximum already did. The value lives in the bar for the running session only, like the maximum, and the station map follows through activeFilters. The distance check moves from the controller predicate into StationFilterState.acceptsQrb so it can be tested; the maximum keeps its behaviour (null or > max is hidden). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Document the minimum QRB filter (#21) Changelog v1.50 under New, the filter tables of the user interface pages, the distance filter section of the feature pages, and the station filter page of the website. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Let the first filter bar row wrap instead of clipping (#21) With both QRB filters the first row of the station filter bar no longer fits a narrow station pane, and as a plain Row it cut the bearing buttons off at the right edge. It is a FlowRow now. Reset, the QRB pair, the QTF controls and the bearings each move to the next line as one group; the QRB pair and the bearings only break up inside their group when even the group is wider than the pane. Separators in the wrapping row have a fixed height, because a flow row line has no intrinsic height to fill. A screen test at 300 dp checks that every bearing button, both QRB labels and fields and the QTF label are displayed and end inside the bar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refuse NaN, Infinity and negatives in the QRB filter fields (#21) toDoubleOrNull also reads "NaN" and "Infinity": a pasted "Infinity" as the minimum hid every station, "NaN" let every one through, and the maximum field had the same hole before. Both QRB fields now go through parseQrbKm, which takes only finite, non-negative distances; anything else leaves the field at its last valid value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Let the station map follow the station filters (#21) The Compose map built its markers from all station rows, so no filter reached it, although its status line reported "filtered view active". The JavaFX map, up to beta-v1.50.0-beta-001, took the sorted, filtered list (StationMapBridge.refreshNow), so this is a regression of the Compose port that never shipped. The markers now come from the rows the list shows, and the filter is a key of the remembered markers so a filter change redraws them. A selected station that a filter hides gets no marker, as in the JavaFX map. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Filter again on redraw; no path analysis for a hidden station (#21) DataTableState.visibleRows caches the filtered rows, and forceRedraw only bumped contentRevision. The filter reads fields that change in place (QRB, worked and QRV flags, last activity), so a redraw could hand back rows filtered before the change -- in the list and, since the map draws the same rows, on the map. forceRedraw now drops the cache, and visibleRows reads contentRevision so a reader recomputes after it. In the running application the user-list refresh also sets a new row filter, which dropped the cache before; this makes the redraw itself sufficient. A selected station without a marker -- hidden by a filter, or without a locator -- no longer starts a path analysis: the map used to set "Loading" with an empty target and send the request. The analysis is cleared instead, and the effect re-runs when the station's marker appears or disappears. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
KST4Contest
KST4Contest is a Java-based client for the ON4KST chat, developed for coordinated VHF, UHF and microwave contest operation.
The application is developed by Marc Fröhlich (DO5AMF) and since 2026 Philipp Wagner (DN9APW).
Start here
- Project website
- Download Stable, Beta and Nightly builds
- Online manual
- GitHub wiki
- Issues and bug reports
- Development roadmap
What KST4Contest does
KST4Contest combines the ON4KST chat with information that is useful when coordinating contacts during a contest.
Among other things, it can:
- display and filter stations from the supported ON4KST chat categories;
- derive band and frequency information from chat messages and station names;
- maintain Worked and NOT QRV information for the available bands;
- calculate station priorities from distance, activity and other available information;
- manage internal skeds and received Win-Test skeds;
- use AirScout information when evaluating possible aircraft-scatter contacts;
- display stations, paths and additional propagation information on maps;
- exchange information with supported logging programs, Win-Test, PSTRotator and a local DX Cluster interface;
- provide configurable automatic replies for recurring chat requests.
Calculated scores, aircraft-scatter information and path assessments are operating aids. They depend on the available data and should not be treated as guarantees that a contact is possible.
Installation
Ready-to-use packages are available for Windows, Linux and macOS. These packages include the required Java runtime, so a separate Java installation is normally not necessary.
Use the central download page to select the appropriate build:
- Stable is intended for normal contest operation.
- Beta contains changes that are being prepared for a stable release.
- Nightly contains the latest automated development build and is mainly intended for testing.
Documentation
The documentation is available in German and English:
The Markdown sources used for the wiki and the generated PDF manuals are stored in github_docs.
Changes to operating behaviour should be documented together with their purpose and limitations. This is especially important for functions whose result depends on external data, heuristics or information derived from chat messages.
Building from source
Building KST4Contest requires JDK 21. The Gradle Wrapper included in the repository should be used, so a separate Gradle installation is not required.
Linux and macOS:
./gradlew clean build
Windows:
.\gradlew.bat clean build
Repository structure
core/– domain, controller and network code, free of user-interface technologyapp-desktop/– the Compose Multiplatform user interface and the packaging tasksgithub_docs/– German and English manual sourceswebsite/– project website sourcespackaging/– platform-specific packaging files
CI status
Documentation
Builds
License
KST4Contest is distributed under the GNU General Public License v3.0.
Supporters/Sponsor
This Project is possible due to donations of the community.
You can sponsor KST4Contest here: Support on Ko-Fi. If you add an Display Name there you will be mentioned here.
The following people are sponsoring KST4Contest:
- Marco (DJ5KW)