Veja, você mesmo criou a confusão.
a) Você declarou uma classe, que estende JFrame;
b) No construtor dessa classe, você criou um objeto, do tipo JFrame.
c) Você exibe o objeto criado, mas usa o add na sua própria classe.
d) Seu construtor acaba não fazendo coisa nenhuma na sua própria classe.
Elimine a confusão removendo o passo b). A forma que você corrigiu está certa, mas ainda gera um código confuso (se você vai criar um JFrame direto, para que estender JFrame?)
O código corrigido fica assim:
[code]
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Font;
public class Tam extends JFrame {
private JLabel displayText;
public Tam() {
displayText = new JLabel("Tam");
displayText.setFont(new Font("Serif", Font.PLAIN, 72));
//Adicionamos tudo no frame que estamos construindo
add(displayText, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 250);
setTitle("Título");
}
public static void main(String[] args) {
//Abrimos a janela da classe Tam, que acabamos de criar
new Tam().setVisible(true);
}
}[/code]
Note que também eliminei a chamada a setVisible(true) do seu construtor. É considerado péssima prática em programação Swing chamar setVisible no construtor, pois você está tornando visível uma janela que ainda não foi completamente construída (a construção de um objeto só termina quando o construtor termina. E isso nem sempre é na última linha do construtor, pois pode existir classes filhas).
Os layout managers definem como os componentes de sua tela ficarão posicionados. Se você não definir nenhum, o JFrame estará por padrão em BorderLayout. Para entender como cada layout manager funciona, dê uma olhada nesse guia visual:
http://download.oracle.com/javase/tutorial/uiswing/layout/visual.html
Layout managers são a forma correta, portável e multiplataforma de posicionar componentes. Com eles, você também pode fazer janelas redimensionáveis, pois você ajusta como cada componente deve se esticar e se locomover quando a janela mudar de tamanho.