f27sb2 software development 2 lecture 6: java guis 5

Post on 12-Jan-2016

221 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

F27SB2 Software Development 2

Lecture 6: Java GUIs 5

Buttons and enumerated types

• often want to manipulate a problem specific set of values

• e.g. a student my fail, pass, gain merit or gain distinction in an exam

• useful if we had distinct values for each possibility

• enumerated type– set of discrete values with textual identifiers

Buttons and enumerated types

• could use distinct variable names• e.g. exam grades: fail, pass, merit, distinction• could give each variable a distinct value from

an existing class• e.g. exam grades as integer final int fail = 0;final int pass = 1;final int merit = 2;final int distinction = 3;

Buttons and enumerated types

• can now use variables as if they were values• disadvantage– no distinct class for the enumerated type

• can use any value from representation class in context where enumerated type value is expected

• e.g. int mygrade = 27;

Buttons and enumerated types

• better to define a new classclass Grade{ private int rep; public Grade(int r) { rep = r; }}...Grade fail = new Grade(0);Grade pass = new Grade(1);...

Buttons and enumerated types

• a variable of a class can only be set to values from that class

Grade mygrade = 27; // type error!Grade mygrade = pass; // OK!

• still problems of input/output– everything must be represented in files/from

keyboard/on screen using characters– need to convert characters to/from enumerated

type– user can enter invalid characters

Buttons and enumerated types

Grade readGrade(BufferedReader f){ String g = f.readLine().trim(); if(g.equals(”fail”)) return fail; if(g.equals(”pass”)) return pass; ... throw new Exception(“bad grade”);}

Buttons and enumerated types

• replace string input with JButtons• one JButton for each value• select JButton to enter value• no need to check validity• user can only select from available JButtons• no need to convert string

Buttons and enumerated types

• e.g. count fruit consumption

• JButton - select fruit • JLabel - display count

fruit count

JFrame

JButtonJLabel

Buttons and enumerated types

• represent each item of fruit as member of a class with own:– JButton– JLabel– integer count

class Item{ JButton b; JLabel c; int count;

Buttons and enumerated types

• constructor to initialise JButton, count, and JLabel

public Item(String name) { b = new JButton(name); b.setFont(new Font("sanserif",Font.BOLD,24)); b.setForeground(Color.white); b.setBackground(Color.black); count=0; c = new JLabel("0",JLabel.CENTER); c.setFont(new Font("sanserif",Font.BOLD,24)); c.setBackground(Color.white); }}

Buttons and enumerated types

• NB no separate String field for name– hold name on JButton– use getText if we need the name

• class for Fruit enumerated typeclass Fruit extends Frame implements ActionListener

• constructor to:– create each value– add each JLabel and JButton to JFrame– add ActionListener for each JButton

 

Buttons and enumerated types

