Graphical User Interfaces are Trees CS 1316 Representing

  • Slides: 40
Download presentation
Graphical User Interfaces are Trees CS 1316: Representing Structure and Behavior

Graphical User Interfaces are Trees CS 1316: Representing Structure and Behavior

Story l Building a Graphical User Interface in Java • Adding pieces to a

Story l Building a Graphical User Interface in Java • Adding pieces to a JFrame • Buttons, panels, etc. l Constructing a GUI is building a tree Layout managers l Making out GUIs do something l Building a musical instrument l • Layout managers are GUI tree renderers • Listeners

Old style Java: Abstract Window Toolkit - AWT l Original Graphical User Interface (GUI)

Old style Java: Abstract Window Toolkit - AWT l Original Graphical User Interface (GUI) Classes • • Container Objects • • • Frame - Main window with title and border. Panel - groups components Canvas - create custom components Input and Output Classes • • • Label - not editable text Button - pushing fires an event • Checkboxes and Radio Buttons Text. Field - input and output of text Text. Area - input and output of multiple lines of text List - Select one or more items from a displayed list Choice - Select one from a drop down list

Swing - javax. swing l l l Replacements for most AWT components • •

Swing - javax. swing l l l Replacements for most AWT components • • • JButton - Button (images and text) JFrame - Frame (main window) JPanel – Panel (container) New GUI components • • • Trees - JTree Split pane - JSplit. Pane Table - JTable Supports multiple looks and feels • Java - also called metal, Windows, Mac, Motif

Swing Top-Level Containers l JFrame - main window with title, maybe a menu bar,

Swing Top-Level Containers l JFrame - main window with title, maybe a menu bar, and the ability to minimize, maximize, and close the window l JApplet - main window for an applet. Inherits from java. applet. Applet l JDialog – pop-up window for simple communication with the user • Like the JFile. Chooser

Working with a JFrame l Pass the title when you create it JFrame frame

Working with a JFrame l Pass the title when you create it JFrame frame = new JFrame("Frame. Demo"); l Add components to the content pane JLabel label = new JLabel("Hello World"); frame. get. Content. Pane(). add(label, Border. Layout. CENTER); l Set the size of the JFrame frame. pack(); // as big as needs to be to display contents l Display the JFrame frame. set. Visible(true); // display the frame

JFrame Options l When creating a GUI application • Have your main class inherit

JFrame Options l When creating a GUI application • Have your main class inherit from JFrame • Or have your main class inherit from JPanel • So it is a JFrame • And create a JFrame in the main method • Create the main class object • Add the main class object to the content pane of the JFrame l If your class inherits from JPanel • It can be reused in another application • Even an applet

GUITree Class /** * A GUI that has various components in it, to demonstrate

GUITree Class /** * A GUI that has various components in it, to demonstrate * UI components and layout managers (rendering) **/ import javax. swing. *; // Need this to reach Swing components public class GUItree extends JFrame { public GUItree(){ super("GUI Tree Example"); /* Put in a panel with a label in it */ JPanel panel 1 = new JPanel(); this. get. Content. Pane(). add(panel 1); JLabel label = new JLabel("This is panel 1!"); panel 1. add(label); /* Put in another panel with two buttons in it JPanel panel 2 = new JPanel(); this. get. Content. Pane(). add(panel 2); JButton button 1 = new JButton("Make a sound"); panel 2. add(button 1); JButton button 2 = new JButton("Make a picture"); panel 2. add(button 2); */ Welcome to Dr. Java. > GUItree gt = new GUItree(); this. pack(); this. set. Visible(true); } }

Whole GUITree public GUItree(){ super("GUI Tree Example"); /* Put in a panel with a

Whole GUITree public GUItree(){ super("GUI Tree Example"); /* Put in a panel with a label in it */ JPanel panel 1 = new JPanel(); this. get. Content. Pane(). add(panel 1); JLabel label = new JLabel("This is panel 1!"); panel 1. add(label); /* Put in another panel with two buttons in it */ JPanel panel 2 = new JPanel(); this. get. Content. Pane(). add(panel 2); JButton button 1 = new JButton("Make a sound"); panel 2. add(button 1); JButton button 2 = new JButton("Make a picture"); panel 2. add(button 2); this. pack(); this. set. Visible(true); }

Where’d panel 1 go? l It’s there, but the current rendering is smashing it

Where’d panel 1 go? l It’s there, but the current rendering is smashing it all together.

GUItree is a tree JFrame JPanel JLabel “This is panel 1!” JPanel JButton “Make

