From b3266fd50a5fc6111f89d1e704260c92f1fc3810 Mon Sep 17 00:00:00 2001 From: Takibalu Date: Mon, 20 May 2024 22:37:49 +0200 Subject: [PATCH] More high severity Issue fixed, Complex methods to smaller ones --- src/main/java/Controller/Controller.java | 58 +++-- src/main/java/Controller/Main.java | 295 +++++++++++++---------- src/main/java/Model/Pipe.java | 64 ++--- src/main/java/Model/Pump.java | 4 +- src/main/java/View/AppPanel.java | 3 +- src/main/java/View/CisternView.java | 4 +- src/main/java/View/GameView.java | 12 +- src/main/java/View/Window.java | 2 +- 8 files changed, 255 insertions(+), 187 deletions(-) diff --git a/src/main/java/Controller/Controller.java b/src/main/java/Controller/Controller.java index ec20fca..a284367 100644 --- a/src/main/java/Controller/Controller.java +++ b/src/main/java/Controller/Controller.java @@ -29,6 +29,9 @@ static public Controller getInstance() { return controller; } final String WrongAttr = "wrong attribute name"; + final String WrongPipe = "wrong pipe name"; + final String WrongPlayer = "wrong player name"; + final String WrongMech = "wrong mechanic name"; final String fellDownStr = "fellDown"; final String stuckStr = "stuck"; final String standingOnStr = "standingOn"; @@ -279,7 +282,7 @@ public void create(String name, String type,int x, int y) { public void connect(String pipeName, String wNodeName) { if (!pipes.contains((Pipe)objectCatalog.get(pipeName))) { - IO_Manager.writeError("wrong pipe name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongPipe, Controller.filetoWrite != null); return; } Pipe p = (Pipe) objectCatalog.get(pipeName); @@ -305,7 +308,7 @@ public void connect(String pipeName, String wNodeName) { public void move(String playerName, String steppableName) { if (!players.contains((Player) objectCatalog.get(playerName))) { - IO_Manager.writeError("wrong player name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongPlayer, Controller.filetoWrite != null); return; } Player p = (Player) objectCatalog.get(playerName); @@ -336,7 +339,7 @@ public void move(String playerName, String steppableName) { public void pierce(String playerName) { if (!players.contains((Player) objectCatalog.get(playerName))) { - IO_Manager.writeError("wrong player name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongPlayer, Controller.filetoWrite != null); return; } Player p = (Player) objectCatalog.get(playerName); @@ -353,7 +356,7 @@ public void pierce(String playerName) { public void glue(String playerName) { if (!players.contains((Player) objectCatalog.get(playerName))) { - IO_Manager.writeError("wrong player name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongPlayer, Controller.filetoWrite != null); return; } Player p = (Player) objectCatalog.get(playerName); @@ -388,7 +391,7 @@ public void lubricate(String saboteurName) { public void repair(String mechanicName) { if (!mechanics.contains((Mechanic) objectCatalog.get(mechanicName))) { - IO_Manager.writeError("wrong mechanic name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongMech, Controller.filetoWrite != null); return; } Mechanic m = (Mechanic) objectCatalog.get(mechanicName); @@ -411,19 +414,19 @@ public void repair(String mechanicName) { public void redirect(String playerName, String inPipeName, String outPipeName) { if (!players.contains((Player) objectCatalog.get(playerName))) { - IO_Manager.writeError("wrong player name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongPlayer, Controller.filetoWrite != null); return; } Player p = (Player) objectCatalog.get(playerName); if (!pipes.contains((Pipe)objectCatalog.get(inPipeName))) { - IO_Manager.writeError("wrong pipe name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongPipe, Controller.filetoWrite != null); return; } Pipe in = (Pipe) objectCatalog.get(inPipeName); if (!pipes.contains((Pipe)objectCatalog.get(outPipeName))) { - IO_Manager.writeError("wrong pipe name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongPipe, Controller.filetoWrite != null); return; } Pipe out = (Pipe) objectCatalog.get(outPipeName); @@ -443,7 +446,7 @@ public void redirect(String playerName, String inPipeName, String outPipeName) { public void pickup(String mechanicName, String pickupName) { if (!mechanics.contains((Mechanic) objectCatalog.get(mechanicName))) { - IO_Manager.writeError("wrong mechanic name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongMech, Controller.filetoWrite != null); return; } Mechanic m = (Mechanic) objectCatalog.get(mechanicName); @@ -467,7 +470,7 @@ public void pickup(String mechanicName, String pickupName) { public void placedown(String mechanicName) { if (!mechanics.contains((Mechanic) objectCatalog.get(mechanicName))) { - IO_Manager.writeError("wrong mechanic name", Controller.filetoWrite != null); + IO_Manager.writeError(WrongMech, Controller.filetoWrite != null); return; } Mechanic m = (Mechanic) objectCatalog.get(mechanicName); @@ -745,12 +748,25 @@ public void waterFlow(String wNodeName) { * @param filename - a fájl amibe mentünk */ public void save(String filename) { + ObjectOutputStream oos = null; + FileOutputStream fops = null; try { - FileOutputStream fops = new FileOutputStream("program.txt"); - ObjectOutputStream oos = new ObjectOutputStream(fops); + fops = new FileOutputStream("program.txt"); + oos = new ObjectOutputStream(fops); oos.writeObject(this); } catch (Exception e) { System.err.println("Error saving state to " + filename + ": " + e.getMessage()); + } finally { + try { + if (oos != null) { + oos.close(); + } + if (fops != null) { + fops.close(); + } + } catch (IOException e) { + System.err.println("Error closing output streams: " + e.getMessage()); + } } IO_Manager.write("saved state to program.txt", Controller.filetoWrite != null); } @@ -760,16 +776,30 @@ public void save(String filename) { * @param filename - a fájl amiből betöltünk */ public void load(String filename) { + ObjectInputStream ois = null; + FileInputStream fis = null; try { - FileInputStream fis = new FileInputStream("program.txt"); - ObjectInputStream ois = new ObjectInputStream(fis); + fis = new FileInputStream("program.txt"); + ois = new ObjectInputStream(fis); controller = (Controller) ois.readObject(); } catch (Exception e) { System.err.println("Error loading state from " + filename + ": " + e.getMessage()); + } finally { + try { + if (ois != null) { + ois.close(); + } + if (fis != null) { + fis.close(); + } + } catch (IOException e) { + System.err.println("Error closing input streams: " + e.getMessage()); + } } IO_Manager.write("loaded state from program.txt", Controller.filetoWrite != null); } + /** * A játék végét lefuttató függvény */ diff --git a/src/main/java/Controller/Main.java b/src/main/java/Controller/Main.java index 9b248cc..047cfef 100644 --- a/src/main/java/Controller/Main.java +++ b/src/main/java/Controller/Main.java @@ -1,8 +1,6 @@ package Controller; import Model.IO_Manager; -import View.AppFrame; -import View.AppPanel; import java.io.File; import java.util.ConcurrentModificationException; @@ -19,8 +17,6 @@ public static void main(String[] args) { String fileToRead = null; String fileToWrite = null; - AppFrame frame; - AppPanel panel; for (int i = 0; i < args.length; i++) { switch (args[i]) { @@ -94,139 +90,172 @@ private static void processCommand(String command, boolean toFile) { for (String s : cmd) s = s.trim(); switch (cmd[0]) { - case "create" -> { - if (cmd.length != 5 && cmd.length !=3) - IO_Manager.writeError("create requires 2 or 4 parameters", Controller.filetoWrite != null); - else - if(cmd[2].equals("pump") || cmd[2].equals("cistern") || cmd[2].equals("spring")){ - if(cmd.length !=5) - IO_Manager.writeError("creating nodes requires 4 parameters", Controller.filetoWrite != null); - else - controller.create(cmd[1], cmd[2], Integer.parseInt(cmd[3]), Integer.parseInt(cmd[4])); - } - else { - if (cmd.length != 3) - IO_Manager.writeError("creating pipes or players requires 2 parameters", Controller.filetoWrite != null); - else - controller.create(cmd[1], cmd[2], 0,0); + case "create" -> processCreateCommand(controller, cmd); + case "connect" -> processConnectCommand(controller, cmd); + case "move" -> processMoveCommand(controller, cmd); + case "pierce" -> processPierceCommand(controller, cmd); + case "glue" -> processGlueCommand(controller, cmd); + case "lubricate" -> processLubricateCommand(controller, cmd); + case "repair" -> processRepairCommand(controller, cmd); + case "redirect" -> processRedirectCommand(controller, cmd); + case "pickup" -> processPickupCommand(controller, cmd); + case "placedown" -> processPlaceDownCommand(controller, cmd); + case "state" -> processStateCommand(controller, cmd); + case "nextTurn" -> processNextTurnCommand(controller, cmd); + case "generate" -> processGenerateCommand(controller, cmd); + case "waterFlow" -> processWaterFlowCommand(controller, cmd); + case "save" -> processSaveCommand(controller, cmd); + case "load" -> processLoadCommand(controller, cmd); + case "endGame" -> processEndGameCommand(controller, cmd); + case "startGame" -> processStartGameCommand(controller, cmd); + default -> IO_Manager.writeError("Unknown command: " + cmd[0], Controller.filetoWrite != null); + } + } - } - } - case "connect" -> { - if (cmd.length != 3) - IO_Manager.writeError("connect requires 2 parameters", Controller.filetoWrite != null); - else - controller.connect(cmd[1], cmd[2]); - } - case "move" -> { - if (cmd.length != 3) - IO_Manager.writeError("move requires 2 parameters", Controller.filetoWrite != null); - else - controller.move(cmd[1], cmd[2]); - } - case "pierce" -> { - if (cmd.length != 2) - IO_Manager.writeError("pierce requires 1 parameter", Controller.filetoWrite != null); - else - controller.pierce(cmd[1]); - } - case "glue" -> { - if (cmd.length != 2) - IO_Manager.writeError("glue requires 1 parameter", Controller.filetoWrite != null); - else - controller.glue(cmd[1]); - } - case "lubricate" -> { - if (cmd.length != 2) - IO_Manager.writeError("lubricate requires 1 parameter", Controller.filetoWrite != null); - else - controller.lubricate(cmd[1]); - } - case "repair" -> { - if (cmd.length != 2) - IO_Manager.writeError("repair requires 1 parameter", Controller.filetoWrite != null); - else - controller.repair(cmd[1]); - } - case "redirect" -> { - if (cmd.length != 4) - IO_Manager.writeError("redirect requires 3 parameters", Controller.filetoWrite != null); - else - controller.redirect(cmd[1], cmd[2], cmd[3]); - } - case "pickup" -> { - if (cmd.length != 3) - IO_Manager.writeError("pickup requires 2 parameters", Controller.filetoWrite != null); - else - controller.pickup(cmd[1], cmd[2]); - } - case "placedown" -> { - if (cmd.length != 2) - IO_Manager.writeError("placedown requires 1 parameter", Controller.filetoWrite != null); - else - controller.placedown(cmd[1]); - } - case "state" -> { - if (cmd.length < 2) - IO_Manager.writeError("available commands are:\tstate get\tstate set", Controller.filetoWrite != null); - else if (cmd[1].equals("get")) - if (cmd.length != 4) - IO_Manager.writeError("state get requires 2 parameters", Controller.filetoWrite != null); - else - controller.stateGet(cmd[2], cmd[3]); - else if (cmd[1].equals("set")) - if (cmd.length != 5) - IO_Manager.writeError("state set requires 3 parameters", Controller.filetoWrite != null); - else - controller.stateSet(cmd[2], cmd[3], cmd[4]); - else - IO_Manager.writeError("available commands are:\tstate get\tstate set", Controller.filetoWrite != null); - } - case "nextTurn" -> { - if (cmd.length != 1) - IO_Manager.writeError("nextTurn requires no parameters", Controller.filetoWrite != null); - else - controller.nextTurn(); - } - case "generate" -> { - if (cmd.length != 4) - IO_Manager.writeError("generate requires 3 parameters", Controller.filetoWrite != null); - else - controller.generate(cmd[1], cmd[2], cmd[3]); - } - case "waterFlow" -> { - if (cmd.length != 2) - IO_Manager.writeError("waterFlow requires no parameters", Controller.filetoWrite != null); - else - controller.waterFlow(cmd[1]); - } - case "save" -> { - if (cmd.length != 2) - IO_Manager.writeError("save requires 1 parameter", Controller.filetoWrite != null); - else - controller.save(cmd[1]); - } - case "load" -> { - if (cmd.length != 2) - IO_Manager.writeError("load requires 1 parameter", Controller.filetoWrite != null); - else - controller.load(cmd[1]); - } - case "endGame" -> { - if (cmd.length != 1) - IO_Manager.writeError("endGame requires no parameters", Controller.filetoWrite != null); - else - controller.endGame(); - } - case "startGame" -> { - if (cmd.length != 1) - IO_Manager.writeError("startGame requires no parameters", Controller.filetoWrite != null); - else - controller.startGame(); - } + private static void processCreateCommand(Controller controller, String[] cmd) { + if (cmd.length != 5 && cmd.length != 3) + IO_Manager.writeError("create requires 2 or 4 parameters", Controller.filetoWrite != null); + else if (cmd[2].equals("pump") || cmd[2].equals("cistern") || cmd[2].equals("spring")) { + if (cmd.length != 5) + IO_Manager.writeError("creating nodes requires 4 parameters", Controller.filetoWrite != null); + else + controller.create(cmd[1], cmd[2], Integer.parseInt(cmd[3]), Integer.parseInt(cmd[4])); + } else { + if (cmd.length != 3) + IO_Manager.writeError("creating pipes or players requires 2 parameters", Controller.filetoWrite != null); + else + controller.create(cmd[1], cmd[2], 0, 0); } } + private static void processConnectCommand(Controller controller, String[] cmd) { + if (cmd.length != 3) + IO_Manager.writeError("connect requires 2 parameters", Controller.filetoWrite != null); + else + controller.connect(cmd[1], cmd[2]); + } + + private static void processMoveCommand(Controller controller, String[] cmd) { + if (cmd.length != 3) + IO_Manager.writeError("move requires 2 parameters", Controller.filetoWrite != null); + else + controller.move(cmd[1], cmd[2]); + } + private static void processPierceCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("pierce requires 1 parameter", Controller.filetoWrite != null); + else + controller.pierce(cmd[1]); + } + + private static void processGlueCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("glue requires 1 parameter", Controller.filetoWrite != null); + else + controller.glue(cmd[1]); + } + + private static void processLubricateCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("lubricate requires 1 parameter", Controller.filetoWrite != null); + else + controller.lubricate(cmd[1]); + } + + private static void processRepairCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("repair requires 1 parameter", Controller.filetoWrite != null); + else + controller.repair(cmd[1]); + } + + private static void processRedirectCommand(Controller controller, String[] cmd) { + if (cmd.length != 4) + IO_Manager.writeError("redirect requires 3 parameters", Controller.filetoWrite != null); + else + controller.redirect(cmd[1], cmd[2], cmd[3]); + } + + private static void processPickupCommand(Controller controller, String[] cmd) { + if (cmd.length != 3) + IO_Manager.writeError("pickup requires 2 parameters", Controller.filetoWrite != null); + else + controller.pickup(cmd[1], cmd[2]); + } + + private static void processPlaceDownCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("placedown requires 1 parameter", Controller.filetoWrite != null); + else + controller.placedown(cmd[1]); + } + + private static void processStateCommand(Controller controller, String[] cmd) { + if (cmd.length < 2) + IO_Manager.writeError("available commands are:\tstate get\tstate set", Controller.filetoWrite != null); + else if (cmd[1].equals("get")) { + if (cmd.length != 4) + IO_Manager.writeError("state get requires 2 parameters", Controller.filetoWrite != null); + else + controller.stateGet(cmd[2], cmd[3]); + } else if (cmd[1].equals("set")) { + if (cmd.length != 5) + IO_Manager.writeError("state set requires 3 parameters", Controller.filetoWrite != null); + else + controller.stateSet(cmd[2], cmd[3], cmd[4]); + } else { + IO_Manager.writeError("available commands are:\tstate get\tstate set", Controller.filetoWrite != null); + } + } + + private static void processNextTurnCommand(Controller controller, String[] cmd) { + if (cmd.length != 1) + IO_Manager.writeError("nextTurn requires no parameters", Controller.filetoWrite != null); + else + controller.nextTurn(); + } + + private static void processGenerateCommand(Controller controller, String[] cmd) { + if (cmd.length != 4) + IO_Manager.writeError("generate requires 3 parameters", Controller.filetoWrite != null); + else + controller.generate(cmd[1], cmd[2], cmd[3]); + } + + private static void processWaterFlowCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("waterFlow requires no parameters", Controller.filetoWrite != null); + else + controller.waterFlow(cmd[1]); + } + + private static void processSaveCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("save requires 1 parameter", Controller.filetoWrite != null); + else + controller.save(cmd[1]); + } + + private static void processLoadCommand(Controller controller, String[] cmd) { + if (cmd.length != 2) + IO_Manager.writeError("load requires 1 parameter", Controller.filetoWrite != null); + else + controller.load(cmd[1]); + } + + private static void processEndGameCommand(Controller controller, String[] cmd) { + if (cmd.length != 1) + IO_Manager.writeError("endGame requires no parameters", Controller.filetoWrite != null); + else + controller.endGame(); + } + + private static void processStartGameCommand(Controller controller, String[] cmd) { + if (cmd.length != 1) + IO_Manager.writeError("startGame requires no parameters", Controller.filetoWrite != null); + else + controller.startGame(); + } } diff --git a/src/main/java/Model/Pipe.java b/src/main/java/Model/Pipe.java index dce0d2d..fb5b8b9 100644 --- a/src/main/java/Model/Pipe.java +++ b/src/main/java/Model/Pipe.java @@ -121,44 +121,52 @@ public boolean PlayerEnter(Player player) { players.add(player); if (lubricated){ - SecureRandom random = new SecureRandom(); - int end = random.nextInt(1,2); - boolean ignoreState = Player.isIgnoreStates(); - Player.setIgnoreStates(true); - if(end == 1){ - player.getStandingOn().PlayerExit(player); - player.setStandingOn(null); - player.Move(nodes.getFirst()); - } - else if(end == 2){ - player.getStandingOn().PlayerExit(player); - player.setStandingOn(null); - player.Move(nodes.getLast()); - } - Player.setIgnoreStates(ignoreState); - players.remove(player); - if (player.getState() == PlayerActionState.MOVE_ACTION) - player.setState(PlayerActionState.SPECIAL_ACTION); - else if (player.getState() == PlayerActionState.SPECIAL_ACTION) { - player.setState(PlayerActionState.TURN_OVER); - Controller.getInstance().turnOver(); - } - lubricated = false; + handleLubricatedPlayer(player); successful = false; } if (glued) { - player.setStuck(true); - player.setGlueLength(1); - glued = false; - player.setState(PlayerActionState.TURN_OVER); - Controller.getInstance().turnOver(); + handleGluedPlayer(player); } } return successful; } + private void handleLubricatedPlayer(Player player) { + SecureRandom random = new SecureRandom(); + int end = random.nextInt(1, 3); // 1 or 2 + boolean ignoreState = Player.isIgnoreStates(); + Player.setIgnoreStates(true); + + player.getStandingOn().PlayerExit(player); + player.setStandingOn(null); + + if (end == 1) { + player.Move(nodes.getFirst()); + } else { + player.Move(nodes.getLast()); + } + + Player.setIgnoreStates(ignoreState); + players.remove(player); + if (player.getState() == PlayerActionState.MOVE_ACTION) { + player.setState(PlayerActionState.SPECIAL_ACTION); + } else if (player.getState() == PlayerActionState.SPECIAL_ACTION) { + player.setState(PlayerActionState.TURN_OVER); + Controller.getInstance().turnOver(); + } + lubricated = false; + } + + private void handleGluedPlayer(Player player) { + player.setStuck(true); + player.setGlueLength(1); + glued = false; + player.setState(PlayerActionState.TURN_OVER); + Controller.getInstance().turnOver(); + } + /** * Amennyiben a játékos leléphet a csőről, akkor * lekerül róla, és az eltávolítja a players attribútumából. diff --git a/src/main/java/Model/Pump.java b/src/main/java/Model/Pump.java index b07145e..64b6d58 100644 --- a/src/main/java/Model/Pump.java +++ b/src/main/java/Model/Pump.java @@ -53,7 +53,9 @@ public void setController(Controller controller) { * @param from melyik elemről vesszük le / csatlakoztatjuk le a pumpát */ @Override - public void PickedUp(Steppable from) {} + public void PickedUp(Steppable from) { + throw new UnsupportedOperationException(); + } /** * Pumpa letétele diff --git a/src/main/java/View/AppPanel.java b/src/main/java/View/AppPanel.java index 3dfd06f..dd670f8 100644 --- a/src/main/java/View/AppPanel.java +++ b/src/main/java/View/AppPanel.java @@ -10,14 +10,13 @@ */ public class AppPanel extends JPanel { - private MouseIn mouseIn=new MouseIn(); - /** * Konstruktor, beállítja a paramétereket */ public AppPanel(){ setFocusable(true); requestFocusInWindow(); + MouseIn mouseIn = new MouseIn(); addMouseListener(mouseIn); addMouseMotionListener(mouseIn); } diff --git a/src/main/java/View/CisternView.java b/src/main/java/View/CisternView.java index 44ca29a..31fd20b 100644 --- a/src/main/java/View/CisternView.java +++ b/src/main/java/View/CisternView.java @@ -14,8 +14,8 @@ */ public class CisternView extends Drawable implements Clickable, CreatePopUpBar, SteppableView { - private Cistern cistern; - private int r; + private final Cistern cistern; + private final int r; private GameView gameView = null; private BufferedImage sprite = null; diff --git a/src/main/java/View/GameView.java b/src/main/java/View/GameView.java index d48fbf1..bcccaf2 100644 --- a/src/main/java/View/GameView.java +++ b/src/main/java/View/GameView.java @@ -7,6 +7,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; +import java.io.Serializable; import java.util.LinkedList; import static View.Pictures.*; @@ -15,7 +16,7 @@ /** * A játék nézetét megvalósító osztály. */ -public class GameView extends Window { +public class GameView extends Window implements Serializable { /** * Map beállítása. @@ -38,7 +39,7 @@ public void mapSetup(String file) { protected PopUpBar popUpBar = null; protected PopUpBar cisternDisplay = null; private boolean ended = false; - private Button exit; + private final Button exit; private AppFrame frame; @@ -76,7 +77,7 @@ public void setStarted(boolean started) { } - private Object sync = new Object(); + private final Object sync = new Object(); /** * kirajzolás megvalósítása. @@ -134,7 +135,6 @@ else if (PointCounter.getInstance().GetMechanicPoints() == PointCounter.getInsta Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.BLACK); g2d.setFont(new Font("Inter", Font.BOLD, 20)); - AppFrame f = Controller.getInstance().getFrame(); g2d.drawString("Válaszd ki a két átirányítandó csövet!", 40, 40); } } @@ -194,12 +194,12 @@ public void mouseReleased(MouseEvent e) { @Override public void mouseEntered(MouseEvent e) { - + // Not used, intentionally left blank } @Override public void mouseExited(MouseEvent e) { - + // Not used, intentionally left blank } @Override diff --git a/src/main/java/View/Window.java b/src/main/java/View/Window.java index 36a72b3..fc2878f 100644 --- a/src/main/java/View/Window.java +++ b/src/main/java/View/Window.java @@ -14,7 +14,7 @@ /** * A játék ablakát reprezentáló osztály */ -public abstract class Window { +public abstract class Window implements Serializable { protected LinkedList drawables = new LinkedList<>(); protected LinkedList clickables = new LinkedList<>(); protected LinkedList components = new LinkedList<>();