- Forward


Discussion of Programming Assignment 4


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

BigPixelEditor
Back SMYC Forward
edu/jmu/cs/academics/bigpixel/gui/BigPixelEditor.java
 
SetBrushSize
Back SMYC Forward
edu/jmu/cs/academics/bigpixel/gui/actions/SetBrushSize.java
 
SetColor
Back SMYC Forward
edu/jmu/cs/academics/bigpixel/gui/actions/SetColor.java
 
ShowGrid
Back SMYC Forward
edu/jmu/cs/academics/bigpixel/gui/actions/ShowGrid.java
 
Close
Back SMYC Forward
edu/jmu/cs/academics/document/actions/Close.java
 
New
Back SMYC Forward
edu/jmu/cs/academics/document/actions/New.java
 
PrintImage
Back SMYC Forward
edu/jmu/cs/academics/gui/actions/PrintImage.java
 
ComponentPrinter
Back SMYC Forward
edu/jmu/cs/academics/io/ComponentPrinter.java
 
DelegatingPrintable
Back SMYC Forward
edu/jmu/cs/academics/io/DelegatingPrintable.java
 
Centralized/Decentralized Control of GUIs
Back SMYC Forward
  • What would the design look like if the control of setting the brush size, color, and grid visibility were centralized?
    • One Design: The BigPixelEditor would be an ActionListener for all of the JMenuItem objects.
    • Another Design: Another class would be an ActionListener for all of the JMenuItem objects.
    • Expand
  • What is the main advantage of using decentralized control (i.e., Action objects)?
    • Increased cohesion
    • Expand
  • Are we using the Strategy Pattern or the Command Pattern (as they are normally described)?
    • The Command Pattern because the work is delegated to the operand (i.e., the BigPixelEditor)
    • Expand
Decentralized Control and the Singleton Pattern
Back SMYC Forward
  • What class currently constructs the Action objects?
    • The main class
      Expand
  • Suppose we added a toolbar and context menu that could be used to initiate these tasks, would you have multiple instances of each Action object?
    • No
      Expand
  • Would it cause failures if you did?
    • Not given the current implementation
      Expand
  • Should we use the Singleton Pattern to avoid potential failures?
    • Why not?
      Expand
Similar (but not Duplicate) Functionality
Back SMYC Forward
  • What similar method (other than ActionPerformed) is in each of the Action objects that set the color, brush size, and grid visibility?
    • updateEditor()
      Expand
  • Is the code identical?
    • No, each Action calls a different method in the operand
      Expand
  • What interface could we add to the design?
    • A BigPixelAction<T> interface with an updateEditor(T newValue) method
      Expand
