josh bloch charlie garrod
play

Josh Bloch Charlie Garrod 17-214 1 Administrivia Reading due - PowerPoint PPT Presentation

Principles of Software Construction: Objects, Design, and Concurrency Part 2: Design case studies Design case study: Java Swing Josh Bloch Charlie Garrod 17-214 1 Administrivia Reading due today: UML and Patterns 26.1 and 26.4


  1. Principles of Software Construction: Objects, Design, and Concurrency Part 2: Design case studies Design case study: Java Swing Josh Bloch Charlie Garrod 17-214 1

  2. Administrivia • Reading due today: UML and Patterns 26.1 and 26.4 • Homework 4b due Thursday, October 22 nd 17-214 2

  3. Key concepts from Thursday • Observer design pattern • Introduction to concurrency – Not enough synchronization: safety failure – Too much synchronization: liveness failure • Event-based programming • Introduction to GUIs 17-214 3

  4. Today • Finish introduction to GUIs • Design case study: GUI potpourri – Strategy – Template method – Observer – Composite – Decorator – Adapter – Façade – Command – Chain of responsibility • Design discussion: Decoupling your game from your GUI 17-214 4

  5. Examples of events in GUIs • User clicks a button, presses a key • User selects an item from a list, an item from a menu • Mouse hovers over a widget, focus changes • Scrolling, mouse wheel turned • Resizing a window, hiding a window • Drag and drop • A packet arrives from a web service, connection drops, … • System shutdown, … 17-214 5

  6. An event-based GUI with a GUI framework • Setup phase – Describe how the GUI window should look – Register observers to handle events Application • Execution event— – Framework gets events from OS, processes events drawing mouse, key, commands redraw, … • Your code is mostly just event handlers GUI Framework get next event event OS See edu.cmu.cs.cs214.rec06.alarmclock.AlarmWindow… 17-214 6

  7. GUI frameworks in Java • AWT – obsolete except as a part of Swing • Swing – widely used • SWT – Little used outside of Eclipse • JavaFX – Billed as a replacement for Swing – Released 2008 – never gained traction • A bunch of modern (web & mobile) frameworks – e.g., Android 17-214 7

  8. GUI programming is inherently multi-threaded • Swing Event Dispatch Thread (EDT) handles all GUI events – Mouse events, keyboard events, timer events, etc. • No other time-consuming activity allowed on the EDT – Violating this rule can cause liveness failures 17-214 8

  9. Ensuring all GUI activity is on the EDT • Never make a Swing call from any other thread – “Swing calls” include Swing constructors • If not on EDT, make Swing calls with invokeLater : public static void main(String[] args) { SwingUtilities.invokeLater(() -> new Test().setVisible(true)); } 17-214 9

  10. Callbacks execute on the EDT • You are a guest on the Event Dispatch Thread! – Don’t abuse the privilege • If > a few ms of work to do, do it off the EDT – javax.swing.SwingWorker designed for this purpose 17-214 10

  11. Components of a Swing application JFrame JPanel JButton JTextField … 17-214 11

  12. Swing has many widgets • JLabel • JTextField • JButton • JTextArea • JCheckBox • JList • JChoice • JScrollBar • … and more • JRadioButton • JFrame is the Swing Window • JPanel (a.k.a. a pane) is the container to which you add your components (or other containers) 17-214 12

  13. To create a simple Swing application • Make a window (a JFrame ) • Make a container (a JPanel ) – Put it in the window • Add components (buttons, boxes, etc.) to the container – Use layouts to control positioning – Set up observers (a.k.a. listeners) to respond to events – Optionally, write custom widgets with application-specific display logic • Set up the window to display the container • Then wait for events to arrive… 17-214 13

  14. E.g., creating a button // public static void main… JFrame window = … JPanel panel = new JPanel(); panel to hold window.setContentPane(panel); the button JButton button = new JButton("Click me"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Button clicked"); } }); panel.add(button); window.setVisible(true); 17-214 14

  15. E.g., creating a button // public static void main… JFrame window = … JPanel panel = new JPanel(); panel to hold window.setContentPane(panel); the button JButton button = new JButton("Click me"); button.addActionListener( (e) -> System.out.println("Button clicked") ); panel.add(button); window.setVisible(true); 17-214 15

  16. The javax.swing.ActionListener • Listeners are objects with callback functions – Can be registered to handle events on widgets – All registered widgets are called if event occurs interface ActionListener { void actionPerformed(ActionEvent e); } class ActionEvent { int when; String actionCommand; int modifiers; Object source(); int id; … } 17-214 16

  17. Button design discussion • Button implementation should be reusable but customizable – Different button label, different event-handling • Must decouple button's action from the button itself • Listeners are separate independent objects – A single button can have multiple listeners – Multiple buttons can share the same listener 17-214 17

  18. Swing has many event listener interfaces • ActionListener • MouseListener • AdjustmentListener • TreeExpansionListener • FocusListener • TextListener • ItemListener • WindowListener • KeyListener • … class ActionEvent { int when; String actionCommand; int modifiers; Object source(); int id; … interface ActionListener { } void actionPerformed(ActionEvent e); } 17-214 18

  19. Today • Finish introduction to GUIs • Design case study: GUI potpourri – Strategy – Template method – Observer – Composite – Decorator – Adapter – Façade – Command – Chain of responsibility • Design discussion: Decoupling your game from your GUI 17-214 19

  20. The decorator pattern abounds 17-214 20

  21. The decorator pattern abounds UML from https://medium.com/@dholnessii/structural-design-patterns-decorator-30f5a8c106a5 17-214 21

  22. Swing layouts The simplest, and default, layout. Wraps around when out of space. Like FlowLayout, but no wrapping More sophisticated layout managers see http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html 17-214 22

  23. A naïve hard-coded implementation class JPanel { protected void doLayout() { switch(getLayoutType()) { case BOX_LAYOUT: adjustSizeBox(); break; case BORDER_LAYOUT: adjustSizeBorder(); break; ... } } private adjustSizeBox() { … } } • A new layout would require changing or overriding JPanel 17-214 23

  24. A better solution: delegate the layout responsibilities • Layout classes, e.g.: contentPane.setLayout(new FlowLayout()); contentPane.setLayout(new GridLayout(4,2)); • Similarly, there are border classes to draw the borders, e.g.: contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 17-214 24

  25. Another GUI design challenge: nesting containers • A JFrame contains a JPanel , which contains a JPanel (and/or other widgets), which contains a JPanel (and/or other widgets), which contains… 17-214 25

  26. The composite pattern • Problem: Collection of objects has behavior similar to the individual objects • Solution: Have collection of objects and individual objects implement the same interface • Consequences: – Client code can treat collection as if it were an individual object – Easier to add new object types – Design might become too general, interface insufficiently useful 17-214 26

  27. Another composite pattern example public interface Expression { double eval(); // Returns value } public class BinaryOperationExpression implements Expression { public BinaryOperationExpression(BinaryOperator operator, Expression operand1, Expression operand2); } public class NumberExpression implements Expression { public NumberExpression(double number); } 17-214 27

  28. Recall: Creating a button //static public void main… JFrame window = … JPanel panel = new JPanel(); window.setContentPane(panel); JButton button = new JButton("Click me"); button.addActionListener( (e) -> { System.out.println("Button clicked"); }); panel.add(button); window.setVisible(true); 17-214 28

  29. An alternative button class MyButton extends JButton { public MyButton() { super("Click me"); } @Override protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); System.out.println("Button clicked"); } } //static public void main… JFrame window = … JPanel panel = new JPanel(); window.setContentPane(panel); panel.add(new MyButton()); window.setVisible(true); 17-214 29

  30. Discussion: Command vs. template method patterns //static public void main… JFrame window = … JPanel panel = new JPanel(); window.setContentPane(panel); JButton button = new JButton(“Click me”); button.addActionListener( (e) -> { System.out.println("Button clicked"); }); class MyButton extends JButton { panel.add(button); public MyButton() { super(“Click me”); } @Override window.setVisible(true); protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); System.out.println("Button clicked"); } } … 17-214 30

  31. Better use of template method: partial customization JComponent: 17-214 31

  32. Event propagation and deep container hierarchies 17-214 32

  33. Event propagation and deep container hierarchies 17-214 33

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend