Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
202
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

Factory Method

The following example uses the Factory Method pattern to produce an editor for the PIM. The PIM tracks a lot of information, and there are many cases where users need an editor to create or modify data. The example uses interfaces to improve the overall flexibility of the system.

The Editable interface defines a builder method, getEditor, which returns an ItemEditor interface. The benefit is that any item can provide an editor for itself, producing an object that knows what parts of a business object can change and how they can be changed. The only thing the user interface needs to do is use the Editable interface to get an editor.

Example A.21 Editable.java

1.public interface Editable {

2.public ItemEditor getEditor();

3.}

The ItemEditor interface provides two methods: getGUI and commitChanges. The getGUI method is another Factory Method—it returns a JComponent that provides a Swing GUI to edit the current item. This makes a very flexible system; to add a new type of item, the user interface can remain the same, because it only uses the

Editable and the ItemEditor interfaces.

The JComponent returned by getGUI can have anything in it required to edit the item in the PIM. The user interface can simply the acquired JComponent in its editor window and use the JComponent functionality to edit the item. Since not everything in an application needs to be graphical, it could also be a good idea to include a getUI method that would return an Object or some other nongraphical interface.

The second method, commitChanges, allows the UI to tell the editor that the user wants to finalize the changes he or she has made.

Example A.22 ItemEditor.java

1.import javax.swing.JComponent;

2.public interface ItemEditor {

3.public JComponent getGUI();

4.public void commitChanges();

5.}

The following code shows the implementation for one of the PIM items, Contact. The Contact class defines two attributes: the name of the person and their relationship with the user. These attributes provide a sample of some of the information, which could be included in an entry in the PIM.

Example A.23 Contact.java

1.import java.awt.GridLayout;

2.import java.io.Serializable;

3.import javax.swing.JComponent;

4.import javax.swing.JLabel;

5.import javax.swing.JPanel;

6.import javax.swing.JTextField;

8.public class Contact implements Editable, Serializable {

9.private String name;

10.private String relationship;

11.

12.public ItemEditor getEditor() {

13.return new ContactEditor();

14.}

15.

16.private class ContactEditor implements ItemEditor, Serializable {

17.private transient JPanel panel;

18.private transient JTextField nameField;

19.private transient JTextField relationField;

20.

21.public JComponent getGUI() {

22. if (panel == null) {

23. panel = new JPanel();

24. nameField = new JTextField(name);

25. relationField = new JTextField(relationship);

26. panel.setLayout(new GridLayout(2,2));

27. panel.add(new JLabel("Name:"));

228

28.

panel.add(nameField);

29.

panel.add(new JLabel("Relationship:"));

30.

panel.add(relationField);

31.

} else {

32.

nameField.setText(name);

33.

relationField.setText(relationship);

34.

}

35.

return panel;

36.

}

37.

 

38.public void commitChanges() {

39.

if (panel != null) {

40.

name = nameField.getText();

41.

relationship = relationField.getText();

42.

}

43.

}

44.

 

45.public String toString(){

46. return "\nContact:\n" +

47. " Name: " + name + "\n" +

48. " Relationship: " + relationship;

49.}

50.}

51.}

Contact implements the Editable interface, and provides its own editor. That editor only applies to the Contact class, and needs to change certain attributes of the Contact, it is best to use an inner class. The inner class has direct access to the attributes of the outer class. If you used another (non-inner) class, Contact would need to provide accessor and mutator methods, making it harder to restrict access to the object’s private data.

Note that the editor itself is not a Swing component, but only an object that can serve as a factory for such a component. The greatest benefit is that you can serialize and send this object across a stream. To implement this feature, declare all Swing component attributes in ContactEditor transient—they’re constructed when and where they’re needed.

The EditorGui represents a generic editor you might use in the PIM. Note that the class uses the ItemEditor interface to entirely manage its edit window. It constructs a JPanel for its edit window, and places the JComponent obtained by the call to getGUI inside. The Swing component provides all the edit capabilities for the Contact, while the EditorGui provides control buttons and a JTextArea to display the state of the Contact object.