• could use individual variables{ Item papaya = new Item(“papaya”); Item peach = new Item(“peach”);

...  • for many Items use an array { Item [] f;  String [] names = {"papaya","peach","pear","persimmon", "physalis","pineapple","plum","pomegranite"};  final int FMAX = 8;

Buttons and enumerated types public Fruit() { f = new Item[FMAX];  setLayout(new GridLayout(FMAX,2));  for(int i=0;i<FMAX;i++) { f[i] = new Item(names[i]); add(f[i].b); f[i].b.addActionListener(this); add(f[i].c); } } 

Buttons and enumerated types

papaya 1

peach 1

pomegranite 221

f

0

1

FMAX

JButton bJLabel cint count

Buttons and enumerated types

• actionPerformed to:– identify JButton– update count & JLabel

  public void actionPerformed(ActionEvent e) { for(int i=0;i<FMAX;i++) if(e.getSource()==f[i].b) { f[i].count++; f[i].c.setText(f[i].count+""); } }}

Buttons and enumerated typesclass TestFruit{ public static void main(String [] args) throws IOException { ... }}

Numeric key pad

• use as front end to other programs• 10 decimal digit keys– 1-9 + 0

• clear key - Z(ero)• multiple digit display

Numeric key pad

1 2 3

4 5 6

7 8 9

Z 0

digit N digit 0

JFrame

JPanelof

JLabels

JPanelof

JButtons

Numeric key pad

• keep track of current value in display• key 0-9– shift all displays left – put new key value in right-most display– multiply current value by 10 and add new digit

Numeric key pad

• e.g. current value is 14

• user presses 5

• current value = 14 * 10 + 5 == 145

0 41

1 54

Numeric key pad

• Z– set all displays to 0 & set current value to 0

• use BorderLayout for JFrame• add display to North• add keys to Center• use GridLayout for JPanels

Numeric key pad

• make array of JLabels for display• make array of JButtons for keypad

class Keypad extends JFrame implements ActionListener{ JLabel [] display; final int DISPLAYS = 10;

JButton [] keys; JButton CLR; int value; final int KEYS = 10;  JPanel d,k; 

Numeric key pad JLabel setupLabel(String s) { JLabel l = new JLabel(s,JLabel.CENTER); l.setFont(new Font("Sansserif",Font.PLAIN,18)); l.setBackground(Color.white); l.setOpaque(true); return l; }  public JButton setupButton(String s,Container c) { JButton b = new JButton(s); b.setFont(new Font("Sansserif",Font.PLAIN,18)); b.setBackground(Color.white); b.setOpaque(true); b.addActionListener(this); c.add(b); return b; }

Numeric key pad

• map JLabels to display public Keypad() { int i; d = new JPanel(new GridLayout(1,DISPLAYS)); display = new JLabel[DISPLAYS]; for(i=0;i<DISPLAYS;i++) display[i]=setupLabel("0");

• add JLabels to display in reverse order

for(i=DISPLAYS-1;i>=0;i--) d.add(display[i]); add(BorderLayout.NORTH,d); 

Numeric key pad

• add keypad JButtons in order: 1-9, Z, 0

k = new JPanel(new GridLayout(4,3)); keys = new JButton[KEYS]; for(i=1;i<KEYS;i++) keys[i] = setupButton(i+"",k); CLR = setupButton("Z",k); keys[0] = setupButton("0",k); add(BorderLayout.CENTER,k);  value = 0; } 

Numeric key padpublic void actionPerformed(ActionEvent e) { if(e.getSource()==CLR) { value = 0; for(int i=0;i<DISPLAYS;i++) display[i].setText("0"); } else { for(int i=0;i<KEYS;i++) if(e.getSource()==keys[i]) 

• ith key selected so new digit has value i  { value=10*value+i; 

Numeric key pad

• shift text from display[j] to display[j+1]• lose text on leftmost display... for(int j=DISPLAYS-2;j>=0;j--) display[j+1]. setText(display[j].getText()); 

• set rightmost display to i display[0].setText(i+""); return; } } } }

Numeric keypad

Sliding blocks puzzle

• 8 square blocks with a distinctive mark on each block

• square tray with 3*3 block positions• arrange blocks in tray in some specified order

from some initial configuration• cannot pick blocks up• can only slide block into free space

Sliding blocks puzzle

1 2 3

4 5 6

7 8

1 2 3

4 5 6

7 8

1 2 3

4

5

6

7 8

1

2

3

4

5

6

7 8

c)

b)a)

d)

Sliding blocks puzzle

• represent tray as 3*3 grid of JButtons• numbered blocks• block in row i/column j has number: i*3+j+1

1 2 3

4 5 6

7 8

column: 0 1 2

row: 0

1

2

• block in row 0 column 0 = 0*3+0+1 = 1• block in row 0 column 1 = 0*3+1+1 = 2• block in row 0 column 2 = 0*3+2+1 = 3• block in row 1 column 0 = 1*3+0+1 = 4• block in row 1 column 1 = 1*3+1+1 = 5• block in row 1 column 2 = 1*3+2+1 = 6• block in row 2 column 0 = 2*3+0+1 = 7• block in row 2 column 1 = 2*3+1+1 = 8

Sliding block puzzle

• user selects JButton to “move” block into space

• program swaps text on selected JButton and space JButton

• can only move block if it is next to the space– i.e. in same row and block is to left/right of space– i.e. in same column and block is above/below

space

Sliding block puzzle

• suppose block is in row i and column j• suppose space is in row spaceI and column spaceJ

• block can move into space if: i==spaceI && (j==spaceJ-1 || j==spaceJ+1)||j==spaceJ && (i==spaceI-1 || i==spaceI+1)