GUItree is a tree JFrame JPanel JLabel “This is panel 1!” JPanel JButton “Make a sound” JButton “Make a picture”

Layout Managers are renderers l How are the components assigned a position and size?

Layout Managers are renderers l How are the components assigned a position and size? • set. Layout(null) - the programmer must give all components a size and position • set. Bounds(top. Left. X, top. Left. Y, width, height); l Better: Use a Layout Manager! • Arranges the components in a container and sets their • • size as well Handles when the main window is resized The programmer just adds the components to the container

Layouts - Flow, Border, Grid l Flow Layout - left to right, no extra

Layouts - Flow, Border, Grid l Flow Layout - left to right, no extra space l Border Layout - Center item gets extra space l Grid Layout - same size components

Flowed GUITree /** * A GUI that has various components in it, to demonstrate

Flowed GUITree /** * A GUI that has various components in it, to demonstrate * UI components and layout managers (rendering) **/ import javax. swing. *; // Need this to reach Swing components import java. awt. *; // Need this to reach Flow. Layout public class GUItree. Flowed extends JFrame { public GUItree. Flowed(){ super("GUI Tree Flowed Example"); this. get. Content. Pane(). set. Layout(new Flow. Layout()); /* Put in a panel with a label in it */ JPanel panel 1 = new JPanel(); this. get. Content. Pane(). add(panel 1); JLabel label = new JLabel("This is panel 1!"); panel 1. add(label); > GUItree. Flowed gtf = new GUItree. Flowed(); /* Put in another panel with two buttons in it */ JPanel panel 2 = new JPanel(); this. get. Content. Pane(). add(panel 2); JButton button 1 = new JButton("Make a sound"); panel 2. add(button 1); JButton button 2 = new JButton("Make a picture"); panel 2. add(button 2); this. pack(); this. set. Visible(true); }

Automatically reflows when resized

Automatically reflows when resized

Bordered GUItree /** * A GUI that has various components in it, to demonstrate

Bordered GUItree /** * A GUI that has various components in it, to demonstrate * UI components and layout managers (rendering) **/ import javax. swing. *; // Need this to reach Swing components import java. awt. *; // Need this to reach Border. Layout public class GUItree. Bordered extends JFrame { public GUItree. Bordered(){ super("GUI Tree Bordered Example"); this. get. Content. Pane(). set. Layout(new Border. Layout()); /* Put in a panel with a label in it */ JPanel panel 1 = new JPanel(); this. get. Content. Pane(). add(panel 1, Border. Layout. NORTH); JLabel label = new JLabel("This is panel 1!"); panel 1. add(label); > GUItree. Bordered gtb = new GUItree. Bordered(); /* Put in another panel with two buttons in it */ JPanel panel 2 = new JPanel(); this. get. Content. Pane(). add(panel 2, Border. Layout. SOUTH); JButton button 1 = new JButton("Make a sound"); panel 2. add(button 1); JButton button 2 = new JButton("Make a picture"); panel 2. add(button 2); this. pack(); this. set. Visible(true); } }

Resizing now follows borders

Resizing now follows borders

Other Layouts - None, Grid. Bag, Card l None (null) - programmer specified l

Other Layouts - None, Grid. Bag, Card l None (null) - programmer specified l Grid. Bag - flexible grid l Card - one card shown at a time

Box. Layout –javax. swing l l Two types • • Can use rigid. Areas

Box. Layout –javax. swing l l Two types • • Can use rigid. Areas to leave a set amount of space between components • l Horizontal - Box. Layout. X_AXIS Vertical - Box. Layout. Y_AXIS Box. create. Rigid. Area(new Dimension(0, 5))); Can use horizontal and/or vertical glue to take up extra space • Box. create. Horizontal. Glue());

Boxed GUItree /** * A GUI that has various components in it, to demonstrate

Boxed GUItree /** * A GUI that has various components in it, to demonstrate * UI components and layout managers (rendering) **/ import javax. swing. *; // Need this to reach Swing components public class GUItree. Boxed extends JFrame { public GUItree. Boxed(){ super("GUI Tree Boxed Example"); this. get. Content. Pane(). set. Layout(new Box. Layout(this. get. Content. Pane(), Box. Layout. Y_AXIS)); /* Put in a panel with a label in it */ JPanel panel 1 = new JPanel(); this. get. Content. Pane(). add(panel 1); JLabel label = new JLabel("This is panel 1!"); panel 1. add(label); Box. Layout is weird —it takes the paneas an input, and whether you want vertical or horizontal (Y or X_AXIS) “boxing” /* Put in another panel with two buttons in it */ JPanel panel 2 = new JPanel(); this. get. Content. Pane(). add(panel 2); JButton button 1 = new JButton("Make a sound"); panel 2. add(button 1); JButton button 2 = new JButton("Make a picture"); panel 2. add(button 2); this. pack(); this. set. Visible(true); } }

