Compare commits
	
		
			3 Commits
		
	
	
		
			837b08c4cb
			...
			5a3df459f9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5a3df459f9 | |||
| 1ae75d4891 | |||
| 0704a4a931 | 
| @@ -0,0 +1,34 @@ | |||||||
|  | package name.nathanmcrae.numbersstation; | ||||||
|  |  | ||||||
|  | import java.io.PrintWriter; | ||||||
|  | import java.io.StringWriter; | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.logging.Formatter; | ||||||
|  | import java.util.logging.LogRecord; | ||||||
|  |  | ||||||
|  | public class CustomFormatter extends Formatter { | ||||||
|  |     private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String format(LogRecord record) { | ||||||
|  |         String timestamp = dateFormat.format(new Date(record.getMillis())); | ||||||
|  |         String logLevel = record.getLevel().getName(); | ||||||
|  |         String className = record.getSourceClassName(); | ||||||
|  |         String methodName = record.getSourceMethodName(); | ||||||
|  |         String message = formatMessage(record); | ||||||
|  |  | ||||||
|  |         StringBuilder logMessage = new StringBuilder(); | ||||||
|  |         logMessage.append(String.format("%s\t%s\t%s\t%s\t%s", timestamp, logLevel, className, methodName, message)); | ||||||
|  |  | ||||||
|  |         if (record.getThrown() != null) { | ||||||
|  |             StringWriter sw = new StringWriter(); | ||||||
|  |             PrintWriter pw = new PrintWriter(sw); | ||||||
|  |             record.getThrown().printStackTrace(pw); | ||||||
|  |             logMessage.append("\n\t").append(sw.toString()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         logMessage.append(System.lineSeparator()); | ||||||
|  |         return logMessage.toString(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,21 +1,74 @@ | |||||||
| package name.nathanmcrae.numbersstation; | package name.nathanmcrae.numbersstation; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
|  | import java.nio.file.Paths; | ||||||
|  | import java.util.logging.FileHandler; | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | import java.util.logging.Level; | ||||||
| import javafx.application.Application; | import javafx.application.Application; | ||||||
|  | import javafx.application.Platform; | ||||||
| import javafx.fxml.FXMLLoader; | import javafx.fxml.FXMLLoader; | ||||||
| import javafx.scene.Parent; | import javafx.scene.Parent; | ||||||
| import javafx.scene.Scene; | import javafx.scene.Scene; | ||||||
| import javafx.stage.Stage; | import javafx.stage.Stage; | ||||||
|  |  | ||||||
| public class Main extends Application { | public class Main extends Application { | ||||||
|  |     private static final Logger logger = Logger.getLogger(Main.class.getName()); | ||||||
|  |  | ||||||
|  |     private static Path statePath = null; | ||||||
|  |  | ||||||
|  |     public Path getStatePath() { | ||||||
|  |         if (statePath == null) { | ||||||
|  |             String stateHome = System.getenv("XDG_STATE_HOME"); | ||||||
|  |             if (stateHome == null || stateHome.isEmpty() || !Paths.get(stateHome).isAbsolute()) { | ||||||
|  |                 String userHome = System.getProperty("user.home"); | ||||||
|  |                 statePath = Paths.get(userHome, ".local", "state", "numbers-station"); | ||||||
|  |             } else { | ||||||
|  |                 statePath = Paths.get(stateHome, "numbers-station"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return statePath; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void start(Stage primaryStage) throws Exception { |     public void start(Stage primaryStage) throws Exception { | ||||||
|  |         setupLogger(); | ||||||
|         Parent root = FXMLLoader.load(getClass().getResource("MainView.fxml")); |         Parent root = FXMLLoader.load(getClass().getResource("MainView.fxml")); | ||||||
|         primaryStage.setTitle("Numbers Station"); |         primaryStage.setTitle("Numbers Station"); | ||||||
|         primaryStage.setScene(new Scene(root)); |         primaryStage.setScene(new Scene(root)); | ||||||
|         primaryStage.show(); |         primaryStage.show(); | ||||||
|  |         logger.info("Application started"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void setupLogger() { | ||||||
|  |         try { | ||||||
|  |             Path logFile = getStatePath().resolve("main.log"); | ||||||
|  |  | ||||||
|  |             if (!Files.exists(logFile.getParent())) { | ||||||
|  |                 Files.createDirectories(logFile.getParent()); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             FileHandler fileHandler = new FileHandler(logFile.toString(), true); | ||||||
|  |             fileHandler.setFormatter(new CustomFormatter()); | ||||||
|  |             logger.addHandler(fileHandler); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             System.out.println("Failed to set up logger: " + e.getMessage()); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void main(String[] args) { |     public static void main(String[] args) { | ||||||
|  |         Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { | ||||||
|  |             logger.log(Level.SEVERE, "Unhandled exception caught", throwable); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         Platform.setImplicitExit(false); | ||||||
|  |         Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> { | ||||||
|  |             logger.log(Level.SEVERE, "Unhandled exception in JavaFX application thread", throwable); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|         launch(args); |         launch(args); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ import java.net.URL; | |||||||
| import java.nio.file.Files; | import java.nio.file.Files; | ||||||
| import java.nio.file.Path; | import java.nio.file.Path; | ||||||
| import java.nio.file.Paths; | import java.nio.file.Paths; | ||||||
|  | import java.util.logging.Level; | ||||||
|  | import java.util.logging.Logger; | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| import java.util.ResourceBundle; | import java.util.ResourceBundle; | ||||||
| import javafx.beans.property.SimpleStringProperty; | import javafx.beans.property.SimpleStringProperty; | ||||||
| @@ -29,6 +31,8 @@ import javafx.stage.Modality; | |||||||
| import javafx.stage.Stage; | import javafx.stage.Stage; | ||||||
|  |  | ||||||
| public class MainController implements Initializable { | public class MainController implements Initializable { | ||||||
|  |     private static final Logger logger = Logger.getLogger(Main.class.getName()); | ||||||
|  |  | ||||||
|     private Stage settingsStage; |     private Stage settingsStage; | ||||||
|     private Stage selectStationStage; |     private Stage selectStationStage; | ||||||
|     private MainSettings settings; |     private MainSettings settings; | ||||||
| @@ -75,7 +79,7 @@ public class MainController implements Initializable { | |||||||
|                     updateStationSettings(selectedStation); |                     updateStationSettings(selectedStation); | ||||||
|                 }); |                 }); | ||||||
|             } catch (Exception e) { |             } catch (Exception e) { | ||||||
|                 e.printStackTrace(); |                 logger.log(Level.SEVERE, "Exception while opening settings", e); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             settingsStage.toFront(); |             settingsStage.toFront(); | ||||||
| @@ -83,7 +87,7 @@ public class MainController implements Initializable { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @FXML |     @FXML | ||||||
|     private void handleSelectStationButtonPress() { |     private void handleSelectStationButtonPress() throws Exception { | ||||||
|         if (selectStationStage == null || !selectStationStage.isShowing()) { |         if (selectStationStage == null || !selectStationStage.isShowing()) { | ||||||
|             try { |             try { | ||||||
|                 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("StationSelectionView.fxml")); |                 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("StationSelectionView.fxml")); | ||||||
| @@ -107,7 +111,7 @@ public class MainController implements Initializable { | |||||||
|                     updateStationSettings(newSelectedStation); |                     updateStationSettings(newSelectedStation); | ||||||
|                 }); |                 }); | ||||||
|             } catch (Exception e) { |             } catch (Exception e) { | ||||||
|                 e.printStackTrace(); |                 logger.log(Level.SEVERE, "Exception while selecting station", e); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             selectStationStage.toFront(); |             selectStationStage.toFront(); | ||||||
| @@ -118,12 +122,10 @@ public class MainController implements Initializable { | |||||||
|         XmlMapper xmlMapper = new XmlMapper(); |         XmlMapper xmlMapper = new XmlMapper(); | ||||||
|         xmlMapper.registerModule(new JavaTimeModule()); |         xmlMapper.registerModule(new JavaTimeModule()); | ||||||
|         String userHome = System.getProperty("user.home"); |         String userHome = System.getProperty("user.home"); | ||||||
|         // TODO: XDG |  | ||||||
|         Path directoryPath = Paths.get(userHome, ".numbers-station"); |  | ||||||
|         Path filePath = directoryPath.resolve("settings.xml"); |  | ||||||
|         try { |  | ||||||
|  |  | ||||||
|             // Create the directory if it doesn't exist |         Path filePath = MainSettings.getSettingsFilePath(); | ||||||
|  |         Path directoryPath = filePath.getParent(); | ||||||
|  |         try { | ||||||
|             if (!Files.exists(directoryPath)) { |             if (!Files.exists(directoryPath)) { | ||||||
|                 Files.createDirectories(directoryPath); |                 Files.createDirectories(directoryPath); | ||||||
|             } |             } | ||||||
| @@ -141,9 +143,8 @@ public class MainController implements Initializable { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } catch (IOException e) { |         } catch (IOException e) { | ||||||
|             // Print the contents of filePath |             logger.log(Level.SEVERE, "Failed to load settings from " + filePath.toString(), e); | ||||||
|             System.out.println("File contents: " + Files.readString(filePath)); |             System.out.println("File contents: " + Files.readString(filePath)); | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -218,6 +219,8 @@ public class MainController implements Initializable { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void updateStationSettings(StationSettings newStationSettings) { |     private void updateStationSettings(StationSettings newStationSettings) { | ||||||
|  |         logger.info("Updating station settings: " + newStationSettings.getName()); | ||||||
|  |  | ||||||
|         if (newStationSettings == null) { |         if (newStationSettings == null) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -11,8 +11,11 @@ import java.nio.file.Files; | |||||||
| import java.nio.file.Path; | import java.nio.file.Path; | ||||||
| import java.nio.file.Paths; | import java.nio.file.Paths; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.logging.Logger; | ||||||
|  |  | ||||||
| public class MainSettings { | public class MainSettings { | ||||||
|  |     private static final Logger logger = Logger.getLogger(Main.class.getName()); | ||||||
|  |  | ||||||
|     private int digitsPerGroup; |     private int digitsPerGroup; | ||||||
|     private String username; |     private String username; | ||||||
|     private int refreshInterval; |     private int refreshInterval; | ||||||
| @@ -25,6 +28,21 @@ public class MainSettings { | |||||||
|         stations.add(new StationSettings("Station 1")); |         stations.add(new StationSettings("Station 1")); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static Path getSettingsFilePath() { | ||||||
|  |         String configHome = System.getenv("XDG_CONFIG_HOME"); | ||||||
|  |         Path directoryPath; | ||||||
|  |         Path filePath; | ||||||
|  |  | ||||||
|  |         if (configHome != null && !configHome.isEmpty() && Paths.get(configHome).isAbsolute()) { | ||||||
|  |             directoryPath = Paths.get(configHome, "numbers-station"); | ||||||
|  |         } else { | ||||||
|  |             String userHome = System.getProperty("user.home"); | ||||||
|  |             directoryPath = Paths.get(userHome, ".config", "numbers-station"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return directoryPath.resolve("main-settings.xml"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public ArrayList<StationSettings> getStations() { |     public ArrayList<StationSettings> getStations() { | ||||||
|         return stations; |         return stations; | ||||||
|     } |     } | ||||||
| @@ -58,16 +76,15 @@ public class MainSettings { | |||||||
|         xmlMapper.registerModule(new JavaTimeModule()); |         xmlMapper.registerModule(new JavaTimeModule()); | ||||||
|         xmlMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); |         xmlMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | ||||||
|         try { |         try { | ||||||
|             String userHome = System.getProperty("user.home"); |             Path filePath = getSettingsFilePath(); | ||||||
|             Path directoryPath = Paths.get(userHome, ".numbers-station"); |             Path directoryPath = filePath.getParent(); | ||||||
|             Path filePath = directoryPath.resolve("settings.xml"); |  | ||||||
|  |  | ||||||
|             // Create the directory if it doesn't exist |  | ||||||
|             if (!Files.exists(directoryPath)) { |             if (!Files.exists(directoryPath)) { | ||||||
|                 Files.createDirectories(directoryPath); |                 Files.createDirectories(directoryPath); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             xmlMapper.writeValue(new File(filePath.toString()), this); |             xmlMapper.writeValue(new File(filePath.toString()), this); | ||||||
|  |             logger.info("Settings saved to " + filePath.toString()); | ||||||
|         } catch (IOException e) { |         } catch (IOException e) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -63,6 +63,13 @@ public class StationSelectionController { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @FXML | ||||||
|  |     private void handleCancelButtonPress(Event event) { | ||||||
|  |         Node node = (Node) event.getSource(); | ||||||
|  |         Stage stage = (Stage) node.getScene().getWindow(); | ||||||
|  |         stage.close(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @FXML |     @FXML | ||||||
|     private void handleRemoveButtonPress(ActionEvent event) { |     private void handleRemoveButtonPress(ActionEvent event) { | ||||||
|         int selectedIndex = stationListView.getSelectionModel().getSelectedIndex(); |         int selectedIndex = stationListView.getSelectionModel().getSelectedIndex(); | ||||||
|   | |||||||
| @@ -13,10 +13,10 @@ | |||||||
|             <Font size="20.0" /> |             <Font size="20.0" /> | ||||||
|          </font> |          </font> | ||||||
|       </Label> |       </Label> | ||||||
|       <Button layoutX="358.0" layoutY="17.0" mnemonicParsing="false" text="+" AnchorPane.rightAnchor="54.5" AnchorPane.topAnchor="17.0" onAction="#handleAddButtonPress"/> |       <Button layoutX="358.0" layoutY="17.0" mnemonicParsing="false" onAction="#handleAddButtonPress" text="+" AnchorPane.rightAnchor="54.5" AnchorPane.topAnchor="17.0" /> | ||||||
|       <Button layoutX="391.0" layoutY="17.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="25.0" text="-" AnchorPane.rightAnchor="21.0" AnchorPane.topAnchor="17.0" onAction="#handleRemoveButtonPress"/> |       <Button layoutX="391.0" layoutY="17.0" mnemonicParsing="false" onAction="#handleRemoveButtonPress" prefHeight="25.0" prefWidth="25.0" text="-" AnchorPane.rightAnchor="21.0" AnchorPane.topAnchor="17.0" /> | ||||||
|       <ListView fx:id="stationListView" layoutX="14.0" layoutY="57.0" prefHeight="301.0" prefWidth="409.0" AnchorPane.bottomAnchor="42.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="57.0" /> |       <ListView fx:id="stationListView" layoutX="14.0" layoutY="57.0" prefHeight="301.0" prefWidth="409.0" AnchorPane.bottomAnchor="42.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="57.0" /> | ||||||
|       <Button layoutX="313.0" layoutY="365.0" mnemonicParsing="false" onMousePressed="#handleSelectButtonPress" text="Select" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="76.5" /> |       <Button layoutX="313.0" layoutY="365.0" mnemonicParsing="false" onMousePressed="#handleSelectButtonPress" text="Select" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="76.5" /> | ||||||
|       <Button layoutX="370.0" layoutY="365.0" mnemonicParsing="false" text="Cancel" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="15.5" /> |       <Button layoutX="370.0" layoutY="365.0" mnemonicParsing="false" onMousePressed="#handleCancelButtonPress" text="Cancel" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="15.5" /> | ||||||
|    </children> |    </children> | ||||||
| </AnchorPane> | </AnchorPane> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user