Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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