Differs in resizing behavior: It’s all in boxes (not borders)

Differs in resizing behavior: It’s all in boxes (not borders)

Which Layout to Use? l An applet or application can have multiple panels (JPanel)

Which Layout to Use? l An applet or application can have multiple panels (JPanel) and have a different layout in each panel. • l l Panels can be inside of other panels. If you want components to not use extra space and stay centered then use Flow. Layout() Or use Border. Layout and put one component that uses all extra space in the center. Use a Box and line up components vertically or horizontally For the most control use null layout. • Much like Layered. Scene. Element!

Nested Panel Example l Often an application uses a Border. Layout • • Main

Nested Panel Example l Often an application uses a Border. Layout • • Main panel in Center Other panels in North, South, West, and East as needed • l Using Flow. Layout or Box In the application at right • • The main panel is in the center The button panel is in the north • Using Flow. Layout

Events l l An event is an object that represents an action: • •

Events l l An event is an object that represents an action: • • • user clicks the mouse user presses a key on the keyboard user closes a window In Swing, objects add or implement listeners for events. • • Listeners are interfaces. Interfaces are not classes: They define functionality that other classes implement. • It’s a contract that certain functionality will be provided.

Events and Listeners l l Say you want to know when your favorite band

Events and Listeners l l Say you want to know when your favorite band will be giving a tour in your city You might sign-up to be notified and give your email address • l Your name and e-mail is added to a list When the event is scheduled in your city • You will be notified via email that the tour is coming

Events and Listeners

Events and Listeners

Adapters l An adapter is an abstract class that provides empty implementations for a

Adapters l An adapter is an abstract class that provides empty implementations for a listener interface. • You can inherit from an adapter and only override the methods you want to handle. class My. Mouse. Adapter extends Mouse. Adapter { /** Method to handle the click of a mouse */ public void mouse. Clicked(Mouse. Event e) {…} }

Named Inner Classes l In Swing, you can use inner classes which are classes

