diff options
| author | notori <188390306+n0tori@users.noreply.github.com> | 2025-03-13 12:28:08 +0000 |
|---|---|---|
| committer | notori <188390306+n0tori@users.noreply.github.com> | 2025-03-13 12:28:08 +0000 |
| commit | 3f80ccbfc0dd2f3b4295e506e7ce5931b720e2ee (patch) | |
| tree | 17b44f56b7aaec5247dbed939e2f567a55b83ce0 /src/main/java/uk/co/notori/gol/MainScreen.java | |
project files
Diffstat (limited to 'src/main/java/uk/co/notori/gol/MainScreen.java')
| -rw-r--r-- | src/main/java/uk/co/notori/gol/MainScreen.java | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/src/main/java/uk/co/notori/gol/MainScreen.java b/src/main/java/uk/co/notori/gol/MainScreen.java new file mode 100644 index 0000000..5829f42 --- /dev/null +++ b/src/main/java/uk/co/notori/gol/MainScreen.java @@ -0,0 +1,185 @@ +package uk.co.notori.gol; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.*; +import java.awt.*; + +/** + * Main screen manager + */ +public class MainScreen { + + private static final Logger log = LoggerFactory.getLogger(MainScreen.class); + + private JPanel currentUI; + private final Container root; + private final ExitHook mainExitHook; + + public interface ExitHook { + void exit(); + } + + public interface NewGameHook { + void newGame(); + } + + public MainScreen(Container root, ExitHook exitHook) { + this(root, exitHook, null); + } + + public MainScreen(Container root, ExitHook exitHook, String savePath) { + this.root = root; + this.mainExitHook = exitHook; + + if (!Util.isKindle()) { + root.setSize(new Dimension(800, 600)); + } + // start new game grid on load + newGame(); + } + + public void start() { + log.info("Starting Game of Life application"); + + if (currentUI != null) { + currentUI.setVisible(true); + + // force a complete refresh + root.invalidate(); + root.validate(); + root.repaint(); + + // very ugly fix for weird component visibility behaviour + if (Util.isKindle()) { + scheduleRefresh(300); + scheduleRefresh(600); + scheduleRefresh(1200); + scheduleRefresh(2000); + scheduleRefresh(3000); + + new java.util.Timer().schedule( + new java.util.TimerTask() { + public void run() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + refreshButtonsOnly(root); + } + }); + } catch (Exception e) { + log.error("Error during button refresh", e); + } + } + }, + 3500 + ); + } + } + + log.info("Application started"); + } + + // another very ugly fix for weird component visibility behaviour + private void scheduleRefresh(final int delay) { + new java.util.Timer().schedule( + new java.util.TimerTask() { + public void run() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + refreshComponentsRecursively(root); + + currentUI.invalidate(); + currentUI.validate(); + currentUI.repaint(); + + root.invalidate(); + root.validate(); + root.repaint(); + + log.info("Completed UI refresh after " + delay + "ms"); + } + }); + } catch (Exception e) { + log.error("Error during UI refresh", e); + } + } + }, + delay + ); + } + + // another very ugly fix for weird component visibility behaviour + private void refreshComponentsRecursively(Container container) { + Component[] components = container.getComponents(); + for (int i = 0; i < components.length; i++) { + Component component = components[i]; + component.invalidate(); + component.validate(); + component.repaint(); + + // handling for buttons to ensure visibility + if (component instanceof JButton) { + JButton button = (JButton)component; + button.setVisible(true); + } + + if (component instanceof Container) { + refreshComponentsRecursively((Container)component); + } + } + } + + private void refreshButtonsOnly(Container container) { + Component[] components = container.getComponents(); + for (int i = 0; i < components.length; i++) { + Component component = components[i]; + + if (component instanceof JButton) { + JButton button = (JButton)component; + button.setVisible(true); + button.invalidate(); + button.validate(); + button.repaint(); + log.info("Refreshed button: " + button.getText()); + } + + if (component instanceof Container) { + refreshButtonsOnly((Container)component); + } + } + } + + public void newGame() { + log.info("Starting new game"); + + // remove current UI if it exists + if (currentUI != null) { + root.remove(currentUI); + } + + // create main UI with new panel + Panel gamePanel = new Panel(root.getSize()); + currentUI = new MainUI( + new ExitHook() { + public void exit() { + mainExitHook.exit(); + } + }, + gamePanel + ); + + currentUI.setSize(root.getSize()); + currentUI.setPreferredSize(root.getSize()); + + root.add(currentUI, BorderLayout.CENTER); + + currentUI.setVisible(true); + gamePanel.setVisible(true); + + root.validate(); + root.repaint(); + } +} |
