Search code examples
clojuremiglayoutminesweeperseesaw

How to create a MigLayout for a simple minesweeper game?


I am working on a simple clojure minesweeper game, mainly to exercise the language a bit. The "core game engine" is ready and now I'd like to add a simple UI. I had a look into seesaw and so far it worked quite nicely.

The only thing I am struggling with is the mig layout which I'd like to use. My idea is to have kind of the following layout:

 _______________________
[_________NORTH_________]
[   ][             ][   ]
[ W ][    FIXED    ][ E ]
[ E ][    SIZE     ][ A ]
[ S ][    BOARD    ][ S ]
[ T ][             ][ T ]
[___][_____________][___]
[_________SOUTH_________]

The north, west, east and south should grow in case the window is resized. The main panel should have a fixed size with all the buttons that represent the game board.

Before I read about mig layout I considered using a border-panel containing a grid-panel but as mentioned on the seesaw github page:

Seesaw has rudimentary support for GridBagLayout in the seesaw.core/form-panel function. I don't recommend using this because it's half-baked and not as powerful as using MigLayout (seesaw.mig) or JGoodies (seesaw.forms).

I'd like to give MigLayout a try. My first try:

(defn make-border-panel 
[]
(mig-panel 
 :constraints ["fill" "[grow][][grow]" "[grow][][grow]"]
 :items [ 
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["X"                  "shrink 0"  ]
       ["Minesweeper North"  "dock north"]
       ["W"                  "dock west" ]
       ["E"                  "dock east" ]
       ["Minesweeper South"  "dock south"]
      ]))

UPDATE 1

I'll ignore north, south, west, east for the moment and did the following to get at least the center board:

(defn make-button [x y]
   (button :id (format "cell_%d_%d" x y)
           :icon (clojure.java.io/resource "minesweeper/icons/button.png")))


(defn make-board
  [w h]
  (mig-panel 
      :constraints [(str "wrap" w) "[]" "[]" ]
      :items (for [x (range w) y (range h)]  
          (vector (make-button x y) "w 24px!, h 24px!"))))

Solution

  • I realized that I do not really need WEST and EAST panel for my minesweeper game. My final layout looks like this:

     _____________
    [____NORTH____]
    [             ]
    [             ]
    [   CENTER    ]
    [             ]
    [_____________]
    [____SOUTH____]
    

    Center itself is another mig panel that contains the buttons representing the mines. The code in clojure looks like the following:

    (defn make-layout
      [rows cols level]
      (mig-panel
       :constraints ["wrap1" "[center]" "[][]" ]
       :items       [[(make-info-panel)]
                    [(make-board-panel rows cols level)]]))
    
    
    (defn make-board-panel
      [rows cols level]
      (let [bg (button-group)]
        (mig-panel
         :constraints [(str "gap 0, wrap" rows) "[]" "[]" ]
         :items       (for [row (range rows) col (range cols)]
                        (vector (make-button row col level bg) "w 24px!, h 24px!")))))