From 9a8c0287e76f1ac7f6ece533d99cb0c8986e5246 Mon Sep 17 00:00:00 2001 From: Lichtblitz Date: Sun, 5 Nov 2023 03:28:22 +0100 Subject: [PATCH] Some code refactoring/cleanup and styling of the ability score table --- .../java/pcgen/gui2/tabs/SummaryInfoTab.java | 24 +---- .../gui3/tabs/summary/AbilityScores.java | 20 +--- .../gui3/tabs/summary/AbilityScoresModel.java | 42 +++++--- .../gui3/tabs/summary/EditableStatCell.java | 12 +++ .../pcgen/gui3/utilty/BoundController.java | 3 + .../gui3/utilty/CustomTableCellFactory.java | 35 +++--- .../java/pcgen/gui3/utilty/JavaFXLoader.java | 32 ++++++ .../pcgen/gui3/tabs/summary/AbilityScores.css | 7 ++ .../gui3/tabs/summary/AbilityScores.fxml | 101 ++++++------------ .../gui3/tabs/summary/EditableStatCell.css | 4 + .../gui3/tabs/summary/EditableStatCell.fxml | 12 ++- 11 files changed, 156 insertions(+), 136 deletions(-) create mode 100644 code/src/java/pcgen/gui3/utilty/JavaFXLoader.java create mode 100644 code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.css create mode 100644 code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.css diff --git a/code/src/java/pcgen/gui2/tabs/SummaryInfoTab.java b/code/src/java/pcgen/gui2/tabs/SummaryInfoTab.java index f9fddcfd4c5..1004f0afc7f 100644 --- a/code/src/java/pcgen/gui2/tabs/SummaryInfoTab.java +++ b/code/src/java/pcgen/gui2/tabs/SummaryInfoTab.java @@ -27,11 +27,8 @@ import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; -import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; -import java.io.IOException; -import java.net.URL; import java.text.NumberFormat; import java.util.Arrays; import java.util.Collection; @@ -107,12 +104,12 @@ import pcgen.gui3.tabs.summary.AbilityScores; import pcgen.gui3.tabs.summary.AbilityScoresModel; import pcgen.gui3.utilty.ColorUtilty; +import pcgen.gui3.utilty.JavaFXLoader; import pcgen.system.LanguageBundle; import pcgen.util.enumeration.Tab; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; -import javafx.fxml.FXMLLoader; import javafx.scene.Scene; /** @@ -296,26 +293,15 @@ private void initTodoPanel(JPanel panel) private void initMiddlePanel(JFXPanel middlePanel) { - URL resource = AbilityScores.class.getResource(AbilityScores.class.getSimpleName() + ".fxml"); - FXMLLoader loader = new FXMLLoader(resource, LanguageBundle.getBundle()); + JavaFXLoader.Components components = JavaFXLoader.load(AbilityScores.class); - Scene scene = null; - try - { - scene = loader.load(); - abilityScores = loader.getController(); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - - middlePanel.setScene(scene); + abilityScores = components.controller(); + middlePanel.setScene(components.fxml()); StatTableModel.initializeTable(statsTable); - middlePanel.setLayout(new GridLayout(2, 1)); + //middlePanel.setLayout(new GridLayout(2, 1)); JPanel statsPanel = new JPanel(); setPanelTitle(statsPanel, LanguageBundle.getString("in_sumAbilityScores")); //$NON-NLS-1$ diff --git a/code/src/java/pcgen/gui3/tabs/summary/AbilityScores.java b/code/src/java/pcgen/gui3/tabs/summary/AbilityScores.java index 7fcc3ec4691..2c2b228d0a2 100644 --- a/code/src/java/pcgen/gui3/tabs/summary/AbilityScores.java +++ b/code/src/java/pcgen/gui3/tabs/summary/AbilityScores.java @@ -7,10 +7,10 @@ import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableIntegerValue; +import javafx.beans.value.ObservableStringValue; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.fxml.FXML; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.cell.TextFieldTableCell; @@ -23,17 +23,7 @@ public class AbilityScores private final ObjectProperty abilityScoresModelProperty = new SimpleObjectProperty<>(); private final ObservableList pcStatList = - FXCollections.observableArrayList();/*statValues-> new Observable[]{ - statValues.getLabel(), - statValues.getTotal(), - statValues.getMod(), - statValues.getBase(), - statValues.getRaceBonus(), - statValues.getOtherBonus() - });*/ - - @FXML - public TableColumn editableColumn; + FXCollections.observableArrayList(); public AbilityScores() { @@ -62,7 +52,7 @@ public Callback cellDataFeatures.getValue().getTotal(); } - public Callback, ObservableIntegerValue> getModFactory() + public Callback, ObservableStringValue> getModFactory() { return cellDataFeatures -> cellDataFeatures.getValue().getMod(); } @@ -82,12 +72,12 @@ public Callback, TableCell, ObservableIntegerValue> getRaceBonusFactory() + public Callback, ObservableStringValue> getRaceBonusFactory() { return cellDataFeatures -> cellDataFeatures.getValue().getRaceBonus(); } - public Callback, ObservableIntegerValue> getOtherBonusFactory() + public Callback, ObservableStringValue> getOtherBonusFactory() { return cellDataFeatures -> cellDataFeatures.getValue().getOtherBonus(); } diff --git a/code/src/java/pcgen/gui3/tabs/summary/AbilityScoresModel.java b/code/src/java/pcgen/gui3/tabs/summary/AbilityScoresModel.java index 29c21ed933d..4cb4fc9c350 100644 --- a/code/src/java/pcgen/gui3/tabs/summary/AbilityScoresModel.java +++ b/code/src/java/pcgen/gui3/tabs/summary/AbilityScoresModel.java @@ -13,6 +13,7 @@ import pcgen.facade.core.CharacterFacade; import pcgen.facade.util.event.ReferenceEvent; import pcgen.facade.util.event.ReferenceListener; +import pcgen.gui2.util.PrettyIntegerFormat; import javafx.application.Platform; import javafx.beans.property.IntegerProperty; @@ -36,11 +37,11 @@ public static class StatValues { @Builder private StatValues(@NonNull String label, - int mod, + @NonNull String mod, int base, - int raceBonus, + @NonNull String raceBonus, @NonNull String total, - int otherBonus, + @NonNull String otherBonus, @NonNull ChangeListener changeListener) { this.label.set(label); @@ -54,11 +55,11 @@ private StatValues(@NonNull String label, } StringProperty label = new SimpleStringProperty(); - IntegerProperty mod = new SimpleIntegerProperty(); + StringProperty mod = new SimpleStringProperty(); IntegerProperty base = new SimpleIntegerProperty(); - IntegerProperty raceBonus = new SimpleIntegerProperty(); + StringProperty raceBonus = new SimpleStringProperty(); StringProperty total = new SimpleStringProperty(); - IntegerProperty otherBonus = new SimpleIntegerProperty(); + StringProperty otherBonus = new SimpleStringProperty(); @EqualsAndHashCode.Include private String getLabelValue() @@ -67,7 +68,7 @@ private String getLabelValue() } @EqualsAndHashCode.Include - private int getModValue() + private String getModValue() { return mod.getValue(); } @@ -79,7 +80,7 @@ private int getBaseValue() } @EqualsAndHashCode.Include - private int getRaceBonusValue() + private String getRaceBonusValue() { return raceBonus.getValue(); } @@ -91,7 +92,7 @@ private String getTotalValue() } @EqualsAndHashCode.Include - private int getOtherBonusValue() + private String getOtherBonusValue() { return otherBonus.getValue(); } @@ -162,11 +163,11 @@ private static StatValues createObjectProperty(PCStat stat, CharacterFacade char { return StatValues.builder() .label(stat.getDisplayName()) - .mod(character.getModTotal(stat)) + .mod(formatModValue(character.getModTotal(stat))) .base(character.getScoreBase(stat)) - .raceBonus(character.getScoreRaceBonus(stat)) + .raceBonus(formatModValue(character.getScoreRaceBonus(stat))) .total(character.getScoreTotalString(stat)) - .otherBonus(character.getScoreOtherBonus(stat)) + .otherBonus(formatModValue(character.getScoreOtherBonus(stat))) .changeListener((observable, oldValue, newValue) -> character.setScoreBase(stat, newValue.intValue())) .build(); @@ -176,10 +177,21 @@ private static StatValues createObjectProperty(PCStat stat, CharacterFacade char private static void overrideObjectProperty(PCStat stat, CharacterFacade character, StatValues values) { values.getLabel().setValue(stat.getDisplayName()); - values.getMod().setValue(character.getModTotal(stat)); + values.getMod().setValue(formatModValue(character.getModTotal(stat))); values.getBase().setValue(character.getScoreBase(stat)); - values.getRaceBonus().setValue(character.getScoreRaceBonus(stat)); + values.getRaceBonus().setValue(formatModValue(character.getScoreRaceBonus(stat))); values.getTotal().setValue(character.getScoreTotalString(stat)); - values.getOtherBonus().setValue(character.getScoreOtherBonus(stat)); + values.getOtherBonus().setValue(formatModValue(character.getScoreOtherBonus(stat))); + } + + + private static String formatModValue(int value) + { + if (value == 0) + { + // let's use a pretty em dash instead of hyphen/minus. + return "\u2014"; + } + return PrettyIntegerFormat.getFormat().format(value); } } diff --git a/code/src/java/pcgen/gui3/tabs/summary/EditableStatCell.java b/code/src/java/pcgen/gui3/tabs/summary/EditableStatCell.java index 013340a9534..8a160b36317 100644 --- a/code/src/java/pcgen/gui3/tabs/summary/EditableStatCell.java +++ b/code/src/java/pcgen/gui3/tabs/summary/EditableStatCell.java @@ -3,7 +3,11 @@ import lombok.Getter; import pcgen.gui3.utilty.BoundController; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.Property; +import javafx.beans.property.ReadOnlyBooleanProperty; +import javafx.beans.property.ReadOnlyBooleanWrapper; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.fxml.FXML; import javafx.scene.control.Spinner; @@ -14,6 +18,7 @@ public class EditableStatCell implements BoundController> { private final Property externalProperty = new SimpleObjectProperty<>(); + private final BooleanProperty isEditingProperty = new SimpleBooleanProperty(false); @FXML public Spinner spinner; @@ -23,6 +28,7 @@ public void initialize(){ if (oldValue && ! newValue){ externalProperty.setValue(spinner.getValueFactory().getValue()); } + isEditingProperty.set(newValue); }); externalProperty.subscribe(value -> spinner.getValueFactory().setValue(value)); @@ -34,6 +40,12 @@ public void bind(Property property) externalProperty.bindBidirectional(property); // don't bind the spinner directly; only update when we lose focus } + @Override + public ReadOnlyBooleanProperty isEditing() + { + return ReadOnlyBooleanWrapper.readOnlyBooleanProperty(isEditingProperty); + } + public void onKeyReleased(KeyEvent keyEvent) { if (KeyCode.ENTER.equals(keyEvent.getCode())){ diff --git a/code/src/java/pcgen/gui3/utilty/BoundController.java b/code/src/java/pcgen/gui3/utilty/BoundController.java index d04ff5e47ff..d126e9b546c 100644 --- a/code/src/java/pcgen/gui3/utilty/BoundController.java +++ b/code/src/java/pcgen/gui3/utilty/BoundController.java @@ -1,8 +1,11 @@ package pcgen.gui3.utilty; import javafx.beans.property.Property; +import javafx.beans.property.ReadOnlyBooleanProperty; public interface BoundController> { void bind(T property); + + ReadOnlyBooleanProperty isEditing(); } diff --git a/code/src/java/pcgen/gui3/utilty/CustomTableCellFactory.java b/code/src/java/pcgen/gui3/utilty/CustomTableCellFactory.java index bb16b0511aa..7b4dd2b51aa 100644 --- a/code/src/java/pcgen/gui3/utilty/CustomTableCellFactory.java +++ b/code/src/java/pcgen/gui3/utilty/CustomTableCellFactory.java @@ -1,17 +1,13 @@ package pcgen.gui3.utilty; -import java.io.IOException; -import java.net.URL; import java.util.Objects; import lombok.AccessLevel; import lombok.Builder; import lombok.NonNull; -import pcgen.system.LanguageBundle; import javafx.application.Platform; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; -import javafx.fxml.FXMLLoader; import javafx.scene.Node; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; @@ -20,15 +16,15 @@ @Builder(access = AccessLevel.PROTECTED) public class CustomTableCellFactory extends TableCell { - private final Class fxmlControllerClass; + private final Class>> fxmlControllerClass; private final Property valueProperty = new SimpleObjectProperty<>(); private Node graphic; private boolean isExternalUpdate; public static Callback, TableCell> - forTableColumn(@NonNull Class>> fxmlControllerClass) + forTableColumn(@NonNull Class>> fxmlControllerClass) { - return list -> CustomTableCellFactory.builder() + return column -> CustomTableCellFactory.builder() .fxmlControllerClass(fxmlControllerClass) .build(); } @@ -39,11 +35,9 @@ protected void initialize() { return; } - try - { - URL resource = fxmlControllerClass.getResource(fxmlControllerClass.getSimpleName() + ".fxml"); - FXMLLoader loader = new FXMLLoader(resource, LanguageBundle.getBundle()); - graphic = loader.load(); + JavaFXLoader.Components>> loaded = JavaFXLoader.load(fxmlControllerClass); + graphic = loaded.fxml(); + valueProperty.addListener((observable, oldValue, newValue) -> { if (isExternalUpdate || Objects.equals(oldValue, newValue)) { @@ -55,12 +49,17 @@ protected void initialize() requestFocus(); }); }); - loader.>>getController().bind(valueProperty); - } - catch (IOException e) - { - throw new RuntimeException(e); - } + loaded.controller().bind(valueProperty); + loaded.controller().isEditing().subscribe(isEditing -> { + if (isEditing) + { + getTableView().getSelectionModel().clearAndSelect(getTableRow().getIndex(), getTableColumn()); + } + else + { + getTableView().getSelectionModel().clearSelection(); + } + }); } @Override diff --git a/code/src/java/pcgen/gui3/utilty/JavaFXLoader.java b/code/src/java/pcgen/gui3/utilty/JavaFXLoader.java new file mode 100644 index 00000000000..5aeaf6c5fe6 --- /dev/null +++ b/code/src/java/pcgen/gui3/utilty/JavaFXLoader.java @@ -0,0 +1,32 @@ +package pcgen.gui3.utilty; + +import java.io.IOException; +import java.net.URL; +import lombok.NonNull; +import pcgen.system.LanguageBundle; + +import javafx.fxml.FXMLLoader; + +public class JavaFXLoader +{ + + public record Components(T fxml, U controller) + { + } + + public static Components load(@NonNull Class controllerClass) + { + URL resource = controllerClass.getResource(controllerClass.getSimpleName() + ".fxml"); + + FXMLLoader loader = new FXMLLoader(resource, LanguageBundle.getBundle()); + + try + { + return new Components<>(loader.load(), loader.getController()); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } +} diff --git a/code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.css b/code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.css new file mode 100644 index 00000000000..770bda9ae1d --- /dev/null +++ b/code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.css @@ -0,0 +1,7 @@ +.titled-pane { + -fx-alignment: center; +} + +.table-column { + -fx-alignment: center; +} \ No newline at end of file diff --git a/code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.fxml b/code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.fxml index 6b31b189129..340a86459b2 100644 --- a/code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.fxml +++ b/code/src/resources/pcgen/gui3/tabs/summary/AbilityScores.fxml @@ -1,88 +1,53 @@ + - - - - + - - - - + + + + + + + - + - + - + - + - + - + - - - - - - - - Dies ist ein Test\nUnd hier folgt ein weiterer\nund was ist das jetzt? - - - Dies ist ein Test\nUnd hier folgt ein weiterer\nund was ist das jetzt? - - - - - - - - - - - - + + + Dies ist ein Test\nUnd hier folgt ein weiterer\nund was ist das jetzt? + + + Dies ist ein Test\nUnd hier folgt ein weiterer\nund was ist das jetzt? + + + + diff --git a/code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.css b/code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.css new file mode 100644 index 00000000000..5f30c2de7d7 --- /dev/null +++ b/code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.css @@ -0,0 +1,4 @@ +.spinner .text-field { + -fx-alignment: center; + -fx-font-weight: bolder; +} \ No newline at end of file diff --git a/code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.fxml b/code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.fxml index 4e8b0ee9f2a..de60b945440 100644 --- a/code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.fxml +++ b/code/src/resources/pcgen/gui3/tabs/summary/EditableStatCell.fxml @@ -1,10 +1,20 @@ + - + + + +