E' appena appena un po' più complessa:

codice:
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class testoEBottone extends JFrame implements DocumentListener, ActionListener {
  
  JTextField tf;
  JButton button;
  
  public void actionPerformed (ActionEvent ae) {
    tf.setText("");    
  }
  
  public void changedUpdate (DocumentEvent de) {
  }
  
  public void insertUpdate(DocumentEvent de) {
    button.setEnabled(true);    
    button.setText("Attivato");
  }
  
  public void removeUpdate (DocumentEvent de) {
    if (de.getDocument().getLength()==0) {
      button.setEnabled(false);
      button.setText("Disattivato");
    }
  }
  
  public testoEBottone() {
    super("Testo attiva");
    this.getContentPane().setLayout(new GridLayout(2,1));
    tf = new JTextField();
    button = new JButton("Disattivato");
    button.setEnabled(false);
    button.addActionListener(this);
    this.getContentPane().add(tf);
    this.getContentPane().add(button);
    tf.getDocument().addDocumentListener(this);
    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.pack();
  }
  
  public static void main (String[] args) {
    testoEBottone teb = new testoEBottone();
  }
}
Questo perché hanno pensato ad una gestione comune degli eventi sui textcomponent in swing (passando dalla creazione del document).