Q:

How to get this JButton to work?

I am having some serious trouble on JButtons. My problem is that the JButton just won't show up, no matter what I try. I've been trying everything for over an hour, and nothing has worked, so I think it is time to ask here. Here is my code. It's just the constructor because the whole class is really big and you don't need to see it.
public Game() {

    frame = new JFrame(NAME);
    canvas = new Canvas();

    canvas.setMinimumSize(new Dimension(width, height));
    canvas.setMaximumSize(new Dimension(width, height));
    canvas.setPreferredSize(new Dimension(width, height));
    canvas.setFocusable(false);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout());
    frame.setSize(width, height);

    frame.add(canvas, BorderLayout.CENTER);

    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.pack();
    frame.setVisible(true);
    frame.setFocusable(true);
    frame.requestFocus();

    JPanel panel = new JPanel();
    JButton play = new JButton("Hi");

    panel.add(play);
    frame.getContentPane().add(panel);
    panel.setPreferredSize(new Dimension(width, height));

}

A:

Main problems:

frame.pack(); should be done after all components are added. 
frame.setVisible(true); is best put after all adding, packing & configuration.

import java.awt.*;
import javax.swing.*;

public class Game {

    private JFrame frame = null;
    private Canvas canvas = null;
    private String NAME = "Moronically Named Game";
    int width = 500;
    int height = 200;

    public Game() {

        frame = new JFrame(NAME);
        canvas = new Canvas();

        canvas.setMinimumSize(new Dimension(width, height));
        canvas.setMaximumSize(new Dimension(width, height));
        canvas.setPreferredSize(new Dimension(width, height));
        canvas.setFocusable(false);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.setSize(width, height);

        frame.add(canvas, BorderLayout.CENTER);

        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setFocusable(true);
        frame.requestFocus();

        JPanel panel = new JPanel();
        JButton play = new JButton("Hi");

        panel.add(play);
        frame.getContentPane().add(panel);
        panel.setPreferredSize(new Dimension(width, height));

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                Game o = new Game();
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Other tips:

For better help sooner, post a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example. E.G. as seen in my answer. You posted an uncompilable code snippet in the question, I turned it into an MCVE for the answer.
See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?  (Yes.) 
As to layout out the GUI with padding as mentioned in tip (2). Provide ASCII art or a simple drawing of the intended layout of the GUI at minimum size, and if resizable, with more width and height.

