© 1999-2003, Flemming Koch Jensen
Alle rettigheder forbeholdt
Command Pattern
Vejledende løsninger

 

 

1 Først laver vi de to banale Receiver-klasser:
class ShoutReceiver  {
  
  public void shout( String s ) {
    System.out.println( s.toUpperCase() );
  }
}
class WhisperReceiver  {
  
  public void whisper( String s ) {
    System.out.println( s.toLowerCase() );
  }
}
Dernæst lave vi de to Command-klasser der får kendskab til Receiver'ne gennem deres konstruktorer:
import javax.swing.*;
import java.awt.event.*;

class ShoutCommand implements ActionListener {
  private ShoutReceiver receiver;
  private JTextField tekstFelt;
  
  public ShoutCommand( ShoutReceiver receiver, JTextField tekstFelt ) {
    this.receiver = receiver;
    this.tekstFelt = tekstFelt;
  }
  
  public void actionPerformed( ActionEvent e ) {
    receiver.shout( tekstFelt.getText() );
    tekstFelt.setText( "" );
  }
}
import javax.swing.*;
import java.awt.event.*;

class WhisperCommand implements ActionListener {
  private WhisperReceiver receiver;
  private JTextField tekstFelt;
  
  public WhisperCommand( WhisperReceiver receiver, JTextField tekstFelt ) {
    this.receiver = receiver;
    this.tekstFelt = tekstFelt;
  }
  
  public void actionPerformed( ActionEvent e ) {
    receiver.whisper( tekstFelt.getText() );
    tekstFelt.setText( "" );
  }
}
TestFrame-klassen er den mest komplekse, da opbygningen af objektsystemet er en betydelig del af løsningen:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class TalkFrame extends JFrame implements ActionListener {
  
  private ActionListener shoutCommand, whisperCommand;
  
  private JRadioButton shoutButton, whisperButton;
  private JButton talkButton;
  
  public TalkFrame( String title ) {
    super( title );
    
    /*
     * Opbygger selve GUI'en
     */
    
    getContentPane().setLayout( new FlowLayout() );
    
    ButtonGroup group = new ButtonGroup();
    
    shoutButton = new JRadioButton( "Råb" );
    shoutButton.addActionListener( this );
    group.add( shoutButton );
    getContentPane().add( shoutButton );
    
    whisperButton = new JRadioButton( "Hvisk" );
    whisperButton.addActionListener( this );
    group.add( whisperButton );
    getContentPane().add( whisperButton );
    
    JTextField tekstFelt = new JTextField( 10 );
    getContentPane().add( tekstFelt );
    
    talkButton = new JButton( "Snak" );
    getContentPane().add( talkButton );
    
    /*
     * Initialiserer vedrørende command'en
     */
    
    shoutCommand = new ShoutCommand( new ShoutReceiver(), tekstFelt );
    whisperCommand = new WhisperCommand( new WhisperReceiver(), tekstFelt );
    
    whisperButton.setSelected( true );
    talkButton.addActionListener( whisperCommand );
    
    /////
    
    setDefaultCloseOperation( EXIT_ON_CLOSE );
    
    pack();
    setVisible( true );
  }
  
  public void actionPerformed( ActionEvent e ) {
    Object source = e.getSource();
    
    if ( source == shoutButton ) {
      removeActionListeners();
      talkButton.addActionListener( shoutCommand );
    } else if ( source == whisperButton ) {
      removeActionListeners();
      talkButton.addActionListener( whisperCommand );
    }
  }
  
  /*
   * Uden denne metode giver gentagne tryk på samme knap problemer
   */
  public void removeActionListeners() {
    talkButton.removeActionListener( whisperCommand );
    talkButton.removeActionListener( shoutCommand );
  }
}
Rødt: Her ser man hvordan de to Command-objekter instantiere med hver deres Receiver, samtidig med de får kendskab til tekstfeltet. Initielt sætter vi whisperCommand som listener på talkButton.
Blåt: Bemærk at vi er nød til at fjerne begge Command-objekter som listeners på talkButton. Dette skyldes at vi ellers kan få tilmeldt det samme Command-objekt flere gange, ved gentagne gange at trykke på denne samme radiobutton.

Kildetekster:

ShoutReceiver.java
WhisperReceiver.java
ShoutCommand.java
WhisperCommand.java
TalkFrame.java
Test.java