450 likes | 595 Vues
Object-Oriented Programming (Java), Unit 25. Kirk Scott. An Introduction to Layout. 25.1 Buttons and Flow Layout 25.2 Border Layout 25.3 Panels. Callicebus cupreus , ( Callicebus = beautiful long-tailed monkey, cupreus = coppery) South America.
E N D
Object-Oriented Programming (Java), Unit 25 Kirk Scott
An Introduction to Layout • 25.1 Buttons and Flow Layout • 25.2 Border Layout • 25.3 Panels
Callicebuscupreus, (Callicebus = beautiful long-tailed monkey, cupreus = coppery) South America
25.1 Buttons and Flow Layout • This unit starts a new sequence of examples which continues into the following units. • The examples include both graphical and functional characteristics. • These units are designed to build towards the final programming project. • The examples are presented in an order that is supposed to make sense from the point of view of developing that final assignment.
Of the remaining units, only Unit 27 has an assignment separate from the final programming project. • The Unit 27 assignment covers elements of Units 26 and 27. • The basic purpose of this assignment is to give you some practice using tools and techniques that are introduced in the last units of the course before you start the final programming project. • Some of what you do in working this assignment you may be able to adapt to your final programming project solution.
The examples in this unit illustrate the use of buttons and layout, using the JButton and JPanelclasses. • These initial examples are not difficult. • They are designed to serve as a reminder of previous material and as a transition to the examples which will follow in later units.
These applications have cups which contain simple seed counts rather than seed objects. • This is in preparation for switching from applications with hand coded components (like cups represented by rectangles) to applications where the components consist largely of buttons and text boxes.
MiscButton1 • This program illustrates using a button rather than a clickable cup to trigger action. • No special layout is specified in this application. • The default layout is known as a FlowLayout. • This arranges things in order (typically from left to right) as they are added to a component such as a panel.
Since there is only one button, the effect of layout choice is minimal anyway. • The cups are still given specific x, y locations like in the previous examples, so their placement is not controlled by the layout. • A screenshot of the application is shown on the next overhead.
Here is a UML diagram for MiscButton1. • It shows the addition of a button and a listener for the button to the application. • This basic structure for handling events through a graphical interface is the same as the basic structure of a component and a listener which was developed in previous examples.
The code for this example is very similar to the code for the previous example. • Instead of having a mouse listener, the application now has a JButton added to the panel, with a listener for the button. • The application still contains the concept of the active cup.
The listener is an inner class of the panel, and the code contained inside the button listener is essentially the same as the code that was in the mouse listener in the previous example. • The difference is that clicking the button on the screen triggers an action on whichever cup is the active cup. • Since this is not based on a mouse click, it’s not necessary to check to see if the click occurred on the active cup, for example.
The complete code for MiscButton1 is given because it is the beginning of this series of examples. • For the following examples it will only be necessary to show the changes from MiscButton1. • The code for MiscButton1 is given on the following overheads.
import java.awt.*; • import java.awt.event.*; • import javax.swing.*; • import java.awt.Graphics2D; • import java.awt.Rectangle; • import java.lang.*; • public class MiscButton1 • { • public static void main(String[] args) • { • MiscButtonFramemyframe = new MiscButtonFrame(); • myframe.setVisible(true); • } • }
class MiscButtonFrame extends JFrame • { • private MiscButtonPanelmyPanel; • private final int FRAMEW = 500; • private final int FRAMEH = 500; • public MiscButtonFrame() • { • setTitle("MiscButton1 Frame"); • setSize(FRAMEW, FRAMEH); • setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); • myPanel = new MiscButtonPanel(); • Container contentPane = getContentPane(); • contentPane.add(myPanel, "Center"); • } • }
class MiscButtonPanel extends JPanel • { • private MiscButtonCupmyCupA; • private MiscButtonCupmyCupB; • private MiscButtonCupwhichCupIsActive; • public MiscButtonPanel() • { • myCupA = new MiscButtonCup(4, 200, 200, 40, 40); • myCupB = new MiscButtonCup(0, 250, 200, 40, 40); • whichCupIsActive = myCupA; • JButtonmyButton = new JButton("Jump"); • MiscButtonListenermyButtonListener = new MiscButtonListener(); • myButton.addActionListener(myButtonListener); • add(myButton); • }
public void paintComponent(Graphics g) • { • Graphics2D g2 = (Graphics2D) g; • super.paintComponent(g2); • myCupA.drawCup(g2); • myCupB.drawCup(g2); • }
private class MiscButtonListener implements ActionListener • { • public void actionPerformed(ActionEvent event) • { • if(whichCupIsActive == myCupA) • { • myCupA.moveCupValueTo(myCupB); • whichCupIsActive = myCupB; • repaint(); • } • else if(whichCupIsActive == myCupB) • { • myCupB.moveCupValueTo(myCupA); • whichCupIsActive = myCupA; • repaint(); • } • else • { • } • } • } • }
class MiscButtonCup • { • private intcupValue; • private Rectangle cupRectangle; • private inttextX; • private inttextY; • public MiscButtonCup(intinValue, intcupX, intcupY, intcupW, intcupH) • { • cupValue = inValue; • cupRectangle = new Rectangle(cupX, cupY, cupW, cupH); • textX = cupX + (int) (.25 * cupW); • textY = cupY + (int) (.6 * cupH); • }
public void moveCupValueTo(MiscButtonCup destination) • { • destination.cupValue = this.cupValue; • this.cupValue = 0; • } • public Rectangle getRectangle() • { • return cupRectangle; • } • public void drawCup(Graphics2D g2) • { • g2.draw(cupRectangle); • g2.drawString(Integer.toString(cupValue), textX, textY); • } • }
MiscButton2 • This version of the application shows how to use a layout other than the default. • In this example the BorderLayout will be used. • The BorderLayout makes it possible to add components to an application in the five positions identified by these constants: NORTH, EAST, SOUTH, WEST, and CENTER.
We’ve already seen how it’s possible to add things to panels using the directions of the compass. • That suggests that internally the system maintains a default border layout for certain kinds of graphical components. • In any case, it’s not difficult to use this system.
Only one component can be put in each of the positions, so this kind of layout is suitable for an application with few components. • It is true that a given component may have sub-components, allowing applications with border layouts to be complex. • If there are lots of components, though, we’ll eventually see that there is a better way of managing them.
In MiscButton2 the button is placed at the bottom of the panel. • The result is analogous to the result in one of the earlier examples where a text field was put in the overall panel and it stretched across the width of the panel. • In this example the button extends across the width of the panel.
You can already anticipate how to make the button display in a normal size—put it in a JPanel. • For the time being, simply note that with a border layout and no sub-panels, this is what happens. • A screenshot of the application is shown on the following overhead:
The UML diagram for MiscButton2 is given on the next overhead. • The only change between this and the UML diagram for MiscButton1 is the addition of the BorderLayout to the MiscButtonPanel.
The changes in code between MiscButton1 and MiscButton2 are also very minor. • There are other layouts besides BorderLayout, and in order to use any layouts other than the default layout, it is necessary to import them. • If you’re using any of the layouts, it’s convenient to import them all at once with an import statement using a *.
On the next overhead, the needed import is shown. • This is followed by the only two lines of code that have to be added to turn MiscButton1 into MiscButton2. • These lines of code are added at the bottom of the MiscButtonPanelconstructor. • MiscButton2 serves simply as a springboard for the MiscButton3, which follows.
import java.awt.*; • setLayout(new BorderLayout()); • add(myButton, BorderLayout.SOUTH);
MiscButton3 • This version of the application creates another panel and puts the button in it. • When the panel containing the button is placed at the bottom of the MiscButtonPanel the button is displayed in a nicer way. • The same kind of thing was done in an earlier example in order to make a text field that had been given a size display correctly.
In general, creating nested panels is a simple approach to doing layout in an application. • A screenshot of the application is shown on the following overhead:
Here is a UML diagram of MiscButton3. • The only change is the inclusion of the JPanel in the design.
There are four lines of code which now appear at the bottom of the MiscButtonPanelconstructor. • They illustrate the general plan for arranging the visual components of an application by placing them each in their own panel and then putting each of these panels into a particular position in the overall panel containing them. • This is shown on the following overhead.
JPanelbuttonPanel = new JPanel(); • buttonPanel.add(myButton); • setLayout(new BorderLayout()); • add(buttonPanel, BorderLayout.SOUTH);