59
Chapter 14 – Using Layout Managers and Events Dr. James Burns –

Chapter 14 – Using Layout Managers and Events Dr. James Burns –

Embed Size (px)

Citation preview

  • Chapter 14 Using Layout Managers and EventsDr. James Burns

  • Layout ManagerA layout manager is an object that controls the size and position of components inside a Container objectThe layout manager that you assign to the window determines how the components are sized and positioned within the windowLayout managers are interface classes that are part of the Java SDKThey align your componentsThen the components do not crowd each other or overlap

  • Learning about Layout ManagersIf you are placing more than one component on a JFrame, JApplet or any other container, you spend a lot of time determining exactly where to place each component so the layout is attractive and no component obscures anotherThe alternative is to use a layout manager

  • ExamplesOne layout manager arranges components in equally spaced columns and rowsAnother layout manager centers components within their ContainerEach layout manager defines methods that arrange components within a Container itself, so you can assign layout managers within layout managers

  • More on Layout ManagersLayout managers can also be a Container itself, so you can assign layout managers within layout managersThe Java platform provides very simple layout managers like FlowLayout and GridLayout to the special purpose BorderLayout and CardLayout to the very flexible GridBagLayout and BoxLayout

  • Table showing when each layout manager should be used

    Layout ManagerWhen to UseBorderLayoutUse when you add components to a maximum of five sections arranged in north, south, east, west, and center positionsFlowLayoutUse when you need to add components from left to right, Flowlayout automatically moves to the next row when needed, and each component takes its preferred sizeGridLayoutUse when you need to add components into a grid of rows and columns; each component is the same size

  • Table, Continued

    Layout ManagerWhen to UseCardLayoutUse when you need to add components that are displayed one at a timeBoxLayoutUse when you need to add components into a single row or a single columnGridBagLayoutUse when you need to set size, placement, and alignment constraints for every component that you add

  • Using Border LayoutThe BorderLayout manager is the default manager class for all content panesYou can use the BorderLayout class with any container that has five or fewer componentsThe components will fill the screen in five regionsnorth, south, east, west, and center

  • Using add() to add componentsWhen you add a component to a container that uses BorderLayout, the add() method uses two argumentsthe component and the region to which the component is addedThe BorderLayout class provides five named constants for the regionsBorderLayout.NORTH, .SOUTH, .EAST, .WEST, and .CENTER

  • import javax.swing.*;import java.awt.*;public class JDemoBorderLayout extends JApplet{ private JButton nb = new JButton("North Button"); private JButton sb = new JButton("South Button"); private JButton eb = new JButton("East Button"); private JButton wb = new JButton("West Button"); private JButton cb = new JButton("Center Button"); public void init() { setLayout(new BorderLayout()); add(nb, BorderLayout.NORTH); add(sb, BorderLayout.SOUTH); add(eb, BorderLayout.EAST); add(wb, BorderLayout.WEST); add(cb, BorderLayout.CENTER); }}

  • Html doc to host the applet

  • Using FlowLayoutYou can use the FlowLayout manager class to arrange components in rows across the width of a ContainerWith FlowLayout, each Component that you add is placed to the right of previously added components in a row, or if the current row is filled, the Component is placed to start a new row

  • Comparing BorderLayoutWith BorderLayout, the Components are sized to fit the pane With FlowLayout, each Component retains its default size, or preferred size.If there is text in the Component, that text may not be visible when it gets resized with BorderLayout

  • FlowLayout class contains three constants you can use to align ComponentsFlowLayout.LEFTFlowLayout.CENTERFlowLayout.RIGHT

    If you do not specify alignment, Components are center-aligned in a FlowLayout Container by default

  • import javax.swing.*;import java.awt.*;import java.awt.event.*;public class JDemoFlowLayout extends JApplet implements ActionListener{ private JButton lb = new JButton("L Button"); private JButton rb = new JButton("R Button"); private Container con = getContentPane(); private FlowLayout layout = new FlowLayout(); public void init() { con.setLayout(layout); con.add(lb); con.add(rb); lb.addActionListener(this); rb.addActionListener(this); } public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if(source == lb) layout.setAlignment(FlowLayout.LEFT); else layout.setAlignment(FlowLayout.RIGHT); con.invalidate(); con.validate(); }}

  • You can Dynamically reposition ComponentsAs illustrated in Figures 14-5, 6 and 7Involving use of con.invalidate();con.validate();The invalidate() call marks the container as needing to be laid outThe validate() call causes the components to be rearranged based on the newly assigned layout

  • Using GridLayoutUse GridLayout if you want to arrange components into equal rows and columnsWhen you create a GridLayout object, you indicate the numbers of rows and columns you want, and then the container surface is divided into a grid

  • For example,The following statement establishes an anonymous GridLayout with four horizontal rows and five vertical columns in a Container named conCon.setLayout(new GridLayout(4, 5));

  • Similarly, within a JApplet, you can establish the same layout with either of the following:This.setLayout(new GridLayout(4, 5));

    setLayout(new GridLayout(4, 5));As you add new components to a Gridlayout, they are positioned left-to-right across each row in sequence

  • More on GridLayoutsYou cannot skip a position or specify an exact position for a componentYou can add a blank label to a grid position and give the illusion of skipping a position

  • GapsYou can specify vertical and horizontal gaps measured in pixels, using two additional arguments.Private GridLayout layout = new GridLayout(3, 2, 5, 5);

  • import javax.swing.*;import java.awt.*;public class JDemoGridLayout extends JApplet{ private JButton b1 = new JButton("Button 1"); private JButton b2 = new JButton("Button 2"); private JButton b3 = new JButton("Button 3"); private JButton b4 = new JButton("Button 4"); private JButton b5 = new JButton("Button 5"); private GridLayout layout = new GridLayout(3, 2, 5, 5); public void init() { setLayout(layout); add(b1); add(b2); add(b3); add(b4); add(b5); }}

  • Using CardLayoutYou use CardLayout when you want multiple compnoents to share the same display spaceThe CardLayout manager generates a stack of containers or components, one on top of anotherEach component is a card and each card can be any component typeex., JButton, JLabel, or JPanel

  • CardLayout uses one of two constructorsCardLayout() creates a card layout without a horizontal or vertical gapCarLayout(int hgap, int vgap) creates a card layout with the specified horizontal and vertical gapsHorizontal gaps are placed at the left and right edgesVertical gaps are placed at the bottom and top edges

  • import javax.swing.*;import java.awt.*;import java.awt.event.*;public class JDemoCardLayout extends JApplet implements ActionListener{ private CardLayout cards = new CardLayout(); private JButton b1 = new JButton("Ace of Hearts"); private JButton b2 = new JButton("Three of Spades"); private JButton b3 = new JButton("Queen of Clubs"); public void init() { setLayout(cards); add("ace", b1); b1.addActionListener(this); add("three", b2); b2.addActionListener(this); add("queen", b3); b3.addActionListener(this); } public void actionPerformed(ActionEvent e) { cards.next(getContentPane()); }}

  • Using Advanced Layout ManagersProfessioinal Java programmers create new components and new layout managersExamples includeGridBagLayout managerallows you to add Components to precise locations within the grid, as well as indicate that specific Components should span multiple rows or columns within the gridIf you want to create a JPanel with six JButtons, in which two are twice as wide as the others, use GridBagLayout

  • Using JPanels to Increase Layout OptionsYou can use the JPanel class to greatly increase the number of possible component arrangements JPanel is similar to a JWindow or a JFrame, in that a JPanel is a surface on which you can place componentsBut JPanel is not a child of JWindow or JFrame

  • JPanel is a type of JComponent.JPanel is a Container, meaning it can contain other componentsFor example, you can create a JApplet using BorderLayout and place a JPanel in any of the five regionsThen within the north JPanel, you can place four JButtons using GRidLayout and within the east JPanel, you can place three JLabels using FlowLayout.

  • JPanels.By using JPanels within JPanels, you can create an infinite variety of screen layouts

    JPanels support double buffering, which is the default buffering strategy resulting in an updated screen only when it is complete so that no flickering takes place while the JPanel is being redrawn

  • JPanel ConstructorsJPanel() creates a JPanel with double buffering and a flow layoutJPanel(LayoutManager layout) creates a JPanel with the specified layout manager and double bufferingJPanel(Boolean isDoubleBuffered) creates a JPanel with flow layout and the specified double-buffering strategyJPanel(LayoutManager layout, Boolean isDoubleBuffered) creates a JPanel with the specified layout manager and the specified doublebuffering strategy

  • ExamplesThe following statements create a JPanel that uses a named BorderLayout managerBorderLayout border = new BorderLayout();JPanel myPanel = new JPanel(border);

  • The following statement accomplishes the same thing as the previous two, combining bothstatements by using an anonymous layout manager:

    JPanel myPanel = new JPANEL(new BorderLayout());

  • import javax.swing.*;import java.awt.*;public class JDemoManyPanels extends JApplet{ // Twelve buttons JButton button01 = new JButton("One"); JButton button02 = new JButton("Two"); JButton button03 = new JButton("Three"); JButton button04 = new JButton("Four"); JButton button05 = new JButton("Five"); JButton button06 = new JButton("Six"); JButton button07 = new JButton("Seven"); JButton button08 = new JButton("Eight"); JButton button09 = new JButton("Nine"); JButton button10 = new JButton("Ten"); JButton button11 = new JButton("Eleven"); JButton button12 = new JButton("Twelve"); // Four panels JPanel panel01 = new JPanel(new GridLayout(2, 0)); JPanel panel02 = new JPanel(new FlowLayout()); JPanel panel03 = new JPanel(new FlowLayout()); JPanel panel04 = new JPanel(new GridLayout(2, 0));

  • public void init() { setLayout(new BorderLayout()); add(panel01, BorderLayout.WEST); add(panel02, BorderLayout.CENTER); add(panel03, BorderLayout.SOUTH); add(panel04, BorderLayout.EAST);

    panel01.add(button01); panel01.add(button02); panel01.add(button03);

    panel02.add(button04); panel02.add(button05); panel02.add(button06);

    panel03.add(button07);

    panel04.add(button08); panel04.add(button09); panel04.add(button10); panel04.add(button11); panel04.add(button12); }}

  • Checker Board PanelThe following program creates a checkerboard panel, as shown in figure 14-16

  • import java.awt.*;import javax.swing.*;public class Checkerboard extends JFrame{ final int ROWS = 8; final int COLS = 8; final int GAP = 2; final int NUM = ROWS * COLS; int x; JPanel pane = new JPanel(new GridLayout(ROWS, COLS, GAP, GAP)); JPanel[] panel = new JPanel[NUM]; Color color1 = Color.WHITE; Color color2 = Color.BLUE; Color tempColor; public Checkerboard() { super("Checkerboard"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); add(pane); for(x = 0; x < NUM; ++x) { panel[x] = new JPanel(); pane.add(panel[x]);

  • if(x % COLS == 0) { tempColor = color1; color1 = color2; color2 = tempColor; } if(x % 2 == 0) panel[x].setBackground(color1); else panel[x].setBackground(color2); } } public static void main(String[] arguments) { Checkerboard frame = new Checkerboard(); final int SIZE = 300; frame.setSize(SIZE, SIZE); frame.setVisible(true); }}

  • Understanding Events and Event HandlingNow that you understand inheritance and abstract classes, you can take a deeper look at event handlingLike all Java classes, events are Objects.Specifically, events are objects that the user initiates, such as key presses or mouse clicks

  • EventObjectEventObject is the parent class for all event objects, which descends from the Object classEventObject is the parent of AWTEvent, which in turn is the parent of specific event classes, such as ActionEvent and ComponentEvent

  • ComponentEventComponentEvent is a child of EventObjectBut is also a parent of KeyEvent and MouseEvent

  • RulesActionEvents are generated by components that users can click, such as JButtons and JCheckBoxesTextEvents are generated by components into which the user enters text, such as a JTextFieldMouseEvents include determining the location of the mouse and distinguishing between a single- and double-click.

  • User ActionResulting Event typeClick a ButtonActionEventClick a componentMouseEventClick an item in a list boxItemEventClick an item in a check boxItemEventChange text in a text fieldTextEventOpen a windowWindowEventIconify a windowWindowEventPress a keyKeyEvent

  • ActionEvents and MouseEventsBecause ActionEvents and MouseEvents involve the mouse, it is easy to confuse ActionEvents and MouseEventsUse ActionEvents when a mouse click changes a component, like a JButtonUse MouseEvents when your program is focusing on what the user is doing manually with the mouse, such as clicking the left mouse button

  • For events in which the program has no interestNo listeners have to be set up for such eventsFor events that you care about, your must set up a listenerEvery Listener interface method has the return type void and each takes one argumentthe object thatis an instanceof the corresponding event class.

  • ActionListenerIs an interface that has a method named actionPerformed()Interface methods such as actionPerformed(), which are called automatically when an appropriate event occurs, are called event handlers

  • import javax.swing.*;import java.awt.*;import java.awt.event.*;public class JDemoKeyFrame extends JFrame implements KeyListener{ JLabel prompt = new JLabel("Type keys below:"); JLabel outputLabel = new JLabel("Key Typed:"); JTextField textField = new JTextField(10); public JDemoKeyFrame() { setTitle("JKey Frame"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout()); add(prompt, BorderLayout.NORTH); add(textField, BorderLayout.CENTER); add(outputLabel, BorderLayout.SOUTH); addKeyListener(this); textField.addKeyListener(this); }

  • public void keyTyped(KeyEvent e) { char c = e.getKeyChar(); outputLabel.setText("Last key typed: " + c); } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public static void main(String[] args) { JDemoKeyFrame keyFrame = new JDemoKeyFrame(); final int WIDTH = 250; final int HEIGHT = 100; keyFrame.setSize(WIDTH, HEIGHT); keyFrame.setVisible(true); }}

  • An Event-Handling Example: KeyListenerYou use the KeyListener interface when you are interested in actions the user initiates from the keyboardThe KeyListener interface contains three methodskeyPressed()keyTyped()keyReleased()

  • Using AWTEvent Class MethodsMethods in these classes will tell you which component was involved in an eventYou use the getComponent() method to find the specific component involved

  • Handling Mouse EventsUsers spend most of their time operating a mouse rather than keying on a keyboardThe MouseMotionListener interface provides you with methods named mouseDragged() and mouseMoved() that detect the mouse being rolled or dragged across a component surface

  • MouseListener interfaceProvides methods, such asmousePressed()mouseClicked()mouseReleased()mouseEntered()mouseExited()The last two methods tell you when a component has a mouse pointer on it or extied from it

  • MouseInputListener InterfaceImplements all the methods in both the MouseListener and MouseMotionListener interfaces, but has no methods of its own

  • import javax.swing.*;import java.awt.*;import java.awt.event.*;public class JMouseActionsFrame extends JFrame implements MouseListener{ final int MAX = 20; final int STARTX = 10; final int STARTY = 20; int x, y; String message[] = new String[MAX]; int msgCount = 0; public JMouseActionsFrame() { setTitle("Mouse Actions"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addMouseListener(this); }

  • public void mouseClicked(MouseEvent e) { int whichButton = e.getButton(); String msg; if(msgCount == MAX) clearScreen(); message[msgCount] = "You pressed the mouse."; if (whichButton == MouseEvent.BUTTON1) msg = "button 1."; else if(whichButton == MouseEvent.BUTTON2) msg = "button 2."; else msg = "button 3.";

  • message[msgCount] = message[msgCount] + " You used " + msg; message[msgCount] = message[msgCount] + " You are at position " + e.getX() + ", " + e.getY() + "."; if (e.getClickCount() == 2) message[msgCount] = message[msgCount] + " You double-clicked"; else message[msgCount] = message[msgCount] + " You single-clicked"; ++msgCount; repaint(); }

  • public void mouseEntered(MouseEvent e) { if(msgCount == MAX) clearScreen(); message[msgCount] = "You entered the frame"; ++msgCount; repaint(); } public void mouseExited(MouseEvent e) { if(msgCount == MAX) clearScreen(); message[msgCount] = "You exited the frame"; ++msgCount; repaint(); }

  • public void mousePressed(MouseEvent e) { }

    public void mouseReleased(MouseEvent e) { }

    public void paint(Graphics g) { super.paint(g); x = STARTX; y = STARTY; for(int a = 0; a < msgCount; ++a) g.drawString(message[a], x, y += 20); }

  • public void clearScreen() { msgCount = 0; for(int a = 0; a < MAX; ++a) message[a] = " "; repaint(); } public static void main(String[] args) { JMouseActionsFrame mFrame = new JMouseActionsFrame(); final int WIDTH = 750; final int HEIGHT = 500; mFrame.setSize(WIDTH, HEIGHT);

    mFrame.setVisible(true); }}