Named Inner Classes l In Swing, you can use inner classes which are classes declared inside another class. public class Class. Name { attributes constructors methods // named inner class My. Mouse. Adapter extends Mouse. Adapter { methods } }

Anonymous Inner Classes l You can create a new listener in place with an

Anonymous Inner Classes l You can create a new listener in place with an anonymous inner class b. add. Focus. Listener(new Focus. Listener () { public void focus. Gained (Focus. Event evt) { … } public void focus. Lost(Focus. Event evt) { … } });

Interactive GUItree: Starting out /** * A GUI that has various components in it,

Interactive GUItree: Starting out /** * A GUI that has various components in it, to demonstrate * UI components and layout managers (rendering). * Now with Interactivity! **/ import javax. swing. *; // Need this to reach Swing components import java. awt. *; // Need this to reach Flow. Layout import java. awt. event. *; // Need this for listeners and events public class GUItree. Interactive extends JFrame { public GUItree. Interactive(){ super("GUI Tree Interactive Example"); File. Chooser. set. Media. Path("D: /cs 1316/mediasources/"); //CHANGE ME! this. get. Content. Pane(). set. Layout(new Flow. Layout()); /* Put in a panel with a label in it */ JPanel panel 1 = new JPanel(); this. get. Content. Pane(). add(panel 1); JLabel label = new JLabel("This is panel 1!"); panel 1. add(label);

Interactive GUItree: First button /* Put in another panel with two buttons in it

Interactive GUItree: First button /* Put in another panel with two buttons in it */ JPanel panel 2 = new JPanel(); this. get. Content. Pane(). add(panel 2); JButton button 1 = new JButton("Make a sound"); button 1. add. Action. Listener( new Action. Listener() { // Here's the listener // Here's the method we're overriding public void action. Performed(Action. Event e) { Sound s = new Sound(File. Chooser. get. Media. Path("warble-h. wav")); s. play(); } } ); panel 2. add(button 1);

Interactive GUItree: Second button JButton button 2 = new JButton("Make a picture"); button 2.

Interactive GUItree: Second button JButton button 2 = new JButton("Make a picture"); button 2. add. Action. Listener( new Action. Listener() { // Here's the listener // Here's the method we're overriding public void action. Performed(Action. Event e) { Picture p = new Picture(File. Chooser. get. Media. Path("shops. jpg")); p. show(); } } ); An inner class can access panel 2. add(button 2); this. pack(); this. set. Visible(true); } } instance variables of the outer class, but not local variables of the method.

Example: A Rhythm Constructing Tool l Take a name of a sound to add

Example: A Rhythm Constructing Tool l Take a name of a sound to add to a root l Play the result • Weave a number of times • Repeat a number times

Building the Rhythm. Tool class /** * A Rhythm-constructing tool **/ import javax. swing.

Building the Rhythm. Tool class /** * A Rhythm-constructing tool **/ import javax. swing. *; // Need this to reach Swing components import java. awt. *; // Need this to reach Flow. Layout import java. awt. event. *; // Need this for listeners and events public class Rhythm. Tool extends JFrame { Each of the values that we’ll access from inside the listeners must be declared as instance variables (fields) of the tools. /* Base of sound that we're creating */ public Sound. Element root; /* Sound that we're creating to add in. */ public Sound. Element new. Sound; /* Declare these here so we can reach them inside listeners */ private JText. Field filename; private JText. Field count; int num;

Starting the Window (JFrame) public Rhythm. Tool(){ super("Rhythm Tool"); File. Chooser. set. Media. Path("D:

Starting the Window (JFrame) public Rhythm. Tool(){ super("Rhythm Tool"); File. Chooser. set. Media. Path("D: /cs 1316/mediasources/"); //CHANGE ME! root = new Sound. Element(new Sound(1)); // Nearly empty sound new. Sound = new Sound. Element(new Sound(1)); // Ditto // Layout for the window overall this. get. Content. Pane(). set. Layout(new Border. Layout());

Filename field /* First panel has new sound field */ JPanel panel 1 =

Filename field /* First panel has new sound field */ JPanel panel 1 = new JPanel(); // Put panel one at the top this. get. Content. Pane(). add(panel 1, Border. Layout. NORTH); // Create a space for entering a new sound filename = new JText. Field("soundfilename. wav"); filename. add. Action. Listener( new Action. Listener() { public void action. Performed(Action. Event e) { /* When hit return in filename field, * create a new sound with that name. * Printing is for debugging purposes. **/ new. Sound = new Sound. Element( new Sound( File. Chooser. get. Media. Path(filename. get. Text()))) ; System. out. println("New sound from "+ File. Chooser. get. Media. Path(filename. get. Text() )); } } ); panel 1. add(filename);

Number field /* Put in another panel with number field * and repeat &

Number field /* Put in another panel with number field * and repeat & weave buttons */ JPanel panel 2 = new JPanel(); // This layout is for the PANEL, not the WINDOW panel 2. set. Layout(new Border. Layout()); // Add to MIDDLE of WINDOW this. get. Content. Pane(). add(panel 2, Border. Layout. CEN TER); // Add a field for arguments for Repeat and Weave count = new JText. Field("10"); num = 10; // Default value count. add. Action. Listener( new Action. Listener() { public void action. Performed(Action. Event e) { // Here's how we convert a string to a number num = Integer. parse. Int(count. get. Text()); } } ); // Add to top of panel 2. add(count, Border. Layout. NORTH);

Repeat button // Now do the Repeat button JButton button 1 = new JButton("Repeat");

Repeat button // Now do the Repeat button JButton button 1 = new JButton("Repeat"); button 1. add. Action. Listener( new Action. Listener() { public void action. Performed(Action. Event e) { // Repeat the number of times specified root. repeat. Next(new. Sound, num); } } ); // Add to RIGHT of PANEL panel 2. add(button 1, Border. Layout. EAST);

Weave button // Now do the Weave button JButton button 2 = new JButton("Weave");

Weave button // Now do the Weave button JButton button 2 = new JButton("Weave"); button 2. add. Action. Listener( new Action. Listener() { public void action. Performed(Action. Event e) { // We'll weave 10 copies in // every num times root. weave(new. Sound, 10, num); } } ); // Add to LEFT of PANEL panel 2. add(button 2, Border. Layout. WEST);

Play Button (and end) /* Put in another panel with the Play button */

Play Button (and end) /* Put in another panel with the Play button */ JPanel panel 3 = new JPanel(); // Put in bottom of WINDOW this. get. Content. Pane(). add(panel 3, Border. Layout. SOUTH); JButton button 3 = new JButton("Play"); button 3. add. Action. Listener( new Action. Listener() { // If this gets triggered, play the composed sound public void action. Performed(Action. Event e) { root. play. From. Me. On(); } } ); panel 3. add(button 3); // No layout manager here this. pack(); this. set. Visible(true); } }