====== Inheritance and GUIs ====== ---- Quoting from a [[http://www.leepoint.net/JavaBasics/gui/gui-commentary/guicom-10-whygui.html|commentary on teaching GUIs]]: "Although inheritance is very important to understand, it isn't used that often. One of the few places where it is used to great advantage is in GUIs. The GUI system can and should be used as a real, not contrived, example of inheritance." ---- ===== Overview of GUI Skills to Learn ===== {{http://www.leepoint.net/JavaBasics/gui/gui_overview.png}} ==== Read-Compute-Write Versus Event-Driven Programming ==== * Read-compute-write. * Most programmers start with a common idea for programming: read input data, process the input data, write the output data. * This is often be done in a loop to process more than one set of input data. * The essential mindset is that the programmer is in control at all times. * This is a very useful paradigm, but GUI programming requires you to change your thinking, and to give up this feeling of total control. * Giving up control - Event-driven programming. * The GUI programming style is referred to as __event-driven__ programming. * In this style of programming you set up the GUI and initialize things. * It appears that the program just stops and sits there doing nothing. * There is no input loop; your program isn't trying to read from the user. * You, the programmer, have to learn to give up control in two ways. * Your program gives control to the GUI system, * and you only get control back when your __listeners__ are called * At an even higher level, your GUI program gives control to the user. * It's the user who selects which of your methods to call by their choice of buttons to click on, menu items to select, etc. * Listeners * When the user clicks a button (or uses another GUI component), an event is sent to a //listener// method. * Your job as a programmer is to write a //listener// method for each component in your GUI. * It's the user, not the programmer, who has control by indirectly choosing methods in your program to execute by interacting with GUI components. ---- ==== GUIs and OOP ==== * See MyFrameI.java - Java GUI example #2, a simple GUI frame example that uses inheritance * This is the Object-Oriented Programming way -- when you want to take an existing class and "specialize" it or "extend" it by adding your own content and behavior, create a subclass of it, adding what you want. * Your new subclass still has all the capabilities of its superclass, plus what you add. * //Build the GUI in the constructor.// * The //JFrame// is built entirely in the constructor. * You should use this style. * //main()// method in //JFrame// subclass * It's common to put the //main()// method in the //JFrame// subclass, but that can seem confusing at first because //main()// builds an object of the class that it's sitting in. * Because it's static, //main()// can be in any class, but the most common location is in the //JFrame// subclass. * See TinyWindow4.java - create a window with a JLabel. * Be sure to read the **NOTES** in this source file. ---- ==== GUIs and Listeners ==== === Example: Dog years (w/ no listener) === * We'll build a GUI to convert a dog's age into an "equivalent" human age. * The logic of the problem (multiplying by 7) is trivial so that we can concentrate on building the GUI. * Build GUI first, then add a Listener method * See DogYears.java - Initial source code for DogYears without a listener * Be sure to read the **NOTES** in this source file. === Complete steps to create a GUI === * Beyond creating a JFrame subclass, setting the title, and making it visible. == 1 - Create and initialize components == * The DogYears example uses labels (JLabel), text fields (JTextField), and a button (JButton). * Create components that are used in the GUI. * Some of them may already have been created in instance variable declarations, and others may be created as local variables. * Additional characteristics should be set. == 2 - Create content pane and set its layout == * There are two things you can add to a window - a menu bar and a content pane (typically using a JPanel) that holds all the components. * Every content pane has a layout that tells how to position and size the components. * You don't have to specify the pixel position and size of each component; it's the layout's job to do that for you. * DogYears uses FlowLayout (simple layout that arranges the components left-to-right). == 3 - Add components to content pane == * After you have a panel and set its layout, add each component to it. == 4 - Set window characteristics and pack it == * The //pack()// method call tells the content pane that you're finished adding components, and that it can now apply the layout. === Example: Dog years (with listener) === * All GUI systems, not just Java, call a method when the user does something that demands the program's attention, e.g. clicking a button. * The details of the connection between the GUI component and the called method vary from language to language. * Java uses a pure object-oriented approach to implementing what is called //listeners//. * There are several kinds of listeners in Java, depending on what the user does, but the most common is called an action listener, which is used with buttons, menu items, etc. * An action listener is added to the button in the example below with the following statement. convertBtn.addActionListener(new ConvertBtnListener()); * //ActionListener// programming interface. * Note: Java //Interfaces// will be covered soon. * An action listener is an object that implements the //ActionListener// programming interface. * The //ActionListener// interface requires that one method, //actionPerformed//, be defined. * Listener classes are usually defined as inner classes (classes inside other classes). * In the //DogYears// example below you will see that objects of the class //ConvertBtnListener// can be used as action listeners because the class implements //ActionListener//. class ConvertBtnListener implements ActionListener * The //actionPerformed// method in this class must be able to get and set the values in the text fields or other input and output areas of the GUI. * A simple, common solution is to define this listener class inside the JFrame subclass. * Any method inside an inner class can refer to instance variables in the outer class. * See DogYearsListen.java - Final source code for DogYears with listener * Be sure to read the **NOTES** in this source file. * Compile this program and look at the class files that result. * You should see //DogYearsListen.class// and //DogYearsListen$ConvertBtnListener.class// (the compiled inner class). ----