300 likes | 317 Views
Learn about graphical interfaces and the PowerBallMachine class through examples in Java programming. Explore Swing components and event handling.
E N D
User Interface The way in which user interacts with program Separates “what” program does from “how” user interacts with it Television Function: Adjust volume, channels, color, etc. Interface: Manual controls Universal Remote Automobile Function: Turn, accelerate, decelerate, stop Interface: Human driver Autonomous vehicle
Powerball Example • Example PowerBallMachine class based on Powerball lottery where person must correctly match 5 balls selected from collection of 55 balls. • PowerballMachine has single method called getOdds(int n, int k). getOdds computes chances of correctly selecting k balls from collection of size n. • Let’s look at two interfaces for our PowerBallMachine- a text based interface and a graphical interface. public class PowerBallMachine { public int getOdds(int n, int k) { int lotteryOdds = 1; for (int i = 1; i <=k; i++) { lotteryOdds = lotteryOdds * (n-i+1)/i; } return lotteryOdds; } }
Powerball- Console Interface public class PowerBallMain { public static void main(String args[]) { PowerBallMachine machine = new PowerBallMachine(); Scanner input = new Scanner(System.in); System.out.println("Enter number of balls to pick from: "); int n = input.nextInt(); System.out.println("How many balls do you want to draw? "); int k = input.nextInt(); System.out.println("Odds of winning are 1 in " + machine.getOdds(n, k)); } }
Basic GUI Components • Original (pre-Java 2) GUI components - heavyweight: • rely on local platform's windowing system • each heavyweight component has a peer that oversees interactions between component and local platform • result: platform-dependent appearance • Java 2's Swing GUI Components are lightweight: • written completely in Java • not "weighed down" by platform's GUI capabilities • not necessarily good for graphics • Pros and Cons: see http://dn.codegear.com/article/26970
Swing Components Frames Scroll Panes Panels Tabbed Panes Split Panes Sun’s Java Tutorial
Swing Components (cont.) Progress Bars Lists Buttons Combo Boxes Labels Text Boxes Menus Spinners Sliders Sun’s Java Tutorial
Displaying Swing Components in Window • To use Swing Components, must provide framework for displaying them • Most prevalent framework for displaying Swing Components is the Window • Most windows you will create are an instance of class JFrame or a subclass of JFrame • JFrame provides the basic attributes and behaviors of a window • title bar at the top of the window • buttons to minimize, maximize, and close the window
Constructing Window Containing Swing Components • Define xxxFrame class as extension of JFrame • For JFrame used to hold labeled text:// LabelFrame.java10public class LabelFrame extends JFrame11 {42 }//end class LabelFrame • Add class instance variable for desired Swing component 10public class LabelFrame extends JFrame11 {12 private JLabel label1;13 private JLabel label2; 42 }//end class LabelFrame
Constructing Window Containing Swing Components • Use class constructor to add component to frame 10 public class LabelFrame extends JFrame11 {12 private JLabel label1;13 private JLabel label2;17 public LabelFrame()//LabelFrame constructor18 { 19 super(“Testing JLabel”); //Creates bare JFrame20 setLayout( new FlowLayout());22 label1 = newJLabel(“Label with text”); 24 add( label1); //add label1 to JFrame41 }//end LabelFrame constructor42 }//end class LabelFrame
Creating and Displaying LabelFrame Window • Create test class which creates object of class LabelFrame, defines action upon window closure, sets window size, and makes it viewable 1// LabelTest.java3 import javax.swing.JFrame;45 public class LabelTest6 {7 public static void main( String args[] )8 {// create LabelFrame9 LabelFrame labelFrame = new LabelFrame( );10 labelFrame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );11 labelFrame.setSize(275, 180 );12 labelFrame.setVisible( true );13}// end main14}// end class LabelTest
Swing ComponentsInteract with your Program PowerballMachine getOdds(int n, int k)
Event Handling Object A Object B Object C Graphical User Interface Event Event Event Widget Registered Listeners Object A Object B Object C Event Listeners or Event Handlers
Creating & Sending Events GUI components that can change state, generate “events” when a change occurs JButtons – ActionEvent JTextField – ActionEvent JLists – ListSelectionEvent JCheckBox – ItemEvent plus many, many more... All have a method which allows objects to register as an event listener addxxxListener(xxxListener x);
Event Listeners/Handlers Objects become event listeners by implementing appropriate interface that allows them to register with GUI component that generates events Ex: JButton is a GUI component that generates events every time it is pressed JButton b = new JButton(“Button #1”); Generate ActionEvents addActionListener(ActionListener a); By virtue of being a JButton, b generates ActionEvents
Event Listeners/Handlers (cont.) Any object implementing ActionListener interface can register with JButton to be notified when button changes state (is pressed) public interface ActionListener { void actionPerformed(ActionEvent e); } public class MyObject implements ActionListener { ... public void actionPerformed(ActionEvent e) { System.out.println(“Don’t press the button!”); } } MyObject mo = new MyObject(); b.addActionListener(mo); By implementing the ActionListener interface, MyObject becomes an ActionListener Since mo is an ActionListener, it can register with JButton b
Button Example Let’s start with a very simple example of a Frame that contains two GUI components a button a label. When button is pressed, message displayed at console
GuiTest: JButton Example import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GuiTest { public static void main(String[] args) { JFrame j = new JFrame("Title"); j.setSize(275, 170); Container c = j.getContentPane(); c.setLayout(new FlowLayout()); JButton b = new JButton("I Believe"); b.addActionListener(new MyActionListener()); c.add(b); JLabel lab = new JLabel("Text and Graphics Label"); c.add(lab); j.setVisible(true); j.addWindowListener(new MyWindowAdapter()); } }
GuiTest: JButton Example (cont.) class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.out.println("Window closed...Exiting Program"); System.exit(0); } } class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button Pressed"); } }
GUITest Revisited Program works fine, but I want to change the structure so that we lay out GUI in constructor vice in main method. Along the way we’ll also Move ActionListener and WindowAdapter classes inside GuiTest class Get ride of JFrame created in main and make GuiTest the JFrame by having GuiTest extend JFrame Reason for doing this may not be clear right now since our GUI is extremely simple, but as they get more complicated these changes will help with scope issues and make it easier to add increasingly sophisticated behavior.
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GuiTest extends JFrame { private Container c; public GuiTest(String t) { super(t); setSize(275, 170); c = getContentPane(); c.setLayout(new FlowLayout()); JButton b = new JButton("I Believe"); b.addActionListener(new MyActionListener()); c.add(b); JLabel lab = new JLabel("Push the button!"); c.add(lab); setVisible(true); addWindowListener(new MyWindowAdapter()); } public static void main(String[] args) { GuiTest g = new GuiTest("GuiTest Title"); } } GuiTest extends JFrame • Compare this version to previous. Things to note: • Explicit definition of JFrame is gone. GuiTest extends JFrame so it is the JFrame. • Most of what was in main is now in GuiTest constructor. • Title for frame is passed via constructor using super.
class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.out.println("Window closed...Exiting Program"); System.exit(0); } } class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button Pressed"); } } GuiTest extends JFrame (cont.) • Compare this version to previous. Things to note: • Explicit definition of JFrame is gone. GuiTest extends JFrame so it is the JFrame. • Most of what was in main is now in GuiTest constructor. • Title for frame is passed via constructor using super.
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GuiTest extends JFrame { private Container c; public GuiTest(String t) { super(t); setSize(275, 170); c = getContentPane(); c.setLayout(new FlowLayout()); JButton b = new JButton("I Believe"); b.addActionListener(new MyActionListener()); c.add(b); JLabel lab = new JLabel("Push the button!"); c.add(lab); setVisible(true); addWindowListener(new MyWindowAdapter()); } public static void main(String[] args) { GuiTest g = new GuiTest("GuiTest Title"); } } GuiTest: Inner Classes
class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.out.println("Window closed...Exiting Program"); System.exit(0); } } class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button Pressed"); } } GuiTest: Inner Classes(cont.)
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GuiTest3 extends JFrame { private Container c; private int x = 0; JLabel lab; public GuiTest3(String t) { super(t); setSize(275, 170); c = getContentPane(); c.setLayout(new FlowLayout()); JButton b = new JButton("I Believe"); b.addActionListener(new MyActionListener()); c.add(b); lab = new JLabel("Push the button!"); c.add(lab); setVisible(true); } GuiTest: Count the button clicks
public static void main(String[] args) { GuiTest3 g = new GuiTest3("GuiTest Title"); g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { x++; if (x == 1) { lab.setText("First Time!"); System.out.println("Button pressed for the first time!"); } else if (x < 10) { lab.setText(x + " times."); System.out.println("Button Pressed " + x + " times."); } else { lab.setText("Enough already...stop!"); System.out.println("Button Pressed " + x + " times."); } } } GuiTest: Count the button clicks (cont.)
FlowLayout: Simplest Layout Manager • GuiTest( ) constructor from GuiTest example creates GUI component objects and attaches them to the JFrame: • GUI components are placed on JFrame left to right in the order in which attached to JFrame (FlowLayout). • Wrap to next line when edge reached. • Layout set before any components attached to JFrame • Other layout managers: • Border (N,S,E,W, Center) and, • Grid (like a 2-D array) • GridBagLayout (most flexible/complex layout manager)
GuiTest( ) Constructor that uses Flow Layout public GuiTest3(String t) { super(t); setSize(275, 170); c = getContentPane(); c.setLayout(new FlowLayout()); JButton b = new JButton("I Believe"); b.addActionListener(new MyActionListener()); c.add(b); lab = new JLabel("Push the button!"); c.add(lab); setVisible(true); } • GuiTest3( ) constructor creates and attaches GUI components to the user interface • c.add(b) adds component to contentPane as per layout manager.