diff options
| author | sowgro <tpoke.ferrari@gmail.com> | 2024-09-02 02:30:39 -0400 | 
|---|---|---|
| committer | sowgro <tpoke.ferrari@gmail.com> | 2024-09-02 02:30:39 -0400 | 
| commit | d685d397573c43194fede9b2bbd3aee76d2cd9f8 (patch) | |
| tree | 8f26bc510701955042be70ada44b81b5f3b15997 /src/main | |
| parent | ef46303949173cd67cf00a4f40d16f1375ed2250 (diff) | |
| download | NPEhero-d685d397573c43194fede9b2bbd3aee76d2cd9f8.tar.gz NPEhero-d685d397573c43194fede9b2bbd3aee76d2cd9f8.tar.bz2 NPEhero-d685d397573c43194fede9b2bbd3aee76d2cd9f8.zip | |
Redesign editors
Diffstat (limited to 'src/main')
6 files changed, 256 insertions, 128 deletions
| diff --git a/src/main/java/net/sowgro/npehero/editor/DiffEditor.java b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java index 9a4365d..75e687a 100755 --- a/src/main/java/net/sowgro/npehero/editor/DiffEditor.java +++ b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java @@ -1,6 +1,7 @@  package net.sowgro.npehero.editor;  import javafx.beans.binding.DoubleBinding; +import javafx.geometry.Insets;  import javafx.geometry.Pos;  import javafx.scene.control.*;  import javafx.scene.layout.HBox; @@ -18,6 +19,7 @@ import java.io.IOException;  public class DiffEditor extends Page  { +    private final TextField titleEntry;      Difficulty diff;      ScrollPane scroll; @@ -29,12 +31,45 @@ public class DiffEditor extends Page          this.diff = diff;          this.prev = prev; +        Label optionsLabel = new Label("Options"); +          Label folderNameLabel = new Label("Folder name");          TextField folderName = new TextField(diff.thisDir.getName());          folderName.setDisable(true);          Label titleLabel = new Label("Title"); -        TextField title = new TextField(diff.title); +        titleEntry = new TextField(diff.title); + +        Label scoresLabel = new Label("Scores"); +        Button clearScores = new Button("Clear leaderboard"); +        clearScores.setOnAction(_ -> { +            Sound.playSfx(Sound.FORWARD); +            diff.leaderboard.entries.clear(); +            try { +                diff.leaderboard.save(); +            } catch (IOException e) { +                Driver.setMenu(new ErrorDisplay("Failed to clear the leaderboard:\n"+e, this)); +            } +        }); + +        Label playLabel = new Label("Play"); +        Button playLevel = new Button("Play level"); +        playLevel.setOnAction(_ -> { +            Sound.playSfx(Sound.FORWARD); +            if (diff.isValid() && diff.level.isValid()) { +                Driver.setMenu(new LevelSurround(diff, this)); +            } +            else { +                Driver.setMenu(new ErrorDisplay("This Level is not valid!\nCheck that all required fields\nare populated.", this)); +            } +        }); + +        VBox options = new VBox(folderNameLabel, folderName, titleLabel, titleEntry, scoresLabel, clearScores, playLabel, playLevel); +        options.setSpacing(10); +//        options.getStyleClass().add("box"); +        options.setPadding(new Insets(5)); + +        ScrollPane optionsScroll = new ScrollPane(options);          Button editNotes = new Button("Edit notes");          editNotes.setOnAction(_ -> { @@ -64,43 +99,6 @@ public class DiffEditor extends Page              );          }); -        Label scoresLable = new Label("Scores"); -        Button editScores = new Button("Clear leaderboard"); -        editScores.setOnAction(_ -> { -            Sound.playSfx(Sound.FORWARD); -            diff.leaderboard.entries.clear(); -            try { -                diff.leaderboard.save(); -            } catch (IOException e) { -                Driver.setMenu(new ErrorDisplay("Failed to clear the leaderboard:\n"+e, this)); -            } -        }); - -        Button playLevel = new Button("Play level"); -        playLevel.setOnAction(_ -> { -            Sound.playSfx(Sound.FORWARD); -            if (diff.isValid() && diff.level.isValid()) { -                Driver.setMenu(new LevelSurround(diff, this)); -            } -            else { -                Driver.setMenu(new ErrorDisplay("This Level is not valid!\nCheck that all required fields\nare populated.", this)); -            } -        }); - -        Button save = new Button("Save"); -        save.setOnAction(_ -> { //assigns text fields to values -            Sound.playSfx(Sound.FORWARD); -            diff.title = title.getText(); -//            diff.bpm = Double.parseDouble(bpm.getText()); -//            diff.numBeats = Integer.parseInt(numBeats.getText()); -            try { -                diff.writeMetadata(); -            } catch (IOException e) { -                //TODO -                throw new RuntimeException(e); -            } -        }); -          HBox scrollContent = new HBox();          scroll = new ScrollPane(scrollContent);          scroll.setFitToWidth(true); @@ -136,12 +134,21 @@ public class DiffEditor extends Page          notePreview.setSpacing(10);          VBox left = new VBox(); -        left.getChildren().addAll(folderNameLabel,folderName,titleLabel,title,scoresLable,editScores,playLevel); -        left.setSpacing(10); +        left.getChildren().addAll(/*optionsLabel, */optionsScroll); +        options.setSpacing(10); +        optionsScroll.setPrefWidth(500); +        optionsScroll.getStyleClass().remove("scroll-pane"); +        optionsScroll.getStyleClass().add("box"); +        optionsScroll.setFitToWidth(true); +        optionsScroll.setPadding(new Insets(5)); +//        optionsft.setPrefHeight();          HBox main = new HBox();          main.getChildren().addAll(left, notePreview); -        main.setSpacing(30); +        main.setSpacing(10); +        main.prefHeightProperty().bind(content.heightProperty().multiply(0.75)); +        main.maxWidthProperty().bind(content.widthProperty().multiply(0.95)); +        optionsScroll.prefHeightProperty().bind(main.heightProperty());          Button exit = new Button();          exit.setText("Back"); @@ -150,7 +157,7 @@ public class DiffEditor extends Page              Driver.setMenu(prev);          }); -        HBox bottom = new HBox(exit,save); +        HBox bottom = new HBox(exit);          bottom.setSpacing(10);          bottom.setAlignment(Pos.CENTER); @@ -168,6 +175,16 @@ public class DiffEditor extends Page          return content;      } +    @Override +    public void onLeave() { +        diff.title = titleEntry.getText(); +        try { +            diff.writeMetadata(); +        } catch (IOException e) { +            e.printStackTrace(); //TODO +        } +    } +      // Duplicates of NotesEditor2 methods, should be made generic and combined      private Block drawBlock(Note n) {          Color color = diff.level.colors[n.lane]; diff --git a/src/main/java/net/sowgro/npehero/editor/DiffList.java b/src/main/java/net/sowgro/npehero/editor/DiffList.java index acda994..45204ed 100755 --- a/src/main/java/net/sowgro/npehero/editor/DiffList.java +++ b/src/main/java/net/sowgro/npehero/editor/DiffList.java @@ -59,7 +59,6 @@ public class DiffList extends Page          });          diffs.setPrefWidth(400); -        diffs.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.67));          error = new Label();          errorBox = new HBox(error); @@ -150,6 +149,8 @@ public class DiffList extends Page          HBox main = new HBox();          main.getChildren().addAll(new VBox(diffs, errorBox),buttons);          main.setSpacing(10); +        main.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.67)); +        diffs.prefHeightProperty().bind(main.heightProperty());          Button exit = new Button();          exit.setText("Back"); diff --git a/src/main/java/net/sowgro/npehero/editor/LevelEditor.java b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java index 8e49180..a39911e 100755 --- a/src/main/java/net/sowgro/npehero/editor/LevelEditor.java +++ b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java @@ -4,10 +4,10 @@ import java.io.File;  import java.io.IOException;  import javafx.beans.property.ReadOnlyStringWrapper; +import javafx.geometry.Insets;  import javafx.geometry.Pos;  import javafx.scene.control.*;  import javafx.scene.layout.*; -import javafx.scene.text.Text;  import javafx.stage.FileChooser;  import javafx.stage.FileChooser.ExtensionFilter;  import net.sowgro.npehero.Driver; @@ -17,84 +17,146 @@ import net.sowgro.npehero.main.*;  public class LevelEditor extends Page  { +      private final ValidIndicator songValid = new ValidIndicator();      private final ValidIndicator diffsInvalid = new ValidIndicator(); +    private final TextField titleEntry; +    private final TextField artistEntry; +    private final TextField descEntry; +    private final ColorPicker[] colorsPickers; +    private final TableView<Difficulty> diffList;      Level level;      private HBox content = new HBox(); -    private File selectedSong = null; -    private File selectedPreview = null; -    private File selectedBackground = null; -      public LevelEditor(Level level, Page prev)      {          this.level = level; -        Text folderNameLabel = new Text("Folder name"); +        Label folderNameLabel = new Label("Folder name");          TextField folderName = new TextField();          if (level.dir != null) {              folderName.setText(level.dir.getName());              folderName.setDisable(true);          } -        Text titleLabel = new Text("Title"); -        TextField title = new TextField(level.title); - -        Text artistLabel = new Text("Artist"); -        TextField artist = new TextField(level.artist); +        Label titleLabel = new Label("Title"); +        titleEntry = new TextField(level.title); -        Text descLabel = new Text("Description"); -        TextField desc = new TextField(level.desc); +        Label artistLabel = new Label("Artist"); +        artistEntry = new TextField(level.artist); -        Text colorsLabel = new Text("Colors"); +        Label descLabel = new Label("Description"); +        descEntry = new TextField(level.desc); -        ColorPicker[] colorsPickers = new ColorPicker[] { +        Label colorsLabel = new Label("Colors"); +        colorsPickers = new ColorPicker[] {                  new ColorPicker(level.colors[0]),                  new ColorPicker(level.colors[1]),                  new ColorPicker(level.colors[2]),                  new ColorPicker(level.colors[3]),                  new ColorPicker(level.colors[4])          }; -          for (ColorPicker cp : colorsPickers) {              cp.getStyleClass().add("button"); +            cp.setMinHeight(60); +            cp.setMinWidth(60);          }          HBox colorPickerBox = new HBox();          colorPickerBox.getChildren().addAll(colorsPickers); +        colorPickerBox.setSpacing(10); -        HBox filesLabel = new HBox(new Text("Files"), songValid); - +        Label backgroundLabel = new Label("Background Image");          FileChooser backgroundChooser = new FileChooser(); -        backgroundChooser.getExtensionFilters().add(new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif")); -        Button backgroundButton = new Button("Background Image"); -        backgroundButton.setOnAction(_ -> { +        backgroundChooser.getExtensionFilters().add(new ExtensionFilter("Image Files (*.png, *.jpg, *.gif)", "*.png", "*.jpg", "*.gif")); +        Button backgroundImport = new Button("Import"); +        Button backgroundRemove = new Button("Remove"); +        backgroundImport.setOnAction(_ -> { +            Sound.playSfx(Sound.FORWARD); +            var f = backgroundChooser.showOpenDialog(Driver.primaryStage); +            if (f == null) { +                return; +            } +            try { +                level.addFile(f, Level.BACKGROUND_FILE); +            } catch (IOException e) { +                // TODO +                e.printStackTrace(); +            } +            backgroundRemove.setDisable(level.background == null); +        }); +        backgroundRemove.setOnAction(_ -> {              Sound.playSfx(Sound.FORWARD); -            selectedBackground = backgroundChooser.showOpenDialog(Driver.primaryStage); +            try { +                level.removeFile(Level.BACKGROUND_FILE); +            } catch (IOException e) { +                // TODO +                e.printStackTrace(); +            } +            backgroundRemove.setDisable(level.background == null);          }); +        backgroundRemove.setDisable(level.background == null); +        Label previewLabel = new Label("Preview Image");          FileChooser previewChooser = new FileChooser(); -        previewChooser.getExtensionFilters().add(new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif")); -        Button previewButton = new Button("Preview Image"); -        previewButton.setOnAction(_ -> { +        previewChooser.getExtensionFilters().add(new ExtensionFilter("Image Files (*.png, *.jpg, *.gif)", "*.png", "*.jpg", "*.gif")); +        Button previewImport = new Button("Import"); +        Button previewRemove = new Button("Remove"); +        previewImport.setOnAction(_ -> { +            Sound.playSfx(Sound.FORWARD); +            var f = previewChooser.showOpenDialog(Driver.primaryStage); +            if (f == null) { +                return; +            } +            try { +                level.addFile(f, Level.PREVIEW_FILE); +            } catch (IOException e) { +                e.printStackTrace(); // TODO +            } +            previewRemove.setDisable(level.preview == null); +        }); +        previewRemove.setOnAction(_ -> {              Sound.playSfx(Sound.FORWARD); -            selectedPreview = previewChooser.showOpenDialog(Driver.primaryStage); +            try { +                level.removeFile(Level.PREVIEW_FILE); +            } catch (IOException e) { +                e.printStackTrace(); // TODO +            } +            previewRemove.setDisable(level.preview == null);          }); +        previewRemove.setDisable(level.preview == null); +        HBox songLabel = new HBox(new Label("Song File"), songValid);          FileChooser songChooser = new FileChooser(); -        songChooser.getExtensionFilters().add(new ExtensionFilter("Audio Files", "*.wav", "*.mp3", "*.aac")); -        Button songButton = new Button("Song file"); -        songButton.setOnAction(_ -> { +        songChooser.getExtensionFilters().add(new ExtensionFilter("Audio Files (*.wav, *.mp3, *.aac)", "*.wav", "*.mp3", "*.aac")); +        Button songImport = new Button("Import"); +        Button songRemove = new Button("Remove"); +        songImport.setOnAction(_ -> {              Sound.playSfx(Sound.FORWARD); -            selectedSong = songChooser.showOpenDialog(Driver.primaryStage); +            var f = songChooser.showOpenDialog(Driver.primaryStage); +            try { +                level.addFile(f, Level.SONG_FILE); +            } catch (IOException e) { +                e.printStackTrace(); // TODO +            } +            songRemove.setDisable(level.song == null);          }); +        songRemove.setOnAction(_ -> { +            Sound.playSfx(Sound.FORWARD); +            try { +                level.removeFile(Level.SONG_FILE); +            } catch (IOException e) { +                e.printStackTrace(); // TODO +            } +            songRemove.setDisable(level.song == null); +        }); +        songRemove.setDisable(level.song == null); - -        HBox diffLabel = new HBox(new Text("Difficulties"), diffsInvalid); +        HBox diffLabel = new HBox(new Label("Difficulties"), diffsInvalid);          diffLabel.setSpacing(5); -        TableView<Difficulty> diffList = new TableView<>(); +        diffList = new TableView<>();          TableColumn<Difficulty,String> diffCol = new TableColumn<>("Difficulty");          TableColumn<Difficulty,String> validCol = new TableColumn<>("Valid?"); @@ -109,7 +171,7 @@ public class LevelEditor extends Page          validCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().isValid() ? "Yes" : "No"));          diffList.setItems(level.difficulties.list); -        diffList.setRowFactory( _ -> { +        diffList.setRowFactory(_ -> {              TableRow<Difficulty> row = new TableRow<>();              row.setOnMouseClicked(event -> {                  if (event.getClickCount() == 2 && (! row.isEmpty()) ) { @@ -128,54 +190,43 @@ public class LevelEditor extends Page          diffList.setSelectionModel(null); -        Button save = new Button("Save"); -        save.setOnAction(e -> { //assigns fields to values -            Sound.playSfx(Sound.FORWARD); -            level.title = title.getText(); -            level.artist = artist.getText(); -            level.desc = desc.getText(); -            level.colors[0] = colorsPickers[0].getValue(); -            level.colors[1] = colorsPickers[1].getValue(); -            level.colors[2] = colorsPickers[2].getValue(); -            level.colors[3] = colorsPickers[3].getValue(); -            level.colors[4] = colorsPickers[4].getValue(); -            try { -                if (selectedBackground != null && selectedBackground.exists()) { -                    level.addFile(selectedBackground, "background"); -                } -                if (selectedPreview != null && selectedPreview.exists()) { -                    level.addFile(selectedPreview, "preview"); -                } -                if (selectedSong != null) { -                    level.addFile(selectedSong, "song"); -                } -            } catch (Exception ex) { -                // TODO -            } -            try { -                level.writeMetadata(); -            } catch (IOException ex) { -                // TODO -            } -            validate(); -        }); +        var b1 = new HBox(songImport, songRemove); +        b1.setSpacing(10); +        var b2 = new HBox(previewImport, previewRemove); +        b2.setSpacing(10); +        var b3 = new HBox(backgroundImport, backgroundRemove); +        b3.setSpacing(10); +        VBox optionsBox = new VBox(folderNameLabel, folderName, titleLabel, titleEntry, artistLabel, artistEntry, descLabel, descEntry, +                songLabel, b1, previewLabel, b2, backgroundLabel, b3, colorsLabel, colorPickerBox/*, new Separator(Orientation.HORIZONTAL), save*/); +        optionsBox.setSpacing(10); +//        left.setPrefWidth(300); +        optionsBox.setPadding(new Insets(5)); + +        ScrollPane leftScroll = new ScrollPane(optionsBox); +        leftScroll.getStyleClass().remove("scroll-pane"); +        leftScroll.getStyleClass().add("box"); +        leftScroll.setPadding(new Insets(5)); +        leftScroll.setFitToWidth(true); +        leftScroll.setPrefWidth(500); + +//        VBox center = new VBox(); +//        center.setSpacing(10); +//        center.setPrefWidth(300); + +        VBox right = new VBox(diffLabel, diffList,newDiffs); +        right.setSpacing(10); +//        right.setPrefWidth(325); -        VBox left = new VBox(filesLabel, songButton, previewButton, backgroundButton, colorsLabel, colorPickerBox); +        Label optionsLable = new Label("Options"); +        VBox left = new VBox(/*optionsLable, */leftScroll);          left.setSpacing(10); -        left.setPrefWidth(300); - -        VBox center = new VBox(folderNameLabel,folderName,titleLabel,title,artistLabel,artist,descLabel,desc); -        center.setSpacing(10); -        center.setPrefWidth(300); - -        VBox right = new VBox(diffLabel,diffList,newDiffs); -        right.setSpacing(10); -        center.setPrefWidth(300);          HBox mainBox = new HBox(); -        mainBox.getChildren().addAll(left, center, right); -        mainBox.setSpacing(30); +        mainBox.getChildren().addAll(left, right); +        mainBox.setSpacing(10); +        mainBox.prefHeightProperty().bind(content.heightProperty().multiply(0.75)); +        mainBox.maxWidthProperty().bind(content.widthProperty().multiply(0.95));          Button exit = new Button();          exit.setText("Back"); @@ -184,7 +235,7 @@ public class LevelEditor extends Page              Driver.setMenu(prev);          }); -        HBox bottom = new HBox(exit, save); +        HBox bottom = new HBox(exit);          bottom.setAlignment(Pos.CENTER);          bottom.setSpacing(10); @@ -204,6 +255,26 @@ public class LevelEditor extends Page      @Override      public void onView() { +        diffList.refresh(); +        validate(); +    } + +    @Override +    public void onLeave() { +        Sound.playSfx(Sound.FORWARD); +        level.title = titleEntry.getText(); +        level.artist = artistEntry.getText(); +        level.desc = descEntry.getText(); +        level.colors[0] = colorsPickers[0].getValue(); +        level.colors[1] = colorsPickers[1].getValue(); +        level.colors[2] = colorsPickers[2].getValue(); +        level.colors[3] = colorsPickers[3].getValue(); +        level.colors[4] = colorsPickers[4].getValue(); +        try { +            level.writeMetadata(); +        } catch (IOException ex) { +            // TODO +        }          validate();      } diff --git a/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java index 5ba7d88..6c45865 100644 --- a/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java +++ b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java @@ -165,8 +165,12 @@ public class NotesEditor2 extends Page {          Pane helpBox = new Pane(); +        ScrollPane actionScroll = new ScrollPane(actionBox); +        actionScroll.getStyleClass().remove("scroll-pane"); +        actionScroll.prefWidthProperty().bind(actionBox.widthProperty().add(20)); +          HBox main = new HBox(); -        main.getChildren().addAll(scroll, actionBox, helpBox); +        main.getChildren().addAll(scroll, actionScroll, helpBox);          main.setSpacing(10);          Button exit = new Button(); diff --git a/src/main/java/net/sowgro/npehero/levelapi/Difficulty.java b/src/main/java/net/sowgro/npehero/levelapi/Difficulty.java index 99fa285..c21ecf1 100755 --- a/src/main/java/net/sowgro/npehero/levelapi/Difficulty.java +++ b/src/main/java/net/sowgro/npehero/levelapi/Difficulty.java @@ -82,7 +82,7 @@ public class Difficulty implements Comparable<Difficulty>       * @throws IOException If there is a problem writing to the file       */      public void writeMetadata() throws IOException { -        if (!jsonFile.createNewFile()) { +        if (!jsonFile.exists() && !jsonFile.createNewFile()) {              throw new IOException("Could not create file " + jsonFile.getAbsolutePath());          }          Map<String, Object> data = jsonParser.fromJson(new FileReader(jsonFile), Map.class); // start with previous values diff --git a/src/main/java/net/sowgro/npehero/levelapi/Level.java b/src/main/java/net/sowgro/npehero/levelapi/Level.java index 218779f..c90fa47 100755 --- a/src/main/java/net/sowgro/npehero/levelapi/Level.java +++ b/src/main/java/net/sowgro/npehero/levelapi/Level.java @@ -14,6 +14,10 @@ import java.util.Map;  public class Level implements Comparable<Level>{ +    public static final String SONG_FILE = "song"; +    public static final String BACKGROUND_FILE = "background"; +    public static final String PREVIEW_FILE = "preview"; +      public final File dir;      public String title = "Unnamed"; @@ -28,6 +32,9 @@ public class Level implements Comparable<Level>{      private final File jsonFile;      private final Gson jsonParser = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); +    private File songFile; +    private File previewFile; +    private File backgroundFile;      /**       * Creates a new level @@ -47,20 +54,28 @@ public class Level implements Comparable<Level>{       * Check for a song file, background file and preview image file       */      public void readFiles() { - +        songFile = null; +        previewFile = null; +        backgroundFile = null; +        song = null; +        background = null; +        preview = null;          File[] fileList = dir.listFiles();          if (fileList == null) {              return;          }          for (File file : fileList) {              String fileName = file.getName(); -            if (fileName.contains("song")) { +            if (fileName.contains(SONG_FILE)) { +                songFile = file;                  song = new Media(file.toURI().toString());              } -            else if (fileName.contains("background")) { +            else if (fileName.contains(BACKGROUND_FILE)) { +                backgroundFile = file;                  background = new Image(file.toURI().toString());              } -            else if (fileName.contains("preview")) { +            else if (fileName.contains(PREVIEW_FILE)) { +                previewFile = file;                  preview = new Image(file.toURI().toString());              }          } @@ -108,7 +123,9 @@ public class Level implements Comparable<Level>{       * @throws IOException If there is a problem writing to the file.       */      public void writeMetadata() throws IOException { -        jsonFile.createNewFile(); +        if (!jsonFile.exists() && !jsonFile.createNewFile()) { +            throw new IOException("Could not create file " + jsonFile.getAbsolutePath()); +        }          Map<String, Object> data = jsonParser.fromJson(new FileReader(jsonFile), Map.class);          data.put("title", title);          data.put("artist", artist); @@ -136,6 +153,24 @@ public class Level implements Comparable<Level>{          readFiles();      } +    /** +     * Deletes a file from the level's directory +     * @param name the new file name EXCLUDING the extension. +     * @throws IOException If there is a problem deleting the file +     */ +    public void removeFile(String name) throws IOException { +        File f = switch (name) { +            case SONG_FILE -> songFile; +            case BACKGROUND_FILE -> backgroundFile; +            case PREVIEW_FILE -> previewFile; +            default -> throw new IllegalArgumentException("Invalid file name " + name); +        }; +        if (!f.delete()) { +            throw new IOException("Failed to delete file " + f.getAbsolutePath()); +        } +        readFiles(); +    } +      @Override      public int compareTo(Level other) {          return title.compareTo(other.title); | 
