380 likes | 484 Views
GUI Tutorial 1. A Bit of Philosophy on what to Teach. There are numerous libraries, frameworks, options Modern GUIs are often developed using XML (e.g., Android, XAML, etc.) My goals for 306: Understand event-driven programming in general Work with one object-oriented GUI library (Swing)
E N D
A Bit of Philosophy on what to Teach • There are numerous libraries, frameworks, options • Modern GUIs are often developed using XML (e.g., Android, XAML, etc.) • My goals for 306: • Understand event-driven programming in general • Work with one object-oriented GUI library (Swing) • Feel confident you can learn other toolkits as needed • Cover only the basics (e.g., there are many layout managers, but I’ll only cover a couple)
Topics in GUI Tutorial 1 • Event-driven programming • Layout managers • Text fields and labels • Responding to buttons • Simple dialogs • confirmation • message • simple input • JPanel • Borders • CheckBox and ComboBox
Event Programming • GUIs are under control of the user, not the program. This type of programming is referred to as event-driven. • Java programs react to a wide variety of user interface events – button pushes, mouse clicks, window manipulation, etc. • Program installs event listeners for events of interest • Need to know the event source– e.g., button, text box, window etc. • All listeners implement the particular interface for that type of event (e.g., button listeners must implement ActionListener)
FirstGUI Covers JFrame, BorderLayout, JTextField, JLabel, JButton, ActionListeners
Basic Strategy – very simple GUI • Create a JFrame (or JApplet) as the top-level container. Normally only 1 JFrame per application. • Define the components as instance variables (or possibly local variables) • In the constructor, allocate space for the components, add them to the JFrame (may call helper methods) • Main is usually very short: • call the constructor • set the default close operation • set visible true. No events yet…
Create a JFrame public class FirstGUI extends JFrame{ public static void main(String[] args) { FirstGUI gui = new FirstGUI(); gui.setVisible(true); } } • GUI displays… barely!
Use the constructor to configure it public FirstGUI() { // EXIT_ON_CLOSE is static int setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("My First GUI"); setSize(200, 100); } • set functions are defined because FirstGUI is-a JFrame
What’s a layout? • A layout manager determines how components will be arranged (order and size) • Layout managers enable programs to be more portable • The default layout manager for a JFrame is BorderLayout • The default layout manager for a JPanel (covered soon) is FlowLayout • Controlling the layout is not an important topic for this class. Suggested reading: http://www.developer.com/java/ent/article.php/630651/Swing-from-A-to-Z-Minimum-Maximum-and-Preferred-Sizes.htm
BorderLayout In a BorderLayout, outer components (N/S/E/W) are sized to their natural size, if possible. Any extra space is given to CENTER. NORTH EAST WEST CENTER SOUTH
Now let’s add components • JTextField – used to accept information, single line • Our JTextField will be an instance variable – because we want to access it from other methods later. • Our JLabel field will be local – only set up and add to GUI, don’t need to access or modify later public class FirstGUI extends JFrame { private JTextField name; private void createLayout() { JLabel nameLabel = new JLabel("Name"); name = new JTextField(20); add(nameLabel, BorderLayout.NORTH); add(name, BorderLayout.CENTER); } call createLayout from ctor only add 1 component/area
Basic Strategy – simple GUI w Events • Create a JFrame (or JApplet) as the top-level container. Normally only 1 JFrame per application. • Define the components as instance variables (or possibly local variables) • In the constructor or an initialization function, allocate space for the components, add them to the JFrame, do other JFrame set up (set default close operation, set size, etc.) • Write an event listener (can be anonymous or inner class) • Attach the event listener to the component • In main, call the constructor, set visible true. Main is usually very short.
Add a Button • In createLayout, define a button, allocate space, add to JFrame JButton nameButton = new JButton("OK"); add(nameButton, BorderLayout.SOUTH); • It displays… but no action yet
Create a listener • A class that responds to events must implement an interface named ActionListener • Remember that an interface: • Specifies methods that must be defined • Provides method signature (name, parameters) • Interface does not provide a method body – like pure virtual in C++. Method must be defined by implementing class. • Requires more libraries. NOTE: just importing java.awt.* does not provide access to java.awt.event.ActionEvent. You can think of it as a directory structure that doesn’t automatically include subdirectories. (that’s not really what happens…) import java.awt.event.*; actionPerformed Event Listener JButton
Simple action listener class • There are several syntax options for where the listener is defined. • We’ll define an inner class. • This should be in your source file, between public ClassName and the final }. • For now, put it just above your main method. • You can give the class any name, but it must implement ActionListener and you must have a method definition for actionPerformed. private class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button pressed"); } } COMMON ERRORS: misspelling actionPerformed, not making it public, not having ActionEvent as a parameter. Run it now… still nothing happens!
Add the listener to a button • Press the button…. nothing happens yet! Need to “attach” the listener to the buton. • Add the action listener to it (inside createLayout()). nameButton.addActionListener(new ButtonListener()); • But system.out.println is not very exciting
JOptionPane JOptionPane provides 3 quick options for dialogs: • Simple input • Simple message • Confirmation
Modifying the action listener • We can access the value of the JTextField because it’s an instance variable and our listener is an inner class • Put these lines in actionPerformed: String message = "Hello " + name.getText(); JOptionPane.showMessageDialog(null, message);
More JOptionPane options String numStr = JOptionPane.showInputDialog("Enter your age"); int num = Integer.parseInt(numStr); int yearsLeft = 100 - num; JOptionPane.showMessageDialog(null, "You have " + yearsLeft + " years left"); NOTE: This example is just to show all JOptionPane options – for most applications you would probably add an age field to the JFrame.
Final JOptionPane example • showConfirmDialog returns an enumerated type int ready = JOptionPane.showConfirmDialog(null, "Are you ready to continue?"); if (ready == JOptionPane.YES_OPTION) JOptionPane.showMessageDialog(null, "Here we go!"); else JOptionPane.showMessageDialog(null, "OK, we'll wait");
CarpoolGUI JPanel, FlowLayout, GridLayout, JComboBox, CheckBox, RadioButton, Font Quick Intro: Panel Communication
CarpoolGUI • Used to sign up for carpooling • Will show lots of GUI components • Creates a more complex layout using panels • We’ll start today, finish next time
JPanel • JPanel is a container to hold other components • A JPanel may be in its own class, or may be a variable inside another class • Which is best? Depends….
Panel Communication This is just a special case of message passing – common OO technique Main panel Control Panel
FlowLayout // default layout is flow JPanel panel = new JPanel(); panel.add(component); • Items displayed in order added • Fills horizontally, move to next line when not enough space for next field. FIELD-1 FIELD-2 FIELD-3 FLD-4 FLD-5 FLD-6
GridLayout JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new GridLayout(4, 3)); buttonPanel.add(button7); buttonPanel.add(button8); … can set 1 of these to 0, will expand as needed • 8 9 • 4 5 6 • 1 2 3 • 0 . CE
Nesting Panels JPanel keypadPanel = new JPanel(); keypadPanel.setLayout(new BorderLayout()); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new GridLayout(4, 3)); buttonPanel.add(button7); buttonPanel.add(button8); … keypadPanel.add(buttonPanel, BorderLayout.CENTER); JTextField display = new JTextField(); keypadPanel.add(display, BorderLayout.NORTH); 7 8 9 4 5 6 1 2 3 0 . CE
Get started: normal items in JFrame public class CarpoolGUI()extends JFrame { public CarpoolGUI() { setSize(new Dimension(400, 250)); setTitle("Let's carpool"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { CarpoolGUI gui = new CarpoolGUI(); gui.setVisible(true); } }
Create panel with combo boxes public class ToFromPanel extends JPanel { private JComboBox<String> toCity, fromCity; public ToFromPanel() { toCity = createCityCombo(); fromCity = createCityCombo(); } private JComboBox<String> createCityCombo() { JComboBox<String> combo = new JComboBox<String>(); combo.addItem("Golden"); combo.addItem("Boulder"); combo.addItem("Denver"); return combo; } } Don’t Repeat Yourself (DRY) We create a createCityCombo method to avoid repeating code.
Continue combo panel • Add to ToFromPanel constructor: JLabel fromLabel = new JLabel("From"); JLabel toLabel = new JLabel("To"); setLayout(new GridLayout(0, 2)); add(fromLabel); add(toLabel); add(fromCity); add(toCity); • Add to CarpoolGUI constructor: ToFromPanel tfPanel = new ToFromPanel(); add(tfPanel, BorderLayout.CENTER);
Create panel with radio buttons public class PreferencePanel extends JPanel { private JRadioButton smokeButton, noSmokeButton; public PreferencePanel() { // Create the buttons smokeButton = new JRadioButton("Smokes"); noSmokeButton = new JRadioButton("No smoke"); // Set no smoke as the default noSmokeButton.setSelected(true); // Add the buttons to the panel add(smokeButton); add(noSmokeButton); } }
Add the panel to the JFrame • In the JFrame constructor: PreferencePanel pPanel = new PreferencePanel(); add(pPanel, BorderLayout.EAST); • But it’s possible to click both! • Need a RadioGroup
Update Preference panel ButtonGroup group = new ButtonGroup(); group.add(smokeButton); group.add(noSmokeButton); setBorder(new TitledBorder (new EtchedBorder(), "Preferences")); • OK, but let’s get items in a column
We’ll use GridLayout setLayout(new GridLayout(2, 1));
Add a border • Add to the ToFromPanel constructor setBorder(new TitledBorder (new EtchedBorder(), "Location"));
CheckBox and Font public class WillDrivePanel extends JPanel { private JTextField name; private JCheckBox willDriveCB; public WillDrivePanel() { JLabel label = new JLabel("Name"); name = new JTextField(20); name.setFont(new Font("SansSerif", Font.BOLD, 12)); add(label); add(name); } } add to JFrame, of course (NORTH)
Add to JFrame WillDrivePanel wdPanel = new WillDrivePanel(); add(wdPanel, BorderLayout.NORTH);
Now the check box willDriveCB = new JCheckBox("Will drive"); add(willDriveCB);