Similar (but not Duplicate) Functionality (cont.)
Back SMYC Forward
public interface BigPixelAction<T> { public abstract void updateEditor(T newValue); }
public class SetBrushSize extends AbstractLocalizedAction implements BigPixelAction<Integer> { // Other code public void updateEditor(final Integer size) { if (size > 0) editor.setBrushSize(size); } }
Similar (but not Duplicate) Functionality (cont.)
Back SMYC Forward
  • Reminder: What is the most important benefit of interfaces?
    • They provide the ability to pass polymorphic objects
      Expand
  • Does this BigPixelAction interface add anything to the design?
    • Nothing other than semantic information, which could be achieved using an empty interface
      Expand
Similar (but not Duplicate) Code
Back SMYC Forward
  • Reminder: How do you get rid of duplicate code across multiple classes?
    • Create a parent (perhaps abstract) class
      Expand
  • Could we add an AbstractBigPixelAction that includes an implementation of updateEditor()?
    • Not in an obvious way, since each updateEditor() method is passed parameters of different type and invokes different methods in the operand
      Expand
  • Could we add use a "bean-like" approach (i.e., use Map objects to hold attributes and refer to them with a key)?
    • Let's see...
      Expand
Similar (but not Duplicate) Code (cont.)
Back SMYC Forward
The Abstract Class
public abstract class BigPixelAction<T> extends AbstractLocalizedAction { protected BigPixelEditor editor; public BigPixelAction(String name, BigPixelEditor editor) { super(name); this.editor = editor; } public void updateEditor(String attribute, T newValue) { editor.setAttribute(attribute, newValue); // Can't check the size } }
Similar (but not Duplicate) Code (cont.)
Back SMYC Forward
One of the Concrete Specializations
public class SetBrushSize extends BigPixelAction<Integer> { // Other code public void actionPerformed(final ActionEvent ae) { Integer response = (Integer) JOptionPane.showInputDialog(editor, strings.getString(WHAT_SIZE_BRUSH_DO_YOU_WANT_TO_USE), strings.getString(SET_BRUSH_SIZE), JOptionPane.QUESTION_MESSAGE, null, SIZES, SIZES[8]); if (response != null) updateEditor(BigPixelEditor.BRUSH_SIZE, response); } }
Similar (but not Duplicate) Code (cont.)
Back SMYC Forward
The Operand
public class BigPixelEditor extends GridComponent implements MouseListener, PropertyChangeListener { private Map<String, Color> colorAttributes; private Map<String, Integer> intAttributes; // Other code public void setAttribute(final String name, final Integer newValue) { intAttributes.put(name, newValue); } public void setAttribute(final String attribute, final Color newValue) { colorAttributes.put(attribute, newValue); } }
Similar (but not Duplicate) Code (cont.)
Back SMYC Forward
  • Is It Cool?
    • Yes
      Expand
  • Does It Work?
    • The body of BigPixelAction.updateEditor() won't compile because T (the type of newValue) isn't bound so editor.setAttribute(attribute, newValue) doesn't match any methods in BigPixelEditor
      Expand
    • It doesn't allow for the validation of the parameters (e.g., you can't ensure that the brushSize is greater than 0 or that the currentColor isn't null)
      Expand
Using Maps for "Attributes"
Back SMYC Forward
  • Advantage:
    • "Attributes" can be dynamically added to an object (not a class)
      Expand
  • Disadvantage:
    • Existence can't be checked at compile-time
      Expand
  • Relationship to Properties/Configurations:
    • They are being loaded at run-time (e.g., from a file) so, even if the keys don't change over time, they need to be handled dynamically at some point in the process
      Expand
Identical Attributes Across Classes
Back SMYC Forward
  • What attribute do all of the Action objects that control the brush size, current color, and grid visibility have?
    • The operand (i.e., the BigPixelEditor named editor)
      Expand
  • Should we add an AbstractBixPixelAction to the design just for this?
    • Probably
      Expand
Centralized/Decentralized Control of GUIs Revisited
Back SMYC Forward
  • Is the control of drawing a BigPixelElement currently centralized or decentralized?
    • Centralized in the BigPixelEditor (which realizes the MouseListener interface?
      Expand
  • What would be involved in adding the following functionality given the current design?
    • Click-and-Drag support to select the size of the BigPixelElement
    • Deleting a cell in a BigPixelElement
    • Deleting a BigPixelElement
    • Undo/Redo Support
  • Should the control of drawing a BigPixelElement be centralized or decentralized?
    • Decentralized
      Expand
Implementing an Interface vs. Wrapping
Back SMYC Forward
  • Why doesn't BigPixelEditor implement the Printable interface?
    • It could, but everything that needs to be Printable would include identical code
      Expand
  • Why not create a parent class (abstract or otherwise)?
    • Because BigPixelEditor (and any other such classes) will need to specialize a JComponent of some unknown and varying kind
      Expand
  • Why not use the decorator pattern?
    • Because the functionality only needs to be added "momentarily" (i.e., for the amount of time it takes to print, during which it needn't be polymorphic).
      Expand
  • Implications?
    • Use a wrapper (i.e., the DelegatingPrintable class)
      Expand
Printing
Back SMYC Forward
  • What makes it easy to print a BigPixelDocument?
    • We have a BigPixelEditor that renders a BigPixelDocument in a way that is appropriate for printing on a single page (after scaling and translation)
      Expand
  • Would this technique work for word processing document?
    • No!
      Expand
  • What do we need instead?
    • A JComponent that renders the document as it would be rendered when printed
      Expand
  • How can we achieve that functionality?
    • Create a JComponent that renders a "preview"
      Expand
There's Always More to Learn
Back -