/**
* Classic Super 95 gasoline
*/
- SUPER,
+ SUPER("Super 95"),
/**
* Diesel (hopefully lead-free)
*/
- DIESEL,
+ DIESEL("Diesel"),
/**
* If you want to feel like saving the planet: Now with at most 10% ethanol in
* your gasoline
*/
- SUPER_E10,
+ SUPER_E10("Super E10"),
/**
* Fancy premium diesel
*/
- PREMIUM_DIESEL,
+ PREMIUM_DIESEL("Premium Diesel"),
/**
* Gas, Gas, Gas, I'm gonna step on the gas
*/
- AUTOGAS
+ AUTOGAS("Car gas");
+
+ public String name;
+
+ private FuelType(String name) {
+ this.name = name;
+ }
}
*/
public static ArrayList<FuelStation> fuelStations = new ArrayList<FuelStation>(Arrays.asList(initialFuelStations));
- /**
- * Main method
- *
- * @param args Program arguments (not in use)
- */
- public static void main(String[] args) {
- // javax.swing.SwingUtilities.invokeLater(() -> {
- // FuelStationUI ui = new FuelStationUI();
- // ui.setVisible(true);
- // });
- }
-
/**
* Get an array of fuel stations which have a number of vending machines
* that is equal to {@code number_of_vending_machines}
+++ /dev/null
-package de.diejungsvondertanke.tankstelle.controllers;
-
-public class ControllerRegistry {
- private static FuelStationUIController main;
-
- public static void registerMain(FuelStationUIController controller) {
- main = controller;
- }
-
- public static FuelStationUIController getMain() {
- return main;
- }
-}
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
-import javafx.scene.control.*;
+import javafx.scene.control.Alert;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
+/**
+ * Main controller class
+ */
public class FuelStationUIController {
- // @FXML
- // public ComboBox<String> comboFuelStations;
-
- // @FXML
- // public ComboBox<FuelType> comboFuelTypes;
-
- // @FXML
- // private TabPane tabPane;
-
- // // child controllers
- // @FXML
- // private HBox resultTab;
-
- // @FXML
- // private HBox priceTab;
-
- // @FXML
- // private HBox stockTab;
-
- // @FXML
- // private HBox searchTab;
-
- // @FXML
- // private HBox newStationTab;
-
- // @FXML
- // private HBox overviewTab;
-
- // @FXML
- // private TextArea outputArea;
-
@FXML
public ComboBox<String> comboFuelStations;
@FXML
private NewStationTabController newStationTabController;
private OverviewTabController overviewTabController;
+ /**
+ * Automatically called initialize() function.
+ *
+ * This is the "main" UI setup routine. For timing reasons, this will/must load
+ * every subtab manually to get the controller object and set the
+ * {@link FuelStationUIController} controller in every subtab controller
+ * element.
+ *
+ * If not done correctly, using the controller in the subtabs WILL FAIL.
+ *
+ * USING THE CONTROLLER OBJECT INSIDE THE {@code initialize()} FUNCTION OF THE
+ * SUBTABS IS NOT PERMITTED AND WILL ALWAYS BE {@code null} DUE TO TIMING
+ */
@FXML
public void initialize() {
// Load all tabs manually and keep controllers
loadTab("/ui/ResultTab.fxml", resultTabContainer, (ResultTabController c) -> {
resultTabController = c;
resultTabController.setParentController(this);
+ resultTabController.refreshList();
});
loadTab("/ui/PriceTab.fxml", priceTabContainer, (PriceTabController c) -> {
priceTabController = c;
(OverviewTabController c) -> {
overviewTabController = c;
overviewTabController.setParentController(this);
- overviewTabController.refresh();
+ // overviewTabController.refresh();
});
} catch (Exception e) {
refreshStationNames();
}
- // Generic loader helper
- // private <T> void loadTab(String fxmlPath, Parent placeholder,
- // java.util.function.Consumer<T> controllerSetter) {
- // try {
- // FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlPath));
- // Parent content = loader.load();
- // T controller = loader.getController();
- // controllerSetter.accept(controller);
- // placeholder.getChildren().setAll(content);
- // } catch (IOException e) {
- // e.printStackTrace();
- // }
- // }
-
+ /**
+ * Generic tab loader helper
+ *
+ * @param <T> I have no idea what this does other than generalise
+ * the type for the consumer
+ * @param fxmlPath Path to the .fxml resource file
+ * @param container A container that inherits from {@link Parent}, for
+ * example {@link GridPane}, {@link HBoc} or
+ * {@link BorderPane}
+ * @param controllerConsumer A {@link Consumer} to
+ * @throws IOException If loading the Tab failed because the .fxml file was not
+ * found
+ */
private <T> void loadTab(String fxmlPath, Parent container, Consumer<T> controllerConsumer) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlPath));
Parent loaded = loader.load();
T controller = loader.getController();
// Add loaded node to the container
- if (container instanceof Pane pane) {
- pane.getChildren().setAll(loaded);
+ if (container instanceof BorderPane border) {
+ border.setCenter(loaded);
} else if (container instanceof ScrollPane scroll) {
scroll.setContent(loaded);
- } else if (container instanceof BorderPane border) {
- border.setCenter(loaded);
+ } else if (container instanceof Pane pane) {
+ pane.getChildren().setAll(loaded);
} else {
throw new IllegalArgumentException("Unsupported container type: " + container.getClass());
}
return Main.fuelStations.get(idx);
}
+ @FXML
public void refreshStationNames() {
comboFuelStations.getItems().setAll(
Main.fuelStations.stream()
.map(this::getDisplayName)
.toList());
+
+ resultTabController.refreshList();
+ overviewTabController.refresh();
}
+ /**
+ * Create some display String for the fuel station lists in the UI
+ *
+ * @param fs a {@link FuelStation} object to get the display name for
+ * @return the display name string
+ */
public String getDisplayName(FuelStation fs) {
int index = Main.fuelStations.indexOf(fs);
if (index >= 0) {
import de.diejungsvondertanke.tankstelle.Main;
import javafx.fxml.FXML;
-import javafx.scene.control.*;
+import javafx.scene.control.RadioButton;
+import javafx.scene.control.TextField;
public class NewStationTabController {
package de.diejungsvondertanke.tankstelle.controllers;
-import de.diejungsvondertanke.tankstelle.*;
+import de.diejungsvondertanke.tankstelle.Fuel;
+import de.diejungsvondertanke.tankstelle.FuelStation;
+import de.diejungsvondertanke.tankstelle.Main;
+import javafx.application.Platform;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.Parent;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
@FXML
public void initialize() {
- colStation.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().station()));
- colType.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().type()));
- colFuel.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().fuel()));
- colAmount.setCellValueFactory(data -> new SimpleFloatProperty(data.getValue().amount()).asObject());
- colCapacity.setCellValueFactory(data -> new SimpleIntegerProperty(data.getValue().capacity()).asObject());
- colPrice.setCellValueFactory(data -> new SimpleFloatProperty(data.getValue().price()).asObject());
+ colStation.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().getStation()));
+ colType.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().getType()));
+ colFuel.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().getFuel()));
+ colAmount.setCellValueFactory(data -> new SimpleFloatProperty(data.getValue().getAmount()).asObject());
+ colCapacity.setCellValueFactory(data -> new SimpleIntegerProperty(data.getValue().getCapacity()).asObject());
+ colPrice.setCellValueFactory(data -> new SimpleFloatProperty(data.getValue().getPrice()).asObject());
}
@FXML
public void refresh() {
table.getItems().clear();
+ // ObservableList<FuelRow> list = FXCollections.observableArrayList();
+ // table.getItems().add(new FuelRow("TestStation", "TestType", "Diesel", 123,
+
+ // 999, 1.23f));
+ System.out.println("On FX thread? " + Platform.isFxApplicationThread());
for (FuelStation station : Main.fuelStations) {
for (Fuel f : station.fuels) {
+ // System.out.println("Row: " +
+ // parentController.getDisplayName(station) + " | " +
+ // station.getClass().getSimpleName() + " | " +
+ // f.FUEL_TYPE + " | " +
+ // f.getStored_amount() + " | " +
+ // f.CAPACITY + " | " +
+ // f.getPrice());
+
table.getItems().add(
new FuelRow(
parentController.getDisplayName(station),
f.getStored_amount(),
f.CAPACITY,
f.getPrice()));
+ // System.out.println("Processed " + f.toString());
}
}
+ // System.out.print(list);
+ // table.setItems(list);
}
- public record FuelRow(
- String station,
- String type,
- String fuel,
- float amount,
- int capacity,
- float price) {
+ public static void printNodeTree(Node node, int depth) {
+ // Indentation
+ String indent = " ".repeat(depth);
+
+ // Print this node
+ System.out.println(indent + node.getClass().getSimpleName()
+ + (node.getId() != null ? " [id=" + node.getId() + "]" : ""));
+
+ // If the node is a Parent, get its children and recurse
+ if (node instanceof Parent parent) {
+ for (Node child : parent.getChildrenUnmodifiable()) {
+ printNodeTree(child, depth + 1);
+ }
+ }
+ }
+
+ public class FuelRow {
+
+ String station;
+ String type;
+ String fuel;
+ float amount;
+ int capacity;
+ float price;
+
+ public String getStation() {
+ return station;
+ }
+
+ public void setStation(String station) {
+ this.station = station;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getFuel() {
+ return fuel;
+ }
+
+ public void setFuel(String fuel) {
+ this.fuel = fuel;
+ }
+
+ public float getAmount() {
+ return amount;
+ }
+
+ public void setAmount(float amount) {
+ this.amount = amount;
+ }
+
+ public int getCapacity() {
+ return capacity;
+ }
+
+ public void setCapacity(int capacity) {
+ this.capacity = capacity;
+ }
+
+ public float getPrice() {
+ return price;
+ }
+
+ public void setPrice(float price) {
+ this.price = price;
+ }
+
+ public FuelRow(String station, String type, String fuel, float amount, int capacity, float price) {
+ this.station = station;
+ this.type = type;
+ this.fuel = fuel;
+ this.amount = amount;
+ this.capacity = capacity;
+ this.price = price;
+ }
+
}
}
.formatted(type, parentController.getDisplayName(station), price));
txtPrice.clear();
+ parentController.refreshStationNames();
} catch (NumberFormatException ex) {
parentController.showError("Invalid number.");
package de.diejungsvondertanke.tankstelle.controllers;
-import de.diejungsvondertanke.tankstelle.*;
+import de.diejungsvondertanke.tankstelle.FuelStation;
+import de.diejungsvondertanke.tankstelle.FuelType;
+import de.diejungsvondertanke.tankstelle.Main;
import de.diejungsvondertanke.tankstelle.error.NoSuchFuelTypeError;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;
+import javafx.scene.control.SelectionMode;
public class ResultTabController {
private ListView<String> listFuelStations;
private FuelStationUIController parentController;
+ @FXML
+ public void initialize() {
+ listFuelStations.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ }
+
public void setParentController(FuelStationUIController parentController) {
this.parentController = parentController;
}
package de.diejungsvondertanke.tankstelle.controllers;
-import de.diejungsvondertanke.tankstelle.*;
+import de.diejungsvondertanke.tankstelle.FuelStation;
+import de.diejungsvondertanke.tankstelle.FuelType;
+import de.diejungsvondertanke.tankstelle.Main;
import de.diejungsvondertanke.tankstelle.error.NoSuchFuelTypeError;
import javafx.fxml.FXML;
package de.diejungsvondertanke.tankstelle.controllers;
-import de.diejungsvondertanke.tankstelle.*;
+import de.diejungsvondertanke.tankstelle.Fuel;
+import de.diejungsvondertanke.tankstelle.FuelStation;
+import de.diejungsvondertanke.tankstelle.FuelType;
import de.diejungsvondertanke.tankstelle.error.NoSuchFuelTypeError;
import javafx.fxml.FXML;
-import javafx.scene.control.*;
+import javafx.scene.control.RadioButton;
+import javafx.scene.control.TextField;
public class StockTabController {
return;
}
station.set_stored_amount(value, type);
+ parentController.refreshStationNames();
parentController.appendOutput("Stock of %s at %s set to %.2f L"
.formatted(type, parentController.getDisplayName(station), value));
} else {
return;
}
station.add_stored_amount(value, type);
+ parentController.refreshStationNames();
parentController.appendOutput("Stock of %s at %s changed by %.2f L"
.formatted(type, parentController.getDisplayName(station), value));
}
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
+import javafx.scene.image.Image;
import javafx.stage.Stage;
public class JFX extends Application {
public static FuelStationUIController controller;
static Parent parent;
+ static Scene scene;
@Override
public void start(Stage s) throws Exception {
stage = s;
Parent parent = loadFXML("FuelStationUI");
- Scene scene = new Scene(parent);
+ scene = new Scene(parent);
stage.setScene(scene);
stage.setTitle("Fuel Station Management System");
+ stage.getIcons().add(new Image(getClass().getResourceAsStream("/icon/gasstation_4334.png")));
+ initializeKeybinds();
stage.show();
}
controller = fxmlLoader.getController();
return parent;
}
+
+ /**
+ * Set the keybinds and set the default closing behaviour to run the quit()
+ * function
+ */
+ private void initializeKeybinds() {
+ // Override the default close behaviour
+ stage.setOnCloseRequest((e) -> {
+ exit();
+ });
+ stage.setFullScreenExitKeyCombination(null);
+
+ // register keybinds here
+ scene.setOnKeyPressed((e) -> {
+ switch (e.getCode()) {
+ case ENTER:
+ if (e.isAltDown()) {
+ if (stage.isFullScreen())
+ stage.setFullScreen(false);
+ else
+ stage.setFullScreen(true);
+
+ }
+ break;
+ case F11:
+
+ if (stage.isFullScreen())
+ stage.setFullScreen(false);
+ else
+ stage.setFullScreen(true);
+ break;
+
+ case F12:
+ if (stage.isMaximized())
+ stage.setMaximized(false);
+ else
+ stage.setMaximized(true);
+ break;
+
+ default:
+ break;
+ }
+ });
+ }
+
+ void exit() {
+ System.exit(0);
+ }
+
+ void exit(int status) {
+ System.exit(status);
+ }
+
+ private void quit() {
+ System.out.println("Exiting program, have a nice day :)");
+ }
}
fx:controller="de.diejungsvondertanke.tankstelle.controllers.NewStationTabController"
hgap="10" vgap="10">
<padding>
- <Insets top="15" right="15" bottom="15" left="15"/>
+ <Insets top="15" right="15" bottom="15" left="15" />
</padding>
<Label text="Type:" GridPane.rowIndex="0" GridPane.columnIndex="0" />
- <ToggleGroup fx:id="group" />
+ <fx:define>
+ <ToggleGroup fx:id="group" />
+ </fx:define>
<RadioButton fx:id="rbSmall" text="Small" selected="true"
toggleGroup="$group"
GridPane.rowIndex="1" GridPane.columnIndex="0" />
<BorderPane xmlns:fx="http://javafx.com/fxml"
fx:controller="de.diejungsvondertanke.tankstelle.controllers.OverviewTabController"
+ fx:id="overviewTabContainer"
>
<padding>
- <Insets top="15" right="15" bottom="15" left="15"/>
+ <Insets top="15" right="15" bottom="15" left="15" />
</padding>
<top>
- <HBox spacing="10">
+ <HBox spacing="10" HBox.hgrow="ALWAYS">
<Label text="Overview of all fuels" />
<Button text="Refresh" onAction="#refresh" />
</HBox>
</top>
<center>
- <TableView fx:id="table">
- <columns>
- <TableColumn fx:id="colStation" text="Fuel Station" />
- <TableColumn fx:id="colType" text="Station Type" />
- <TableColumn fx:id="colFuel" text="Fuel" />
- <TableColumn fx:id="colAmount" text="Amount (L)" />
- <TableColumn fx:id="colCapacity" text="Capacity (L)" />
- <TableColumn fx:id="colPrice" text="Price (€/L)" />
- </columns>
- </TableView>
+ <VBox spacing="10" VBox.vgrow="ALWAYS">
+
+ <TableView fx:id="table" VBox.vgrow="ALWAYS">
+ <columns>
+ <TableColumn fx:id="colStation" text="Fuel Station" />
+ <TableColumn fx:id="colType" text="Station Type" />
+ <TableColumn fx:id="colFuel" text="Fuel" />
+ <TableColumn fx:id="colAmount" text="Amount (L)" />
+ <TableColumn fx:id="colCapacity" text="Capacity (L)" />
+ <TableColumn fx:id="colPrice" text="Price (€/L)" />
+ </columns>
+ </TableView>
+ </VBox>
</center>
</BorderPane>
\ No newline at end of file
fx:controller="de.diejungsvondertanke.tankstelle.controllers.ResultTabController"
spacing="20">
<padding>
- <Insets top="15" right="15" bottom="15" left="15"/>
+ <Insets top="15" right="15" bottom="15" left="15" />
</padding>
<VBox spacing="10">
<VBox spacing="10">
<Label text="Fuel station selection (multiple):" />
- <ListView fx:id="listFuelStations" prefWidth="220" />
+ <ListView fx:id="listFuelStations" prefWidth="220" multiple="true" />
</VBox>
</HBox>
\ No newline at end of file