1.06k likes | 1.24k Views
CS102 – GUI. Based on : David Davenport’s slides Spring 2002 References: http://java.sun.com/docs/books/tutorial/uiswing http://www.aduni.org/courses/java Core Java Volume 1 http://www.javaworld.com/javaworld/jw-04-1998/jw-04-howto.html. AWT. abstract window toolkit
E N D
CS102 – GUI Based on : David Davenport’s slides Spring 2002 References: http://java.sun.com/docs/books/tutorial/uiswing http://www.aduni.org/courses/java Core Java Volume 1 http://www.javaworld.com/javaworld/jw-04-1998/jw-04-howto.html
AWT • abstract window toolkit • AWT components were provided by the JDK 1.0 and 1.1 platforms. • delegates into native windowing system • therefore, looks different in different platforms
AWT • Since platforms vary, AWT had to choose a lowest common denominator • write once, debug everywhere …
JFC & Swing • JFC is short for JavaTM Foundation Classes, which encompass a group of features to help people build graphical user interfaces (GUIs). The JFC was first announced at the 1997 JavaOne developer conference and has the following features: • The Swing Components • Include everything from buttons to split panes to tables. You can see mugshots of all the components in http://java.sun.com/docs/books/tutorial/uiswing/components/components.html. • Pluggable Look and Feel Support • Gives any program that uses Swing components a choice of looks and feels. For example, the same program can use either the JavaTM look and feel or the Windows look and feel. We expect many more look-and-feel packages to become available from various sources. • Accessibility API • Enables assistive technologies such as screen readers and Braille displays to get information from the user interface. • Java 2DTM API (Java 2 Platform only) • Enables developers to easily incorporate high-quality 2D graphics, text, and images in applications and in applets. • Drag and Drop Support (Java 2 Platform only) • Provides the ability to drag and drop between a Java application and a native application.
Swing • is implemented without making use of native window elements • components are painted by java on blank windows. • more flexibility, not the lowest common denominator • same look, same bugs in all platforms • The Swing components will continue to be enhanced in the future, AWT is dying
Swing, other differences • Swing buttons and labels can display images instead of, or in addition to, text. • You can easily add or change the borders drawn around most Swing components. For example, it's easy to put a box around the outside of a container or label. • You can change the behavior or appearance of a Swing component by either invoking methods on it or creating a subclass of it. • Swing components don't have to be rectangular. Buttons, for example, can be round. • Assistive technologies such as screen readers can easily get information from Swing components. For example, a tool can easily get the text that's displayed on a button or label.
Swing’s Handicaps? • performance • familiarity
Programming forms • Procedural programming • code is executed in sequential order. • Event-driven programming • code is executed upon activation of events. statement 1 statement 2 statement 3 -------- -------- statement n method 1 method 2 method 3 -------- -------- method n Do method 2then method 1 then method 3 Do method 1then method 3
procedural programming • Up to now, our control flow model has been pretty straight-forward. • Execution starts at main() and executes statement sequentially branching with if,for,and while statement, and occasional method calls. • When we need user input we call read() on the console stream which waits (blocks) until the user types something, then returns. • One problem with this model is: How do we wait for and respond to input from more than one source (eg keyboard and mouse). If we block on either waiting for input, we may miss input from the other.
Event-driven programming • the system waits for user input events, and these events trigger program methods • Event-based programming addresses the two problems: • How to wait on multiple input sources (input events) • How to decide what to do on each type of input event
General form of event-driven programming • The operating system and window system process input event from devices (mouse movement, mouse clicks, key presses etc) • The window system decides which window, and hence which frame and program, each input event belongs to. • A data structure describing the event is produced and placed on an 'event queue'. Events are added to one end of the queue by the window system . Events are removed from the queue and processed by the program. These event data structures hold information including: • Which of the program's windows this event belongs to. • The type of event (mouse click, key press, etc.) • Any event-specific data (mouse position, key code, etc.)
Event loop main(){ ...set up application data structures... ...set up GUI.... // enter event loop while(true){ Event e = get_event(); process_event(e); // event dispatch routine } } • the event loop is usually hidden from programmer, he/she provides just a process_event() method
Java Event Management • java system has more control over event system, it directs events based on their type • you only override behavior you are interested in. • more details later…
AWT Applications - Frame • Frame is a container for components Frame with normal window controls Optional Menu Three containers in Frame with Border Layout UI-components inside containers each with own layout
AWT classes Container Panel Applet AWTEvent Button Window Frame Font Label Dialog FileDialog FontMetrics TextField TextComponent Object Color TextArea List Graphics Choice Component CheckBox CheckBoxGroup LayoutManager Canvas MenuComponent MenuItem Menu MenuBar Scrollbar
AWT & Swing classes AWTEvent Classes in thejava.awt package LayoutManager Heavyweight 1 Fon t FontMetrics Object Color Panel Applet JApplet Graphics Component Container Window Frame JFrame * Dialog JDialog JComponent Swing Components in the javax.swing package Lightweight
Understanding the GUI {label} {Frame} components {textfield} {button} • UI-containers • have list of UI-components • Each UI-component • is a class • with paint method • & lists of Event listeners
Setting up the GUI • Extend Frame class • In constructor • Create instances of containers& add them to Frame • Create instances of components& add them to containers or Frame • Possibly override paint method Hint: Employ layout managers to arrange components in containers • UI-components added to components list • Painting Frame • paints Frame borders • calls Frame paint method • calls paint method of each object in component list
A simple example import javax.swing.*; class FirstFrame extends JFrame { public FirstFrame() { setTitle("FirstFrame"); setSize(300, 200); } } public class FirstTest { public static void main(String[] args) { JFrame frame = new FirstFrame(); frame.show(); } }
Simple Example Remarks • we have two classes, one for the frame, the other for the main method that creates the frame • we could have put the main method inside class FirstFrame • if we don’t set the size, the default is a window of size 0x0 • java runtime creates a new thread for our frame • it doesn’t terminate, just hides
Hello World Program import javax.swing.*; public class HelloWorldSwing { public static void main(String[] args) { JFrame frame = new JFrame("HelloWorld"); JLabel label = new JLabel("Hello World"); frame.getContentPane().add(label); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); frame.setBounds(200, 200, 200, 50); frame.setVisible(true); } }
Containers • Swing provides three generally useful top-level container classes: JFrame, JDialog, and JApplet. • To appear onscreen, every GUI component must be part of a containment hierarchy. Each containment hierarchy has a top-level container as its root. • Each top-level container has a content pane that, generally speaking, contains the visible components in that top-level container's GUI. • You can optionally add a menu bar to a top-level container. The menu bar is positioned within the top-level container, but outside the content pane.
Container Tree • a frame, or main window (JFrame) • a panel, sometimes called a pane (JPanel) • a button (JButton) • a label (JLabel)
Containers .. • The frame is a top-level container. It exists mainly to provide a place for other Swing components to paint themselves. • The panel is an intermediate container. Its only purpose is to simplify the positioning of the button and label. Other intermediate Swing containers, such as scroll panes (JScrollPane) and tabbed panes (JTabbedPane), typically play a more visible, interactive role in a program's GUI. • The button and label are atomic components -- components that exist not to hold random Swing components, but as self-sufficient entities that present bits of information to the user. Often, atomic components also get input from the user.
Using Layout Managers • By default, every container has a layout manager. • All JPanel objects use a FlowLayout by default, whereas content panes (the main containers in JApplet, JDialog, and JFrame objects) use BorderLayout by default. • You can change the layout as: JPanel pane = new JPanel(); pane.setLayout(new BorderLayout()); • When you add components to a panel or a content pane, the arguments you specify to the add method depend on the layout manager that the panel or content pane is using.
Border Layout • A border layout lays out a container, arranging and resizing its components to fit in five regions: north, south, east, west, and center. • Each region may contain no more than one component, and is identified by a corresponding constant: NORTH, SOUTH, EAST, WEST, and CENTER. When adding a component to a container with a border layout, use one of these five constants, for example: Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(new Button("Okay"), BorderLayout.SOUTH);
Border Layout Example Container contentPane = getContentPane(); //Use the content pane's default BorderLayout. //contentPane.setLayout(new BorderLayout()); contentPane.add(new JButton("Button 1 (NORTH)"), BorderLayout.NORTH); contentPane.add(new JButton("2 (CENTER)"), BorderLayout.CENTER); contentPane.add(new JButton("Button 3 (WEST)"), BorderLayout.WEST); contentPane.add(new JButton("Long-Named Button 4 (SOUTH)"), BorderLayout.SOUTH); contentPane.add(new JButton("Button 5 (EAST)"), BorderLayout.EAST);
Border Layout cont. • We specified the component as the first argument to the add method. For example: add(component, BorderLayout.CENTER) //preferred However, you might see code in other programs that specifies the component second. For example, the following are alternate ways of writing the preceding code: add(BorderLayout.CENTER, component) add("Center", component) //valid but error prone • By default, a BorderLayout puts no gap between the components it manages. You can specify gaps (in pixels) using the following constructor: BorderLayout(int horizontalGap, int verticalGap) You can also use the following methods to set the horizontal and vertical gaps, respectively: void setHgap(int) void setVgap(int)
Border Layout Resizing • First North and South are drawn with their normal sizes, then east & west, finally all the rest of the space is reserved for center. • center is the default location • by default anything in center fill resize to fill the space
Flow Layout • FlowLayout puts components in a row, sized at their preferred size. • If the horizontal space in the container is too small to put all the components in one row, FlowLayout uses multiple rows. • Within each row, components are centered (the default), left-aligned, or right-aligned as specified when the FlowLayout is created.
Flow Layout Example Container contentPane = getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.add(new JButton("Button 1")); contentPane.add(new JButton("2")); contentPane.add(new JButton("Button 3")); contentPane.add(new JButton("Long-Named Button 4")); contentPane.add(new JButton("Button 5"));
The FlowLayout API • The FlowLayout class has three constructors: • public FlowLayout() • public FlowLayout(int alignment) • public FlowLayout(int alignment, int horizontalGap, int verticalGap) • The alignment argument must have the value FlowLayout.LEFT, FlowLayout.CENTER, or FlowLayout.RIGHT. • The horizontalGap and verticalGap arguments specify the number of pixels to put between components. If you don't specify a gap value, FlowLayout uses 5 for the default gap value.
Grid Layout • A GridLayout places components in a grid of cells. • Each component takes all the available space within its cell, and each cell is exactly the same size. • If you resize the GridLayout window, it changes the cell size so that the cells are as large as possible, given the space available to the container.
Grid Layout Example Container contentPane = getContentPane(); contentPane.setLayout(new GridLayout(0,2)); contentPane.add(new JButton("Button 1")); contentPane.add(new JButton("2")); contentPane.add(new JButton("Button 3")); contentPane.add(new JButton("Long-Named Button 4")); contentPane.add(new JButton("Button 5")); • The constructor tells the GridLayout class to create an instance that has two columns and as many rows as necessary.
The GridLayout API • The GridLayout class has two constructors: public GridLayout(int rows, int columns) public GridLayout(int rows, int columns, int horizontalGap, int verticalGap) • At least one of the rows and columns arguments must be nonzero. • The horizontalGap and verticalGap arguments to the second constructor allow you to specify the number of pixels between cells. If you don't specify gaps, their values default to zero.
GridBagLayout • GridBagLayout is the most flexible and complex one • A GridBagLayout places components in a grid of rows and columns, allowing specified components to span multiple rows or columns. • Not all rows necessarily have the same height. Similarly, not all columns necessarily have the same width. • Essentially, GridBagLayout places components in rectangles (cells) in a grid, and then uses the components' preferred sizes to determine how big the cells should be. • see http://www.interex.org/pubcontent/enterprise/jul00/08chew.html for a nice description
Setting Up … GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); JPanel pane = new JPanel(); pane.setLayout(gridbag); //For each component to be added to this container: //...Create the component... //...Set instance variables in the GridBagConstraints instance... gridbag.setConstraints(theComponent, c); pane.add(theComponent);
GridBagConstraints • gridx, gridy • Specify the row and column at the upper left of the component. • gridwidth, gridheight • Specify the number of columns (for gridwidth) or rows (for gridheight) in the component's display area. • fill • Used when the component's display area is larger than the component's requested size to determine whether and how to resize the component. Valid values are NONE (the default), HORIZONTAL (make the component wide enough to fill its display area horizontally, but don't change its height), VERTICAL and BOTH. • ipadx, ipady • Specifies the internal padding: how much to add to the minimum size of the component. The default value is zero. The width of the component will be at least its minimum width plus ipadx*2 pixels, the height of the component will be at least its minimum height plus ipady*2 pixels. • insets • Specifies the external padding of the component -- the minimum amount of space between the component and the edges of its display area. By default, each component has no external padding. • anchor • Used when the component is smaller than its display area to determine where (within the area) to place the component. Valid values (defined as GridBagConstraints constants) are CENTER (the default), NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, and NORTHWEST. • weightx, weighty • Weights are used to determine how to distribute space among columns (weightx) and among rows (weighty); this is important for specifying resizing behavior.
Horizontal Fill • fill = HORIZONTAL expands components to maximum horizontally, but normal vertically fill=HORIZONTAL fill=NONE
Weights • all the components expand equally horizontally, since their weightx are equal • only button 5’s area expand vertically, since other’s weighty’s are 0
Ipad & inset • ipad values grow the component itself, whereas insets grow the area while keeping the component same size • fill = HORIZONTAL makes buttons wider than they should be, but only button 4 with a nonzero ipady value is higher than normal.