Dúvida sobre a criação de objetos

Queria saber por que quando crio um JButton com um método:

JButton btn; criarBotao(btn);

Método:
void criarBotao(JButton b) { b = new JButton("Botão"); };

Não posso acessá-lo em outra classe, por exemplo um código como esse:
classeDoBotao.btn.setText("Algo");

Gera uma NullPointerException mesmo com o botão criado através do método.

Isso é um erro comum para quem está iniciando. Isso não funciona porque a linguagem Java sempre passa parâmetros por cópia. Mesmo quando o argumento é um objeto, o que é passado é uma cópia da referência, e não a referência em si. Ou seja, você deve pensar em btn e b como variáveis diferentes, mesmo que elas apontem para o mesmo objeto. No seu caso, a maneira correta de fazer o que você pretende é:

JButton btn = criarBota();

JButton criarBotao(){
    return new JButton("Botão");
}

Mas e se eu quiser adicionar eventos ao botão? Já que o retorno é o último comando.

É só criar uma variável dentro do método e usá-lo normalmente. No final, você retorna a referência. Lembrando que será criada uma cópia da referência (e não do objeto).

JButton criarBotao(){
    JButton b = new JButton("Botão");
    //...
    return b;
}