Skip to content

Commit 0e48050

Browse files
committed
Merge pull request #306 from JLLeitschuh/fix/deploymentUI
Fixes various Deployment UI Issues
2 parents fb98e4e + 7707cf1 commit 0e48050

File tree

8 files changed

+130
-53
lines changed

8 files changed

+130
-53
lines changed

core/src/main/java/edu/wpi/grip/core/operations/networktables/NTManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public void updateSettings(ProjectSettingsChangedEvent event) {
6060

6161
NetworkTable.shutdown();
6262
if (projectSettings.getNetworkProtocol() == ProjectSettings.NetworkProtocol.NETWORK_TABLES) {
63-
NetworkTable.setIPAddress(projectSettings.computeNetworkTablesServer());
63+
NetworkTable.setIPAddress(projectSettings.computeNetworkProtocolServerAddress());
6464
NetworkTable.initialize();
6565
}
6666
}

core/src/main/java/edu/wpi/grip/core/settings/ProjectSettings.java

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@ public enum NetworkProtocol {
2727
@Setting(label = "FRC Team Number", description = "The team number, if used for FRC")
2828
private int teamNumber = 0;
2929

30-
@Setting(label = "NetworkTables Server", description = "The host that runs the NetworkTables server. If not " +
31-
"specified but NetworkTables is enabled, the hostname is derived from the team number.")
32-
private String networkTablesServer = "";
30+
@Setting(label = "NetworkTables Server Address", description = "The host that runs the Network Protocol server. If not " +
31+
"specified and Network Tables is specified as the protocol, the hostname is derived from the team number.")
32+
private String networkProtocolServerAddress = "";
33+
34+
@Setting(label = "Deploy Address", description = "The remote host that grip should be remotely deployed to. If not " +
35+
"specified and Network Tables is specified as the protocol, the hostname is derived from the team number.")
36+
private String deployAddress = "";
3337

3438
public void setNetworkProtocol(NetworkProtocol networkProtocol) {
3539
this.networkProtocol = checkNotNull(networkProtocol, "Network protocol cannot be null");
@@ -48,32 +52,48 @@ public int getTeamNumber() {
4852
return teamNumber;
4953
}
5054

51-
public void setNetworkTablesServer(String networkTablesServer) {
52-
this.networkTablesServer =
53-
checkNotNull(networkTablesServer, "NetworkTables server cannot be null");
55+
public void setNetworkProtocolServerAddress(String networkProtocolServerAddress) {
56+
this.networkProtocolServerAddress =
57+
checkNotNull(networkProtocolServerAddress, "Network Protocol Server Address cannot be null");
58+
}
59+
60+
public String getNetworkProtocolServerAddress() {
61+
return networkProtocolServerAddress;
62+
}
63+
64+
public void setDeployAddress(String deployAddress) {
65+
this.deployAddress = checkNotNull(deployAddress, "Deploy Address can not be null");
5466
}
5567

56-
public String getNetworkTablesServer() {
57-
return networkTablesServer;
68+
public String getDeployAddress() {
69+
return deployAddress;
5870
}
5971

6072
/**
6173
* @return The address of the machine that the NetworkTables server is running on. If
62-
* {@link #setNetworkTablesServer} is specified, that is returned, otherwise this is based on the team number.
74+
* {@link #setNetworkProtocolServerAddress} is specified, that is returned, otherwise this is based on the team number.
6375
*/
64-
public String computeNetworkTablesServer() {
65-
if (networkTablesServer.isEmpty()) {
76+
public String computeNetworkProtocolServerAddress() {
77+
if (networkProtocolServerAddress.isEmpty()) {
78+
return "roboio-" + teamNumber + "-frc.local";
79+
} else {
80+
return networkProtocolServerAddress;
81+
}
82+
}
83+
84+
public String computeDeployAddresss() {
85+
if (networkProtocolServerAddress.isEmpty()) {
6686
return "roboio-" + teamNumber + "-frc.local";
6787
} else {
68-
return networkTablesServer;
88+
return networkProtocolServerAddress;
6989
}
7090
}
7191

7292
@Override
7393
public String toString() {
7494
return MoreObjects.toStringHelper(this)
7595
.add("networkProtocol", networkProtocol)
76-
.add("networkTablesServer", networkTablesServer)
96+
.add("networkProtocolServerAddress", networkProtocolServerAddress)
7797
.add("teamNumber", teamNumber)
7898
.toString();
7999
}

ui/src/main/java/edu/wpi/grip/ui/DeployerController.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
import edu.wpi.grip.ui.util.deployment.DeployedInstanceManager;
1313
import javafx.application.Platform;
1414
import javafx.fxml.FXML;
15-
import javafx.scene.control.Accordion;
16-
import javafx.scene.control.DialogPane;
17-
import javafx.scene.control.ProgressBar;
18-
import javafx.scene.control.TextArea;
15+
import javafx.scene.control.*;
1916
import javafx.scene.layout.HBox;
17+
import javafx.scene.layout.Priority;
2018

2119
import java.io.IOException;
2220
import java.io.OutputStream;
@@ -122,9 +120,17 @@ private void onDeploy(DeployedInstanceManager manager) {
122120
})
123121
.done(deployedManager -> {
124122
Platform.runLater(() -> {
125-
controlsBox.getChildren().add(startStopButtonFactory.create(deployedManager));
123+
final Label startStopLabel = new Label("Start / Stop Deployed Instance: ");
124+
startStopLabel.setMaxWidth(Double.MAX_VALUE);
125+
startStopLabel.setMaxHeight(Double.MAX_VALUE);
126+
HBox.setHgrow(startStopLabel, Priority.SOMETIMES);
127+
final StartStoppableButton startStoppableButton = startStopButtonFactory.create(deployedManager);
128+
startStopLabel.setLabelFor(startStoppableButton);
129+
controlsBox.getChildren().addAll(startStopLabel, startStoppableButton);
126130
deploymentMethods.setDisable(true);
127131
progressIndicator.setProgress(-1);
132+
// Resize window to accommodate the added label
133+
getRoot().getScene().getWindow().sizeToScene();
128134
});
129135
});
130136

ui/src/main/java/edu/wpi/grip/ui/deployment/DeploymentOptionsController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ private void deploy() {
7777
});
7878
})
7979
.done((t) -> {
80+
setErrorText("Success! Waiting for start.");
8081
onDeployCallback.accept(t);
8182
Platform.runLater(() -> {
8283
deploySpinner.setVisible(false);
@@ -89,6 +90,7 @@ private void setErrorText(String text) {
8990
Platform.runLater(() -> {
9091
deployErrorText.setText(text);
9192
root.requestLayout();
93+
root.getScene().getWindow().sizeToScene();
9294
});
9395
}
9496

@@ -121,7 +123,8 @@ public InetAddress call() throws IOException {
121123
if (inetAddress.isReachable(1000)) {
122124
return inetAddress;
123125
} else {
124-
notify("Attempt " + i + "/" + attemptCount + " failed");
126+
// i + 1 so that the attempt counter is zero based.
127+
notify("Attempt " + i + 1 + "/" + attemptCount + " failed");
125128
}
126129
}
127130
throw new IOException("Failed to connect");

ui/src/main/java/edu/wpi/grip/ui/deployment/FRCAdvancedDeploymentOptionsController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.inject.Inject;
44
import com.google.inject.assistedinject.Assisted;
5+
import edu.wpi.grip.core.Pipeline;
56
import edu.wpi.grip.ui.util.deployment.DeployedInstanceManager;
67
import javafx.scene.control.Label;
78
import javafx.scene.control.TextField;
@@ -21,6 +22,7 @@ public class FRCAdvancedDeploymentOptionsController extends DeploymentOptionsCon
2122
private final Supplier<OutputStream> stdOut, stdErr;
2223

2324
private TextField address;
25+
private final String projectAddress;
2426

2527
public interface Factory {
2628
FRCAdvancedDeploymentOptionsController create(
@@ -32,11 +34,13 @@ FRCAdvancedDeploymentOptionsController create(
3234

3335
@Inject
3436
FRCAdvancedDeploymentOptionsController(DeployedInstanceManager.Factory deployedInstanceManagerFactor,
37+
Pipeline pipeline,
3538
@Assisted Consumer<DeployedInstanceManager> onDeployCallback,
3639
@Assisted("stdOut") Supplier<OutputStream> stdOut,
3740
@Assisted("stdErr") Supplier<OutputStream> stdErr) {
3841
super("FRC Advanced", onDeployCallback);
3942
this.deployedInstanceManagerFactor = deployedInstanceManagerFactor;
43+
this.projectAddress = pipeline.getProjectSettings().computeDeployAddresss();
4044
this.stdOut = stdOut;
4145
this.stdErr = stdErr;
4246

@@ -45,6 +49,7 @@ FRCAdvancedDeploymentOptionsController create(
4549
@Override
4650
protected void postInit() {
4751
this.address = new TextField();
52+
this.address.setText(projectAddress);
4853
this.address.setPromptText("roborio-[team number]-frc.local");
4954

5055
this.address.textProperty().addListener((observable, oldValue, newValue) -> {

ui/src/main/java/edu/wpi/grip/ui/deployment/FRCDeploymentOptionsController.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.google.inject.Inject;
44
import com.google.inject.assistedinject.Assisted;
5+
import edu.wpi.grip.core.Pipeline;
6+
import edu.wpi.grip.ui.util.Spinners;
57
import edu.wpi.grip.ui.util.deployment.DeployedInstanceManager;
68
import javafx.scene.control.Label;
79
import javafx.scene.control.Spinner;
@@ -20,6 +22,7 @@
2022
public class FRCDeploymentOptionsController extends DeploymentOptionsController {
2123

2224
private Spinner<Integer> teamNumberSpinner;
25+
private final int teamNumber;
2326
private final DeployedInstanceManager.Factory deployedInstanceManagerFactor;
2427
private final Supplier<OutputStream> stdOut, stdErr;
2528

@@ -33,36 +36,31 @@ FRCDeploymentOptionsController create(
3336

3437
@Inject
3538
FRCDeploymentOptionsController(DeployedInstanceManager.Factory deployedInstanceManagerFactor,
39+
Pipeline pipeline,
3640
@Assisted Consumer<DeployedInstanceManager> onDeployCallback,
3741
@Assisted("stdOut") Supplier<OutputStream> stdOut,
3842
@Assisted("stdErr") Supplier<OutputStream> stdErr) {
3943
super("FRC", onDeployCallback);
4044
this.deployedInstanceManagerFactor = deployedInstanceManagerFactor;
45+
this.teamNumber = pipeline.getProjectSettings().getTeamNumber();
4146
this.stdOut = stdOut;
4247
this.stdErr = stdErr;
4348
}
4449

4550
@Override
46-
@SuppressWarnings("PMD.IfElseStmtsMustUseBraces")
4751
protected void postInit() {
4852
final Label label = new Label("Team Number");
49-
final SpinnerValueFactory.IntegerSpinnerValueFactory spinnerValueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(0, Integer.MAX_VALUE, 190);
53+
final SpinnerValueFactory.IntegerSpinnerValueFactory spinnerValueFactory =
54+
new SpinnerValueFactory.IntegerSpinnerValueFactory(0, Integer.MAX_VALUE, teamNumber);
5055
this.teamNumberSpinner = new Spinner(spinnerValueFactory);
51-
this.teamNumberSpinner.setEditable(true);
52-
// Ensure the value entered is only a number
53-
this.teamNumberSpinner.getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
54-
if ("".equals(newValue)) {
55-
teamNumberSpinner.getEditor().setText(Integer.toString(0));
56-
} else try {
57-
int value = Integer.parseInt(newValue);
58-
teamNumberSpinner.getEditor().setText(Integer.toString(value));
59-
} catch (NumberFormatException e) {
60-
teamNumberSpinner.getEditor().setText(oldValue);
61-
}
62-
});
56+
Spinners.makeEditableSafely(teamNumberSpinner, Integer::valueOf);
57+
label.setLabelFor(teamNumberSpinner);
58+
6359
getOptionsGrid().addRow(0, label, this.teamNumberSpinner);
6460
}
6561

62+
63+
6664
@Override
6765
protected Promise<DeployedInstanceManager, String, String> onDeploy() {
6866
final Deferred<DeployedInstanceManager, String, String> deferredDeploy = new DeferredObject<>();

ui/src/main/java/edu/wpi/grip/ui/pipeline/input/NumberSpinnerInputSocketController.java

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import edu.wpi.grip.core.events.SocketChangedEvent;
88
import edu.wpi.grip.ui.pipeline.SocketHandleView;
99
import edu.wpi.grip.ui.util.GRIPPlatform;
10+
import edu.wpi.grip.ui.util.Spinners;
1011
import javafx.beans.InvalidationListener;
1112
import javafx.fxml.FXML;
1213
import javafx.scene.control.Spinner;
1314
import javafx.scene.control.SpinnerValueFactory;
14-
import javafx.util.StringConverter;
1515

1616
import static com.google.common.base.Preconditions.checkArgument;
1717

@@ -55,12 +55,9 @@ public interface Factory {
5555
public void initialize() {
5656
super.initialize();
5757
final Spinner<Double> spinner = new Spinner<>(this.valueFactory);
58-
spinner.setEditable(true);
58+
Spinners.makeEditableSafely(spinner, Double::valueOf);
5959
spinner.disableProperty().bind(this.getHandle().connectedProperty());
60-
spinner.focusedProperty().addListener((s, ov, nv) -> {// Code found at http://stackoverflow.com/questions/32340476/manually-typing-in-text-in-javafx-spinner-is-not-updating-the-value-unless-user
61-
if (nv) return;
62-
commitEditorText(spinner);
63-
});
60+
6461
this.setContent(spinner);
6562
}
6663

@@ -80,17 +77,4 @@ public void updateSpinnerFromSocket(SocketChangedEvent event) {
8077
}
8178
}
8279

83-
// Code found at http://stackoverflow.com/questions/32340476/manually-typing-in-text-in-javafx-spinner-is-not-updating-the-value-unless-user
84-
private <T> void commitEditorText(Spinner<T> spinner) {
85-
if (!spinner.isEditable()) return;
86-
String text = spinner.getEditor().getText();
87-
SpinnerValueFactory<T> valueFactory = spinner.getValueFactory();
88-
if (valueFactory != null) {
89-
StringConverter<T> converter = valueFactory.getConverter();
90-
if (converter != null) {
91-
T value = converter.fromString(text);
92-
valueFactory.setValue(value);
93-
}
94-
}
95-
}
9680
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package edu.wpi.grip.ui.util;
2+
3+
4+
import javafx.scene.control.Spinner;
5+
import javafx.scene.control.SpinnerValueFactory;
6+
import javafx.util.StringConverter;
7+
8+
import java.util.function.Function;
9+
10+
/**
11+
* Utility methods to set up spinners in a safe way.
12+
*/
13+
public final class Spinners {
14+
15+
private Spinners() {
16+
/* no-op */
17+
}
18+
19+
/**
20+
* Makes the spinner editable.
21+
* Ensures that the values will be committed when focus is lost.
22+
* Ensures that the only values that the spinner can accept are parable into whatever number type they represent.
23+
* @param <T> The number type of the spinner
24+
*/
25+
@SuppressWarnings("PMD.IfElseStmtsMustUseBraces")
26+
public static <T extends Number> void makeEditableSafely(Spinner<T> spinner, Function<String, T> parseToNumber) {
27+
spinner.setEditable(true);
28+
spinner.focusedProperty().addListener((s, ov, nv) -> {
29+
if (nv) return;
30+
commitEditorText(spinner);
31+
});
32+
// Ensure the value entered is only a number
33+
spinner.getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
34+
if ("".equals(newValue)) {
35+
spinner.getEditor().setText("0");
36+
} else try {
37+
T value = parseToNumber.apply(newValue);
38+
spinner.getEditor().setText(value.toString());
39+
} catch (NumberFormatException e) {
40+
spinner.getEditor().setText(oldValue);
41+
}
42+
});
43+
}
44+
45+
/**
46+
*
47+
* @see <a href="http://stackoverflow.com/questions/32340476/manually-typing-in-text-in-javafx-spinner-is-not-updating-the-value-unless-user">Stack Overflow Post</a>
48+
*/
49+
private static <T> void commitEditorText(Spinner<T> spinner) {
50+
if (!spinner.isEditable()) return;
51+
String text = spinner.getEditor().getText();
52+
SpinnerValueFactory<T> valueFactory = spinner.getValueFactory();
53+
if (valueFactory != null) {
54+
StringConverter<T> converter = valueFactory.getConverter();
55+
if (converter != null) {
56+
T value = converter.fromString(text);
57+
valueFactory.setValue(value);
58+
}
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)