Spruce up JavaFX client, README
This commit is contained in:
parent
79884e8e8e
commit
47b7980f24
@ -5,7 +5,7 @@ packages:
|
|||||||
sources:
|
sources:
|
||||||
- https://git.sr.ht/~crg/lingo
|
- https://git.sr.ht/~crg/lingo
|
||||||
artifacts:
|
artifacts:
|
||||||
- lingo/server/target/lingo-server-1.0.jar
|
- lingo/server/target/lingo-server.jar
|
||||||
tasks:
|
tasks:
|
||||||
- build: |
|
- build: |
|
||||||
cd lingo
|
cd lingo
|
||||||
|
29
README.md
29
README.md
@ -1,19 +1,24 @@
|
|||||||
# Lingo WebSocket
|
## Lingo
|
||||||
|
|
||||||
Lingo with WebSockets
|
A word guessing game based on the [game show](https://en.wikipedia.org/wiki/Lingo_(American_game_show)).
|
||||||
|
|
||||||
## Build
|
#### Browser client
|
||||||
|
|
||||||
`mvn clean install`
|
- Practice: https://lingo.charego.com/practice.html
|
||||||
|
- Competitive: https://lingo.charego.com
|
||||||
|
|
||||||
## Launch server
|
#### JavaFX client
|
||||||
|
|
||||||
`mvn -f ./server/pom.xml spring-boot:run`
|
- Requirements: Java 11, Maven 3
|
||||||
|
- Build: `mvn clean install`
|
||||||
|
- Start client: `mvn -f client javafx:run`
|
||||||
|
|
||||||
## Launch client
|
#### Running locally
|
||||||
|
|
||||||
`mvn -f ./client/pom.xml exec:java`
|
- Build: `mvn clean install`
|
||||||
|
- Start server
|
||||||
Practice: <http://localhost:8080/practice.html>
|
* Default port (8080): `java -jar server/target/lingo-server.jar`
|
||||||
|
* Custom port: `java -jar server/target/lingo-server.jar --server.port=<port>`
|
||||||
Multiplayer: <http://localhost:8080>
|
- Start client
|
||||||
|
* Browser: `open http://localhost:<port>`
|
||||||
|
* JavaFX: `mvn -f client javafx:run -Dlingo-url=http://localhost:<port>`
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
|
||||||
<listEntry value="/lingo-websocket-client/src/main/java/lingo/client/bootstrap/LingoClient.java"/>
|
|
||||||
</listAttribute>
|
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
|
||||||
<listEntry value="1"/>
|
|
||||||
</listAttribute>
|
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
|
||||||
</listAttribute>
|
|
||||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" path="1" type="4"/> "/>
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/lingo-websocket-client/src/main/config" path="3" type="2"/> "/>
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="lingo-websocket-client" type="1"/> "/>
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER" path="3" type="4"/> "/>
|
|
||||||
</listAttribute>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
|
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="lingo.client.bootstrap.LingoClient"/>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="lingo-websocket-client"/>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>
|
|
||||||
</launchConfiguration>
|
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<javafx.version>11.0.2</javafx.version>
|
<javafx.version>11.0.2</javafx.version>
|
||||||
|
<lingo.url>https://lingo.charego.com</lingo.url>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -48,15 +49,23 @@
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-maven-plugin</artifactId>
|
||||||
|
<version>0.0.4</version>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>com.charego.lingo.client.bootstrap.LingoClient</mainClass>
|
||||||
|
<options>
|
||||||
|
<option>-Dlingo.url=${lingo.url}</option>
|
||||||
|
</options>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>com.charego.lingo.client.bootstrap.LingoClient</mainClass>
|
<mainClass>com.charego.lingo.client.bootstrap.LingoClient</mainClass>
|
||||||
<addResourcesToClasspath>true</addResourcesToClasspath>
|
<addResourcesToClasspath>true</addResourcesToClasspath>
|
||||||
<additionalClasspathElements>
|
|
||||||
<additionalClasspathElement>src/main/config</additionalClasspathElement>
|
|
||||||
</additionalClasspathElements>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
|
|
||||||
|
|
||||||
# Development
|
|
||||||
web.base.url: http://localhost:8080
|
|
||||||
web.socket.url: ws://localhost:8080/sockjs
|
|
||||||
|
|
||||||
# Production
|
|
||||||
#web.base.url: https://lingo.charego.com
|
|
||||||
#web.socket.url: wss://lingo.charego.com/sockjs
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
logging:
|
|
||||||
level:
|
|
||||||
com.charego.lingo: DEBUG
|
|
@ -66,8 +66,9 @@ public class MultiplayerConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RestTemplate restTemplate(Environment env) {
|
public RestTemplate restTemplate(Environment env) {
|
||||||
|
String webServerUrl = env.getRequiredProperty("lingo.url");
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
restTemplate.setUriTemplateHandler(new RootUriTemplateHandler(env.getProperty("web.base.url")));
|
restTemplate.setUriTemplateHandler(new RootUriTemplateHandler(webServerUrl));
|
||||||
return restTemplate;
|
return restTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import javax.annotation.PreDestroy;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.core.task.TaskExecutor;
|
import org.springframework.core.task.TaskExecutor;
|
||||||
import org.springframework.messaging.simp.stomp.StompCommand;
|
import org.springframework.messaging.simp.stomp.StompCommand;
|
||||||
import org.springframework.messaging.simp.stomp.StompFrameHandler;
|
import org.springframework.messaging.simp.stomp.StompFrameHandler;
|
||||||
@ -26,8 +26,8 @@ public class StompTemplate {
|
|||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(StompTemplate.class);
|
private static final Logger log = LoggerFactory.getLogger(StompTemplate.class);
|
||||||
|
|
||||||
@Value("${web.socket.url}")
|
@Autowired
|
||||||
private String webSocketUrl;
|
private Environment env;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TaskExecutor taskExecutor;
|
private TaskExecutor taskExecutor;
|
||||||
@ -49,6 +49,8 @@ public class StompTemplate {
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void postConstruct() {
|
private void postConstruct() {
|
||||||
|
String webServerUrl = env.getRequiredProperty("lingo.url");
|
||||||
|
String webSocketUrl = webServerUrl.replace("http", "ws") + "/sockjs";
|
||||||
log.info("Connecting to STOMP endpoint: " + webSocketUrl);
|
log.info("Connecting to STOMP endpoint: " + webSocketUrl);
|
||||||
taskExecutor.execute(() -> stompClient.connect(webSocketUrl, new WebSocketSessionHandler()));
|
taskExecutor.execute(() -> stompClient.connect(webSocketUrl, new WebSocketSessionHandler()));
|
||||||
taskExecutor.execute(new WebSocketSessionListener());
|
taskExecutor.execute(new WebSocketSessionListener());
|
||||||
|
@ -44,7 +44,7 @@ public class SinglePlayerPresenter {
|
|||||||
|
|
||||||
public SinglePlayerPresenter(WordRepository wordRepo, int wordLength, EventHandler<ActionEvent> backButtonHandler) {
|
public SinglePlayerPresenter(WordRepository wordRepo, int wordLength, EventHandler<ActionEvent> backButtonHandler) {
|
||||||
backButton = new Button("Back");
|
backButton = new Button("Back");
|
||||||
backButton.getStyleClass().add("game-nav");
|
backButton.getStyleClass().add("navigation");
|
||||||
StackPane.setAlignment(backButton, Pos.BOTTOM_LEFT);
|
StackPane.setAlignment(backButton, Pos.BOTTOM_LEFT);
|
||||||
StackPane.setMargin(backButton, new Insets(0, 0, 10, 10));
|
StackPane.setMargin(backButton, new Insets(0, 0, 10, 10));
|
||||||
backButton.setOnAction(backButtonHandler);
|
backButton.setOnAction(backButtonHandler);
|
||||||
|
@ -15,4 +15,8 @@ module com.charego.lingo.client {
|
|||||||
requires spring.messaging;
|
requires spring.messaging;
|
||||||
requires spring.web;
|
requires spring.web;
|
||||||
requires spring.websocket;
|
requires spring.websocket;
|
||||||
|
exports com.charego.lingo.client.bootstrap;
|
||||||
|
exports com.charego.lingo.client.multiplayer;
|
||||||
|
opens com.charego.lingo.client.bootstrap to javafx.fxml, spring.core;
|
||||||
|
opens com.charego.lingo.client.multiplayer to javafx.fxml, spring.core;
|
||||||
}
|
}
|
||||||
|
2
client/src/main/resources/application.properties
Normal file
2
client/src/main/resources/application.properties
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html
|
||||||
|
logging.level.com.charego.lingo = DEBUG
|
@ -3,6 +3,7 @@
|
|||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.geometry.Pos?>
|
<?import javafx.geometry.Pos?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.layout.BorderPane?>
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
@ -14,16 +15,20 @@
|
|||||||
|
|
||||||
<center>
|
<center>
|
||||||
<BorderPane fx:id="gameModeChooser">
|
<BorderPane fx:id="gameModeChooser">
|
||||||
|
<top>
|
||||||
|
<VBox alignment="CENTER" prefHeight="100.0" prefWidth="100.0" styleClass="header">
|
||||||
|
<Label text="Lingo" styleClass="title"/>
|
||||||
|
<Label text="word guessing game" styleClass="subtitle"/>
|
||||||
|
</VBox>
|
||||||
|
</top>
|
||||||
<center>
|
<center>
|
||||||
<VBox spacing="20" alignment="CENTER">
|
<VBox spacing="20" alignment="CENTER">
|
||||||
<children>
|
<Button text="Play a practice game" onAction="#showSinglePlayer" prefWidth="350" styleClass="gamemode,practice" />
|
||||||
<Button text="Practice" onAction="#showSinglePlayer" prefWidth="350" styleClass="game-mode" />
|
<Button text="Join a multiplayer game" onAction="#showMultiplayer" prefWidth="350" styleClass="gamemode,multiplayer" />
|
||||||
<Button text="Multiplayer" onAction="#showMultiplayer" prefWidth="350" styleClass="game-mode" />
|
|
||||||
</children>
|
|
||||||
</VBox>
|
</VBox>
|
||||||
</center>
|
</center>
|
||||||
<bottom>
|
<bottom>
|
||||||
<Button text="Exit" onAction="#exit" prefWidth="50" styleClass="game-nav">
|
<Button text="Exit" onAction="#exit" prefWidth="50" styleClass="navigation">
|
||||||
<BorderPane.alignment>
|
<BorderPane.alignment>
|
||||||
<Pos fx:value="BOTTOM_LEFT" />
|
<Pos fx:value="BOTTOM_LEFT" />
|
||||||
</BorderPane.alignment>
|
</BorderPane.alignment>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<children>
|
<children>
|
||||||
<Canvas fx:id="canvas" width="650" height="420" onKeyPressed="#keyPressed" />
|
<Canvas fx:id="canvas" width="650" height="420" onKeyPressed="#keyPressed" />
|
||||||
<WebView fx:id="webView" prefWidth="650" prefHeight="420" />
|
<WebView fx:id="webView" prefWidth="650" prefHeight="420" />
|
||||||
<Button fx:id="backButton" text="Back" prefWidth="50" styleClass="game-nav">
|
<Button fx:id="backButton" text="Back" prefWidth="50" styleClass="navigation">
|
||||||
<StackPane.alignment>
|
<StackPane.alignment>
|
||||||
<Pos fx:value="BOTTOM_LEFT" />
|
<Pos fx:value="BOTTOM_LEFT" />
|
||||||
</StackPane.alignment>
|
</StackPane.alignment>
|
||||||
|
@ -1,12 +1,43 @@
|
|||||||
|
.button {
|
||||||
|
-fx-cursor: hand;
|
||||||
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
-fx-font-family: Helvetica;
|
-fx-font-family: Helvetica;
|
||||||
-fx-font-smoothing-type: gray;
|
-fx-font-smoothing-type: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-mode {
|
.header {
|
||||||
|
-fx-background-color: steelblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
-fx-font-size: 32px;
|
||||||
|
-fx-text-fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
-fx-font-size: 24px;
|
||||||
|
-fx-text-fill: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gamemode {
|
||||||
|
-fx-background-radius: 10px;
|
||||||
|
-fx-border-color: black;
|
||||||
|
-fx-border-radius: 10px;
|
||||||
-fx-font-size: 24px;
|
-fx-font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-nav {
|
.gamemode.practice {
|
||||||
-fx-font-size: 12px;
|
-fx-text-fill: forestgreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gamemode.multiplayer {
|
||||||
|
-fx-text-fill: steelblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation {
|
||||||
|
-fx-background-color: steelblue;
|
||||||
|
-fx-font-size: 12px;
|
||||||
|
-fx-text-fill: white;
|
||||||
}
|
}
|
||||||
|
12
pom.xml
12
pom.xml
@ -23,18 +23,8 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<module>api</module>
|
<module>api</module>
|
||||||
<module>common</module>
|
<module>common</module>
|
||||||
|
<module>client</module>
|
||||||
<module>server</module>
|
<module>server</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<!-- Disable client module by default -->
|
|
||||||
<!-- The build fails under headless JDK -->
|
|
||||||
<profile>
|
|
||||||
<id>javafx</id>
|
|
||||||
<modules>
|
|
||||||
<module>client</module>
|
|
||||||
</modules>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
|
||||||
<listEntry value="/lingo-websocket-server/src/main/java/lingo/server/LingoServer.java"/>
|
|
||||||
</listAttribute>
|
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
|
||||||
<listEntry value="1"/>
|
|
||||||
</listAttribute>
|
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
|
||||||
</listAttribute>
|
|
||||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" path="1" type="4"/> "/>
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/lingo-websocket-server/src/main/config" path="3" type="2"/> "/>
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="lingo-websocket-server" type="1"/> "/>
|
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER" path="3" type="4"/> "/>
|
|
||||||
</listAttribute>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
|
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="lingo.server.LingoServer"/>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="lingo-websocket-server"/>
|
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>
|
|
||||||
</launchConfiguration>
|
|
@ -43,10 +43,7 @@
|
|||||||
<!-- Add src/main/resources to the classpath -->
|
<!-- Add src/main/resources to the classpath -->
|
||||||
<!-- Remove duplicate resources from target/classes -->
|
<!-- Remove duplicate resources from target/classes -->
|
||||||
<addResources>true</addResources>
|
<addResources>true</addResources>
|
||||||
<folders>
|
<finalName>${project.artifactId}</finalName>
|
||||||
<!-- Add src/main/config to the classpath -->
|
|
||||||
<folder>${project.basedir}/src/main/config</folder>
|
|
||||||
</folders>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<!-- Repackage as executable JAR (java -jar) -->
|
<!-- Repackage as executable JAR (java -jar) -->
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
|
|
||||||
|
|
||||||
server:
|
|
||||||
address: localhost
|
|
||||||
port: 8080
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
logging:
|
|
||||||
level:
|
|
||||||
lingo: DEBUG
|
|
||||||
web: DEBUG
|
|
2
server/src/main/resources/application.properties
Normal file
2
server/src/main/resources/application.properties
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html
|
||||||
|
logging.level.com.charego.lingo = DEBUG
|
Loading…
x
Reference in New Issue
Block a user