Example A.24 EditorGui.java

1.import java.awt.Container;

2.import java.awt.event.ActionListener;

3.import java.awt.event.WindowAdapter;

4.import java.awt.event.ActionEvent;

5.import java.awt.event.WindowEvent;

6.import javax.swing.BoxLayout;

7.import javax.swing.JButton;

8.import javax.swing.JComponent;

9.import javax.swing.JFrame;

10.import javax.swing.JPanel;

11.import javax.swing.JTextArea;

12.public class EditorGui implements ActionListener{

13.private JFrame mainFrame;

14.private JTextArea display;

15.private JButton update, exit;

16.private JPanel controlPanel, displayPanel, editorPanel;

17.private ItemEditor editor;

18.

19.public EditorGui(ItemEditor edit){

20.editor = edit;

21.}

22.

23.public void createGui(){

24.mainFrame = new JFrame("Factory Pattern Example");

25.Container content = mainFrame.getContentPane();

26.content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

28.editorPanel = new JPanel();

29.editorPanel.add(editor.getGUI());

30.content.add(editorPanel);

31.

229

32.displayPanel = new JPanel();

33.display = new JTextArea(10, 40);

34.display.setEditable(false);

35.displayPanel.add(display);

36.content.add(displayPanel);

37.

38.controlPanel = new JPanel();

39.update = new JButton("Update Item");

40.exit = new JButton("Exit");

41.controlPanel.add(update);

42.controlPanel.add(exit);

43.content.add(controlPanel);

44.

45.update.addActionListener(this);

46.exit.addActionListener(this);

48.mainFrame.addWindowListener(new WindowCloseManager());

49.mainFrame.pack();

50.mainFrame.setVisible(true);

51.}

52.

53.

54.public void actionPerformed(ActionEvent evt){

55.Object originator = evt.getSource();

56.if (originator == update){

57. updateItem();

58.}

59.else if (originator == exit){

60. exitApplication();

61.}

62.}

64.private class WindowCloseManager extends WindowAdapter{

65.public void windowClosing(WindowEvent evt){

66. exitApplication();

67.}

68.}

70.private void updateItem(){

71.editor.commitChanges();

72.display.setText(editor.toString());

73.}

74.

75.private void exitApplication(){

76.System.exit(0);

77.}

78.}

79.

Note that the Update Item button makes a call to the ItemEditor 's commitChanges method.

The RunPattern class runs this pattern by creating a Contact and an EditorGui object. The EditorGui constructor sets the ItemEditor for the example.

Example A.25 RunPattern.java

1.import javax.swing.JComponent;

2.import javax.swing.JFrame;

3.import java.awt.event.WindowAdapter;

4.import java.awt.event.WindowEvent;

7.public class RunPattern{

8.public static void main(String [] arguments){

9.System.out.println("Example for the FactoryMethod pattern");

10.System.out.println();

11.

12.System.out.println("Creating a Contact object");

13.System.out.println();

14.Contact someone = new Contact();

15.

16.System.out.println("Creating a GUI editor for the Contact");

17.System.out.println();

18.System.out.println("The GUI defined in the EditorGui class is a truly generic

editor.");

19.System.out.println("It accepts an argument of type ItemEditor, and delegates");

20.System.out.println(" all editing tasks to its ItemEditor and the associated GUI.");

230

21.System.out.println(" The getEditor() Factory Method is used to obtain the

ItemEditor");

22.System.out.println(" for the example.");

23.System.out.println();

24.System.out.println("Notice that the editor in the top portion of the GUI is,");

25.System.out.println(" in fact, returned by the ItemEditor belonging to the");

26.System.out.println(" Contact class, and has appropriate fields for that class.");

28.EditorGui runner = new EditorGui(someone.getEditor());

29.runner.createGui();

30.}

31.}

32.

 

 

Y

 

 

L

 

 

F

 

 

M

 

A

E

 

T

 

 

TEAM FLY PRESENTS

231