@@ -31,24 +31,81 @@ public Controller getController() {
3131 public SokobanWindow (Controller controller ) {
3232 this .controller = controller ;
3333
34+ // Calculate game panel dimensions
3435 int IMAGE_WIDTH = controller .getWarehouse ().getColumns () * IMAGE_SIZE ;
3536 int IMAGE_HEIGHT = controller .getWarehouse ().getLines () * IMAGE_SIZE ;
3637
37- this .setDefaultCloseOperation ( JFrame .EXIT_ON_CLOSE );
38- this .setPreferredSize ( new Dimension ( IMAGE_WIDTH + 16 , IMAGE_HEIGHT + 39 ));
39- if (controller .isOnCustomLevel ()) {
40- this .setTitle ( "Custom level" );
41- }
42- else {
43- this .setTitle ( "Level %s" .formatted (controller .getLevel ()));
44- }
38+ // Create game panel with fixed size
39+ SokobanPanel gamePanel = new SokobanPanel (controller );
40+ gamePanel .setPreferredSize (new Dimension (IMAGE_WIDTH , IMAGE_HEIGHT ));
41+
42+ // Create and configure the info panel
43+ JPanel infoPanel = makeInfoPanel ();
44+
45+ // Create main content panel with BoxLayout for vertical arrangement
46+ JPanel contentPane = new JPanel ();
47+ contentPane .setLayout (new BoxLayout (contentPane , BoxLayout .Y_AXIS ));
48+
49+ // Center the game panel horizontally
50+ JPanel gamePanelContainer = new JPanel ();
51+ gamePanelContainer .setLayout (new BoxLayout (gamePanelContainer , BoxLayout .X_AXIS ));
52+ gamePanelContainer .add (Box .createHorizontalGlue ());
53+ gamePanelContainer .add (gamePanel );
54+ gamePanelContainer .add (Box .createHorizontalGlue ());
55+
56+ // Add vertical glue to push content to center
57+ contentPane .add (Box .createVerticalGlue ());
58+ contentPane .add (gamePanelContainer );
59+ contentPane .add (Box .createVerticalStrut (20 )); // Add some space between panels
60+ contentPane .add (infoPanel );
61+ contentPane .add (Box .createVerticalGlue ());
62+
63+ // Set up the frame
64+ this .setDefaultCloseOperation (JFrame .EXIT_ON_CLOSE );
65+ this .setContentPane (contentPane );
66+
67+ // Calculate window size with extra padding for centering
68+ int windowWidth = Math .max (500 , IMAGE_WIDTH + 40 );
69+ int windowHeight = IMAGE_HEIGHT + infoPanel .getPreferredSize ().height + 80 ; // Extra padding for vertical centering
70+
71+ // Set size and position
72+ this .setSize (windowWidth , windowHeight );
73+ this .setMinimumSize (new Dimension (windowWidth , windowHeight ));
74+ this .setLocationRelativeTo (null );
4575 this .setResizable (false );
76+ this .setTitle (controller .isOnCustomLevel () ? "Custom level" : "Level %s" .formatted (controller .getLevel ()));
4677
47- this . add ( new SokobanPanel ( controller ));
48- this .addKeyListener ( this );
78+ // Add key listener and make window visible
79+ this .addKeyListener (this );
4980 this .pack ();
50- this .setLocationRelativeTo ( null );
51- this .setVisible ( true );
81+ this .setVisible (true );
82+ }
83+
84+ private static JPanel makeInfoPanel () {
85+ JPanel infoPanel = new JPanel ();
86+ infoPanel .setBorder (BorderFactory .createEmptyBorder (10 , 10 , 10 , 10 ));
87+ infoPanel .setBackground (Color .LIGHT_GRAY );
88+
89+ String controlsText = """
90+ <html><div style='font-family: Arial; text-align: center;'>
91+ <table cellspacing='10' style='margin: 0 auto;'>
92+ <tr>
93+ <td style='text-align: right;'><b>Movement:</b></td>
94+ <td style='text-align: left;'>Arrow Keys</td>
95+ <td style='text-align: right;'><b>Undo:</b></td>
96+ <td style='text-align: left;'>Space</td>
97+ </tr>
98+ <tr>
99+ <td style='text-align: right;'><b>Restart:</b></td>
100+ <td style='text-align: left;'>Backspace</td>
101+ <td style='text-align: right;'><b>Exit:</b></td>
102+ <td style='text-align: left;'>ESC</td>
103+ </tr>
104+ </table></div></html>";""" ;
105+
106+ JLabel controlsLabel = new JLabel (controlsText );
107+ infoPanel .add (controlsLabel );
108+ return infoPanel ;
52109 }
53110
54111 @ Override
0 commit comments