@SuppressWarnings({"AbstractMethodCallInConstructor", "ThisEscapedInObjectConstruction"})
  protected AbstractGameDisplay() {
    doAddWindowListener(this);

    addMenuBar();

    // A pane for the entire center area: map, status.
    JPanel contentPane = new JPanel(new BorderLayout());
    doAddKeyListener(contentPane);
    setContentPane(contentPane);
    contentPane.setBorder(BorderFactory.createEtchedBorder());

    // ..add the map.
    JPanel westContainer = new JPanel(new BorderLayout());
    _mapPane = createMapPane();
    _mapPane.addMouseListener(this);
    JScrollPane mapContainer = new JScrollPane(_mapPane);
    mapContainer.setBorder(BorderFactory.createEtchedBorder());

    // ..add the status area.
    JPanel statusPaneContainer =
        new JPanel(new BorderLayout()); // hack to deal with text area sizing bug.
    statusPaneContainer.setAlignmentX(Component.LEFT_ALIGNMENT);
    _statusPane = createStatusPane();
    _statusPane.setEditable(false);
    statusPaneContainer.add(_statusPane, BorderLayout.WEST);
    westContainer.add(mapContainer, BorderLayout.CENTER);
    westContainer.add(statusPaneContainer, BorderLayout.SOUTH);

    // The side pane with all the currently relevant details (e.g. selected hex info).
    _detailsPane = createDetailsPane();
    _detailsPane.setBorder(BorderFactory.createEtchedBorder());

    // A bottom pane with a list of the game events from the previously run turn.
    _eventsPane = createEventsPane();
    _eventsPane.setBorder(BorderFactory.createEtchedBorder());

    contentPane.add(westContainer, BorderLayout.CENTER);
    contentPane.add(_detailsPane, BorderLayout.EAST);
    contentPane.add(_eventsPane, BorderLayout.SOUTH);
  }