Download Slide 1

Document related concepts
no text concepts found
Transcript
Object-Oriented Programming
(Java), Unit 26
Kirk Scott
1
More on Layout
• 26.1 Background Information
• 26.2 Switching from Cups to Registers
• 26.3 Using Text Fields as Application
Components
• 26.4 Adding Labels and Using the GridLayout
2
3
"The 3 of Birds" by the Master of the Playing
Cards, 15th century Germany
4
The 9 of Beasts
5
The Martyrdom of St. Sebastian
6
St. Sebastian, Andrea Mantegna, 1480,
Musée du Louvre, Paris.
7
• The final project assignment is built on a
continuation of Wari.
• The example programs in the units starting
with this one will be based on something else.
• This makes these examples somewhat less
helpful than the earlier examples.
8
• Hard as it may be to believe, there is an
educational logic to this.
• The point is that you will need to figure out
how to adapt code from a different problem
domain into code that will work for your
problem domain.
• All software development ultimately stems
from inspired code theft…
9
• The examples of the previous unit used simplified
cups.
• The examples of this unit show how to use text
boxes to store certain kinds of information and
text areas to store other kinds of information.
• The names of the components in this application
and the values placed in them are intended to
suggest the registers and memory of a simple
CPU.
10
• These registers can be adapted to represent the
cups of a Wari game.
• Keep in mind that the functionality of the game is
not in the cup components themselves.
• The game functionality is implemented in other
classes which make use of these components.
• This is what makes it possible for the components
to be adapted for use in different applications.
11
• In order to introduce the examples, it is helpful to
review what registers and memory are and how
they’re used in the simulation of a simple
computer chip.
• A register is a small block of storage space on a
computer chip.
• It can be used to hold the value of a single
variable or the address of an instruction, for
example.
• In a register, values are stored in binary form.
12
• In a real chip the registers may be up to 32 or
64 bits long and the bits store the electronic
equivalent of binary 1’s and 0’s.
• In the example programs in this and the
following units the registers will be 8 bits long.
• Their contents will be represented by a String
of length 8 containing the characters 1 and 0.
13
• A CPU has an assembly language consisting of
a set of human-readable mnemonics for the
hardware instructions.
• It is possible to access the general purpose
registers of the chip using assembly language.
• Suppose the chip in question has general
purpose registers named A through D.
14
• This is an example of the form of an assembly
language statement for storing the value 1 in
register D:
• MOVE D, X01
• The name of the instruction comes first, followed
by the destination operand, followed by the
source operand.
• The X in X01 signifies that the value is given in
hexadecimal notation, and the 01 is a two digit
hexadecimal number with a decimal value of 1.
15
• Assembly language statements can be translated into
machine language statements, which the chip can
execute.
• The MOVE given above might translate as follows:
• 10000101
00000100
00000001
• The first eight bits would be the machine code for the
MOVE instruction.
• The second eight bits, 00000100, would be the code for
the register D.
• This value is decimal 4, which would match with D if the
registers were numbered 1 through 4.
• The last 8 bits, 00000001, is an eight digit binary number
with a decimal value of 1.
16
You can visualize the outcome of the execution
of this instruction inside the chip in this way.
The value 00000001 is moved to register D.
D 00000001
17
Suppose that the decimal value
10, binary 00001010, were moved to
register C. The results of the two moves
together could be visualized as follows:
C 00001010
D 00000001
18
• The instruction set for a chip would also
include arithmetic operations like addition
and subtraction.
• The assembly language for subtracting the
contents of register D from the contents of
register C might look like this:
• SUB C, D
19
• This might translate into machine language as follows:
• 10001011
00000011
00000100
• The first eight bits would be the code for the
subtraction instruction.
• The second 8 bits would be the code for register C.
• The third eight bits would be the code for register D.
• The contents of register D would be unchanged by the
operation
• The value in register C, decimal 10, would have 1
subtracted from it.
20
After execution of the instruction, the
decimal value 9, binary 00001001, is in
register C. The results can be visualized
as shown below:
C 00001001
D 00000001
21
• The example programs of this unit implement
8 bit registers where the bits are represented
by a String of 8 characters.
• It is possible to move the contents of one
register to another.
• It will also become possible to move the
contents of a register to and from a
representation of memory.
22
26.2 Switching from Cups to Registers
23
MiscRegister
• The designation Misc, which will appear in the
following examples, is an acronym of the
phrase “Minimal instruction set computer”
• The examples to come will be based on the
idea of registers in a machine
• You will have to adapt the register examples to
represent cups in your version of Wari/Togiz
Kumalak
24
• In the first example, MiscRegister, registers
contain strings of characters representing
binary digits.
• Action is triggered in the application by
clicking a button.
• The code implements a swap of register
contents, not a jump as in the previous Wari
examples.
25
• Because swapping replaces jumping, there is
no need to keep track of an active register in
the code.
• Both registers are affected reciprocally by
clicking the button.
• Here is a screenshot of the application:
26
27
• The UML diagram for MiscRegister is given on
the following overhead.
• The change from the last example of the
previous unit is the replacement of the two
cups by two registers, each having a rectangle
and byte.
28
MiscRegister
1
MiscRegisterFrame
1
ContentPane
1
MiscRegisterPanel
BorderLayout
1
1
1
1
2
MiscRegisterRegister
1
Rectangle
1
JPanel
1
1
MiscRegisterByte
JButton
1
MiscButtonListener
29
• The code for MiscRegister is much the same as
the code for MiscButton3 except for the
MiscRegister and MiscRegisterByte classes.
• The implementation of the register class will
change in future examples, but the basic idea
is that a register encapsulates a machine byte.
• The register provides a graphical
representation of the byte as well as other
methods that affect it.
30
• The complete code for this example is given
beginning on the next overhead.
• The following examples build on it
• For them it will only be necessary to show
those places where there are significant
changes.
31
•
•
•
•
•
•
•
•
•
•
•
•
import
import
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
java.awt.Graphics2D;
java.lang.*;
java.awt.Rectangle;
public class MiscRegisterOneFile
{
public static void main(String[] args)
{
MiscRegisterFrame myframe = new
MiscRegisterFrame();
•
myframe.setVisible(true);
•
}
• }
32
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
class MiscRegisterFrame extends JFrame
{
private MiscRegisterPanel myPanel;
private final int FRAMEW = 500;
private final int FRAMEH = 500;
public MiscRegisterFrame()
{
setTitle("MiscRegister Frame");
setSize(FRAMEW, FRAMEH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myPanel = new MiscRegisterPanel();
Container contentPane = getContentPane();
contentPane.add(myPanel, "Center");
}
}
33
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
class MiscRegisterPanel extends JPanel
{
private MiscRegisterRegister registerA;
private MiscRegisterRegister registerB;
200);
public MiscRegisterPanel()
{
registerA = new MiscRegisterRegister("11110000", 160,
registerB = new MiscRegisterRegister("00001111", 260,
200);
JButton myButton = new JButton("Swap");
MiscButtonListener myButtonListener = new
MiscButtonListener();
myButton.addActionListener(myButtonListener);
JPanel buttonPanel = new JPanel();
buttonPanel.add(myButton);
setLayout(new BorderLayout());
add(buttonPanel, BorderLayout.SOUTH);
}
34
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
registerA.drawRegister(g2);
registerB.drawRegister(g2);
}
private class MiscButtonListener implements
ActionListener
{
public void actionPerformed(ActionEvent
event)
{
registerA.swapRegisterContents(registerB);
repaint();
}
}
}
35
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
class MiscRegisterRegister
{
private MiscRegisterByte registerByte;
private Rectangle registerRectangle;
private static int regW = 80;
private static int regH = 20;
private int textX;
private int textY;
public MiscRegisterRegister()
{
}
public MiscRegisterRegister(String stringIn, int regX, int
regY)
{
regH);
registerByte = new MiscRegisterByte(stringIn);
registerRectangle = new Rectangle(regX, regY, regW,
textX = regX + (int) (.16 * regW);
textY = regY + (int) (.75 * regH);
}
36
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
public void setRegisterByte(MiscRegisterByte byteIn)
{
registerByte = byteIn;
}
public MiscRegisterByte getRegisterByte()
{
return registerByte;
}
public void swapRegisterContents(MiscRegisterRegister source)
{
MiscRegisterByte tempByte;
tempByte = source.getRegisterByte();
source.setRegisterByte(this.getRegisterByte());
this.setRegisterByte(tempByte);
}
37
•
•
•
•
•
•
public void drawRegister(Graphics2D g2)
{
g2.draw(registerRectangle);
g2.drawString(registerByte.getStringFromByte(),
textX, textY);
}
}
38
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
class MiscRegisterByte
{
public static final int bitsinbyte = 8;
private static final String junk = "00000000";
private char bytearray[] = new char[bitsinbyte];
public MiscRegisterByte()
{
/* This looks a little weird.
getChars() is a String class method.
The 4 parameters are the beginning and
ending indexes of the String to copy,
a character array to copy into, and a
beginning index in the character array
to copy into. This accomplishes
initializing the character array
containing the value of a byte to the
junk string. */
junk.getChars(0, bitsinbyte, bytearray, 0);
}
39
•
•
•
•
•
•
•
•
•
•
•
•
public MiscRegisterByte(String stringIn)
{
/* The preliminary lines in this code
are designed to deal with an input
String which is either shorter or
longer than 8 characters. */
junk.getChars(0, bitsinbyte, bytearray, 0);
int stringlength = stringIn.length();
if(stringlength > bitsinbyte)
stringlength = bitsinbyte;
stringIn.getChars(0, stringlength, bytearray, 0);
}
40
•
•
•
•
•
•
•
public void setByteToThisString(String astring)
{
junk.getChars(0, bitsinbyte, bytearray, 0);
int stringlength = astring.length();
if(stringlength > bitsinbyte)
stringlength = bitsinbyte;
astring.getChars(0, stringlength, bytearray,
0);
•
•
•
•
•
•
•
}
public String getStringFromByte()
{
return String.copyValueOf(bytearray);
}
}
41
26.3 Using Text Fields as Application
Components
42
MiscText
• In this program each register is represented by
a text field.
• The text fields have listeners, so it is possible
to enter new values into the registers.
• There is also a button with a listener.
• The button causes a swap of the values
between the registers.
43
• From this point on the graphical components of
the example applications are instances of system
supplied classes, like JTextField.
• They are not instances of classes which are
written from scratch, such as Cup or MiscRegister
of the previous examples.
• The key point is that a register is represented by a
text field on the screen
• There is still a register class that has that text field
44
• The progression of Echo and Wari examples went
from things like text fields to clickable cups.
• In a sense, this new progression of examples is
going in the opposite direction.
• It turns out to be much simpler to use system
supplied classes for graphical components than
homemade classes.
• A screenshot of MiscText is given on the next
overhead.
45
46
• The UML diagram for the application brings
out several important points.
• The relationships among the classes
representing the registers and the panels in
the application are somewhat complex.
• The MiscTextPanel has two MiscTextRegister
objects as instance variables.
• These registers have instances of MiscTextByte
and JTextField.
47
• The MiscTextRegister class has an inner class,
TextFieldListener.
• The MiscTextPanel class has a JPanel for
displaying the registers’ contents.
• The registers’ text fields are added to this
JPanel.
• This JPanel has the default FlowLayout, so the
text fields are displayed from left to right.
48
• The MiscTextPanel also has a JPanel to hold the
application’s button.
• The button has a listener which is implemented
as an inner class of the MiscTextPanel.
• The MiscTextPanel has BorderLayout and the
JPanel containing the text fields is added to it at
the top, and the JPanel containing the button is
added to it at the bottom.
• The UML diagram is given on the following
overhead.
49
MiscText
1
MiscTextFrame
1
ContentPane
1
MiscTextPanel
BorderLayout
1
1
1
2
1
MiscTextRegister
1
JPanel
JPanel
1
1
1
1
2
MiscTextByte
JTextField
1
TextFieldListener
JButton
1
MiscButtonListener
50
• Selections of code from the MiscTextPanel and
the MiscTextRegister classes follow.
• These two classes contain elements which are
significantly different from previous
application classes.
51
• The constructor for the MiscTextPanel begins
with the six lines of code shown on the next
overhead.
• The two registers are constructed, the layout is
set, and a panel to hold the graphical
representations of the registers is constructed.
• This panel has added to it the text fields
belonging to the registers.
• Note the calls to the getMyField() method.
• The text fields are instance variables inside the
MiscTextRegister class.
52
•
•
•
•
•
•
•
•
•
registerA = new MiscTextRegister("11110000");
registerB = new MiscTextRegister("00001111");
setLayout(new BorderLayout());
JPanel registerPanel = new JPanel();
registerPanel.add(registerA.getMyField());
registerPanel.add(registerB.getMyField());
53
• The code for the button listener, which is an inner
class of the MiscTextPanel, contains only one
change.
• The call to repaint(), which has appeared in all
previous listeners, is commented out.
• This is a small, but important step in the right
direction.
• One of the purposes of moving from hand-made
components to system components is that the
code will be simplified.
54
• The graphical representations of the registers
are instances of JTextFields.
• These are system supplied classes, and the
system takes care of repainting them when
necessary.
• The run time appearance of the application is
the same with or without calls to repaint().
• The listener code is shown on the next
overhead.
55
•
•
•
•
•
•
•
•
private class MiscButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
registerA.swapRegisterContents(registerB);
//repaint();
}
}
56
• The MiscTextRegister class has these two
instance variables:
• private MiscTextByte registerByte;
• private JTextField myField;
57
• The MiscTextByte instance variable is part of
the model of the application.
• It holds state.
• The JTextField instance variable is part of the
view of the application.
• This is what’s used to graphically represent
part of the application on the screen.
58
• The method for swapping register contents in
the MiscTextRegister class involves both
exchanging the bytes and updating the
contents of the respective text fields.
• In other words, both the model and the view
have to be updated.
• This method is shown on the next overhead.
59
•
•
•
•
•
•
•
•
•
•
•
•
•
public void swapRegisterContents(MiscTextRegister source)
{
MiscTextByte tempByte;
/* Put the explicit parameter's byte into temp
in preparation for swapping. */
tempByte = source.getRegisterByte();
/* Put the implicit parameter's byte into
the explicit parameter. */
source.setRegisterByte(this.getRegisterByte());
/* Now that the explicit parameter's byte
has been updated, its byte can be used
to set the text in its text field. */
source.myField.setText(source.getRegisterByte().getStringFromByte()
);
•
•
•
•
•
•
•
•
/*
Put the temp byte into
the implicit parameter. */
this.setRegisterByte(tempByte);
/* Now that the implicit parameter's byte
has been updated, its byte can be used
to set the text in its text field. */
this.myField.setText(this.getRegisterByte().getStringFromByte());
}
60
• Finally, the listener which is attached to the
text fields is another place where in the past a
call to repaint() might have been expected.
• Like the action listener given above, this code
still shows a call to repaint(), but it has been
commented out.
• The code for the text field listener is shown on
the next overhead.
61
•
•
•
•
•
•
•
•
•
private class TextFieldListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String inputString = myField.getText();
registerByte.setByteToThisString(inputString);
//myField.repaint();
}
}
62
• The calls to repaint() have been shown
commented out in this example in order to
emphasize the change.
• In all future examples there will simply be no calls
to repaint() in the code.
• Although structurally different, from the
programmer’s point of view this has something in
common with the point made earlier when the
Echo programs stopped containing a loop.
• The system is taking care of stuff for us and we
don’t have to worry about it anymore.
63
26.4 Adding Labels and Using the
GridLayout
64
MiscLabel
• This program includes labels on the text fields.
• It also puts each visual component into its
own panel and then arranges those subpanels
in a grid layout in the MiscLabelPanel in order
to get a desirable appearance for the
application.
• A screenshot of the application is shown on
the next overhead.
65
66
• Using a GridLayout turns out to be very
convenient.
• If you run the example and then resize its
frame on the screen, you will see that the
system automatically arranges the
components in the grid to fit the new frame
size.
• This is shown on the next overhead.
67
68
• The UML diagram for MiscLabel shows that
everything that appears in the main panel is
put into its own instance of JPanel, and the
main panel has a grid layout.
• The UML diagram is given on the next
overhead.
69
MiscLabel
1
MiscLabelFrame
1
ContentPane
1
MiscLabelPanel
GridLayout
1
1
1
2
1
JPanel
2
1
MiscLabelRegister
1
MiscLabelByte
1
JPanel
1
JLabel
2
1
2
1
JTextField
JPanel
1
JButton
1
MiscButtonListener
1
TextFieldListener
70
• The MiscLabelPanel constructor illustrates the
syntax for creating labels.
• It also illustrates the syntax for using the grid
layout.
• When such a layout is constructed, the
number of rows and the number of columns
are given as parameters.
71
• The components that are added to a panel
with this layout are displayed row by row.
• The code includes comments which point out
the positions in the grid of components added
to the panel.
• The code is given on the following overheads.
72
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
public MiscLabelPanel()
{
registerA = new MiscLabelRegister("11110000");
registerB = new MiscLabelRegister("00001111");
/*
/*
/*
This makes a 3X2 grid. */
setLayout(new GridLayout(3, 2));
JLabel labelA = new JLabel("Register A", JLabel.LEFT);
JPanel labelPanelA = new JPanel();
labelPanelA.add(labelA);
This goes into position (1, 1). */
add(labelPanelA);
JPanel regPanelA = new JPanel();
regPanelA.add(registerA.getMyField());
This goes into position (1, 2). */
add(regPanelA);
73
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
/*
/*
JLabel labelB = new JLabel("Register B", JLabel.LEFT);
JPanel labelPanelB = new JPanel();
labelPanelB.add(labelB);
This goes into position (2, 1). */
add(labelPanelB);
JPanel regPanelB = new JPanel();
regPanelB.add(registerB.getMyField());
This goes into position (2, 2). */
add(regPanelB);
JButton myButton = new JButton("Swap");
MiscButtonListener myButtonListener = new
MiscButtonListener();
myButton.addActionListener(myButtonListener);
JPanel buttonPanel = new JPanel();
buttonPanel.add(myButton);
/* This goes into position (3, 1). */
add(buttonPanel);
}
74
• Courtesy of John Campbell and Francisco de
Zurburan: St. Lucy
75
76
77
The End
78