Sliding blocks puzzleclass Blocks extends JFrame implements ActionListener{ JButton [][] blocks;

• remember row/column for space int spaceI,spaceJ;

public JButton setupButton(String s,Container c) { JButton b = new JButton(s); b.setFont(new Font("Sansserif",Font.PLAIN,18)); b.setBackground(Color.white); b.setOpaque(true); c.add(b); b.addActionListener(this); return b; }

Sliding blocks puzzle public Blocks() { setLayout(new GridLayout(3,3));  blocks = new JButton[3][3];

• set up each block with appropriate label for(int i=0;i<3;i++) for(int j=0;j<3;j++) blocks[i][j]= setupButton((i*3+j+1)+"",this);

• set up space JButton in bottom right corner blocks[2][2].setText(""); spaceI=2; spaceJ=2; }

Sliding blocks puzzle public void actionPerformed(ActionEvent e) { for(int i=0;i<3;i++) for(int j=0;j<3;j++) if(e.getSource()==blocks[i][j]) if((i==spaceI && (j==spaceJ-1 || j==spaceJ+1)) || (j==spaceJ && (i==spaceI-1 || i==spaceI+1)))

• set current space JButton text to text from selected JButton

{ blocks[spaceI][spaceJ]. setText(blocks[i][j].getText());

Sliding blocks puzzle

• remember row/column position of new space JButton and set text to blank

  spaceI=i; spaceJ=j; blocks[spaceI][spaceJ].setText(""); return; } }} class TestBlocks{ ... }

Sliding blocks puzzle

Noughts and crosses

• game played on 3*3 board• each player makes either “O”

or “X” mark• players take it in turns to

place mark on free grid square of their choice

• first player to place 3 marks in horizontal/vertical/diagonal straight line wins

X

O

X

O

Noughts and crosses

• represent board as 3*3 grid of JButtons– player presses JButton to make mark

messages

X

O O

X

JFrame

JLabel

JPanel of

JButtons

Noughts and crosses

• computers chooses/marks JButton in turn• after user plays:– check if legal square i.e. no mark– set mark– check if user wins – computer plays in next free square• if none then draw• many better algorithms

– check if computer wins

Noughts and crossesclass Noughts extends Frame implements ActionListener{ JButton [][] squares; JLabel messages; JPanel board;  public JButton setupButton(String s,Container c) { JButton b = new JButton(s); b.setFont(new Font("Sansserif",Font.PLAIN,24)); b.setBackground(Color.white); b.setOpaque(true); c.add(b); b.addActionListener(this); return b; }

Noughts and crosses public Noughts() { board = new JPanel(new GridLayout(3,3)); squares = new JButton[3][3]; for(int i=0;i<3;i++) for(int j=0;j<3;j++) squares[i][j]= setupButton("",board); add(BorderLayout.CENTER,board);

messages = new JLabel("Select a square to play X.", JLabel.CENTER); messages.setFont(new Font("Serif",Font.ITALIC,18)); messages.setBackground(Color.white); add(BorderLayout.NORTH,messages); }

Noughts and crosses boolean checkwin(String mark) { boolean rwin, cwin; for(int i=0;i<3;i++) { rwin=true; cwin=true; for(int j=0;j<3;j++)

• check next in row i { rwin=rwin && squares[i][j].getText().equals(mark);

• check next in column i cwin=cwin && squares[j][i].getText().equals(mark); } if(rwin || cwin) return true; }

Noughts and crosses

• check both diagonals return (squares[0][0].getText().equals(mark) && squares[1][1].getText().equals(mark) && squares[2][2].getText().equals(mark)) || (squares[0][2].getText().equals(mark) && squares[1][1].getText().equals(mark) && squares[2][0].getText().equals(mark)); }

Noughts and crosses

• return boolean to indicate whether or not computer could find a blank square

  boolean computerplay() { for(int i=0;i<3;i++) for(int j=0;j<3;j++) if(squares[i][j].getText().equals("")) { squares[i][j].setText("O"); return true; } return false; }

Noughts and crosses public void actionPerformed(ActionEvent e) { for(int i=0;i<3;i++) for(int j=0;j<3;j++) if(e.getSource()==squares[i][j]) if(squares[i][j].getText().equals("")) { squares[i][j].setText("X"); if(checkwin("X")) messages.setText("You win."); else if(!computerplay()) messages.setText("Draw."); else if(checkwin("O")) messages.setText("I win.");

Noughts and crosses else messages.setText("Select a square to play X."); return; } else { messages. setText("Can't play in that square."); return; } }} class TestNoughts{ ... }

Noughts and crosses

top related