![]() |
2D1339 Programkonstruktion för F för F1, 2004-2005
progk04 |
![]() |
Övning 7
Uppgift: Skriv en klass Bok som beskriver böcker. Varje bok ska ha egenskaperna författare, titel och stulen. Stulen ska vara sann om boken är stulen (från biblioteket som vi ska bygga upp) och falsk annars. Då böckerna skapas är de naturligtvis inte stulna. Dessutom ska det finnas en metod läs() som man använder om man vill läsa boken. Då en bok läses är det 25% risk att den blir stulen.
Här följer ett program som försöker likna ett bibliotek. Det kräver den klass ni skrev i förra uppgiften. public class Huvudklass{ public static void main(String[] args){ Bibliotek biblan = new Bibliotek(); while(!biblan.allaStulna()){ biblan.läsAlla(); biblan.status(); } } } class Bibliotek{ private static final int maxAntalBöcker = 1000; private static int antalBöcker = 4; private Bok[] böcker; public Bibliotek(){ böcker = new Bok[maxAntalBöcker]; böcker[0] = new Bok("Mumintrollen","Jansson"); böcker[1] = new Bok("Flugornas herre","Golding"); böcker[2] = new Bok("Javaboken","Franzen"); böcker[3] = new Bok("Das Kapital","Marx"); } public boolean allaStulna(){ int böckerKvar = 0; for(int i = 0; i < antalBöcker; i++) if(!böcker[i].geStulen()) böckerKvar++; if(böckerKvar == 0) return true; else return false; } public void läsAlla(){ for(int i = 0; i < antalBöcker; i++) böcker[i].läs(); } public void status(){ for(int i = 0; i < antalBöcker; i++){ System.out.print(böcker[i].geTitel()+"\t"); if(böcker[i].geStulen()) System.out.println("\t Snodd"); else System.out.println("\t Ledig"); } System.out.println(); } }
Rörliga bollar
Ett program som låter bollar studsa i ett fönster. Illustrerar animering i lab2.
/*********************************************************** Exempel från laboration i kursen prg 1999. ***********************************************************/ /* Det här programmet visar en animation bestående av bollar i olika färger och storlekar. Programmet består av tre klasser: Klassen Ball beskriver en boll. Bollens färg, storlek och rörelsevektor representeras. Klassen BallCanvas är en målarduk (Canvas) på vilken bollarna rör sig. BallWindow beskriver ett fönster. Klassen innehåller också programmets main-metod. I main-metoden skapas ett nytt fönster som innehåller en BallCanvas. Därefter startas animeringen genom att anropa metoden run() i BallCanvas. Fil: BallWindow.java Bruk: java BallWindow & Version: 1.0, 981213 Författare: snilsson@nada.kth.se Ändringar: rosell@nada.kth.se, 030120 */ import java.awt.*; import java.awt.event.*; // Den här målarduken visar ett antal bollar som rör sig // med olika hastighet. Metoden run() startar animeringen. class BallCanvas extends Canvas { private static double FRICTION = 0.9995; private Ball ball1, ball2; public BallCanvas() { ball1 = new Ball( 100, 100, 5); ball1.setColor( Color.red); ball1.setMotion( 1.5, -2.0); ball2 = new Ball( 120, 80, 8); ball2.setColor( Color.blue); ball2.setMotion( 3.0, 5.0); } public void paint( Graphics g) { ball1.paint( g); ball2.paint( g); } private void slowDown( Ball ball) { ball.setMotion( FRICTION*ball.getDX(), FRICTION*ball.getDY()); } // Utför animeringen public void run() { while ( true) { ball1.move(); checkWall( ball1); slowDown( ball1); ball2.move(); checkWall( ball2); repaint(); // Vänta ett ögonblick (5 millisekunder) try { Thread.sleep( 5); } catch ( InterruptedException e) { // do nothing } } } // Kollar om bollen rör vid väggen och ändrar i så fall // rörelseriktningen. private void checkWall( Ball ball) { Dimension dim = getSize(); int width = dim.width; int height = dim.height; // Ändra rörelsevektorns x-komponent om bollen vidrör // någon av de vertikala väggarna. if (ball.getX() - ball.getRadius() < 0 || ball.getX() + ball.getRadius() > width) ball.setMotion( -ball.getDX(), ball.getDY()); // Ändra rörelsevektorns y-komponent om bollen vidrör // någon av de horisontella väggarna. if (ball.getY() - ball.getRadius() < 0 || ball.getY() + ball.getRadius() > height) ball.setMotion( ball.getDX(), -ball.getDY()); } } class Ball { private double x, y; // Bollens mittpunkt och radie private int radius; private double dx = 0.0; // Rörelsevektorns komponenter private double dy = 0.0; private Color color = Color.black; public Ball( int x, int y, int radius) { this.x = (double) x; this.y = (double) y; this.radius = radius; } public void setColor( Color color) { this.color = color; } public void setMotion( double dx, double dy) { this.dx = dx; this.dy = dy; } public int getRadius() { return radius; } public int getX() { return (int) x; } public int getY() { return (int) y; } public double getDX() { return dx; } public double getDY() { return dy; } public void move() { x += dx; y += dy; } public void paint( Graphics g) { g.setColor(color); g.fillOval((int) x - radius, (int) y - radius, 2 * radius, 2 * radius); } } class BallWindow extends Frame { public BallWindow() { // Man kan avsluta det här programmet genom att stänga // fönstret (Den här koden är mystisk och kan bara begripas // av den som känner till anonyma inre klasser. addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit( 0); } }); } public static void main( String[] args) { BallWindow window = new BallWindow(); BallCanvas canvas = new BallCanvas(); window.setSize( 200, 200); window.setResizable( false); window.setBackground( Color.white); window.setTitle( "BallWindow"); window.add( canvas); window.show(); canvas.run(); } }
Hastighetsstyrning med skjutreglage
Följande program modifierar bollprogrammet. En av bollarna styrs av mha en Scrollbar. Också nyttigt för lab 2.
/*********************************************************** Exempel från laboration i kursen prg 1999. ***********************************************************/ /* Det här programmet visar en animation bestående av bollar i olika färger och storlekar. Programmet består av tre klasser: Klassen Ball beskriver en boll. Bollens färg, storlek och rörelsevektor representeras. Klassen BallCanvas är en målarduk (Canvas) på vilken bollarna rör sig. BallWindow beskriver ett fönster. Klassen innehåller också programmets main-metod. I main-metoden skapas ett nytt fönster som innehåller en BallCanvas. Därefter startas animeringen genom att anropa metoden run() i BallCanvas. Fil: BallWindow.java Bruk: java BallWindow Version: 1.0, 98121 Författare: snilsson@nada.kth.s Ändringar: 2002-01-13 Utbyggt med en boll vars hastighet kan styras med ett skjutreglage */ import java.awt.*; import java.awt.event.*; // Den här målarduken visar ett antal bollar som rör sig // med olika hastighet. Metoden run() startar animeringen. class BallCanvas extends Canvas implements AdjustmentListener { private static double FRICTION = 0.9995; private Ball ball1; private ControlledBall ball2; public BallCanvas() { ball1 = new Ball( 100, 100, 5); ball1.setColor( Color.red); ball1.setMotion( 1.5, -2.0); ball2 = new ControlledBall( 120, 80, 8); ball2.setColor( Color.blue); ball2.setMotion( 3.0, 5.0); } public void paint( Graphics g) { ball1.paint( g); ball2.paint( g); } private void slowDown( Ball ball) { ball.setMotion( FRICTION*ball.getDX(), FRICTION*ball.getDY()); } // Utför animeringen public void run() { while (true) { ball1.move(); checkWall( ball1); slowDown( ball1); ball2.move(); checkWall( ball2); repaint(); // Vänta ett ögonblick (5 millisekunder) try { Thread.sleep( 5); } catch (InterruptedException e) { // do nothing } } } // Kollar om bollen rör vid väggen och ändrar i så fall // rörelseriktningen. private void checkWall( Ball ball) { Dimension dim = getSize(); int width = dim.width; int height = dim.height; // Ändra rörelsevektorns x-komponent om bollen vidrör // någon av de vertikala väggarna. if (ball.getX() - ball.getRadius() < 0 || ball.getX() + ball.getRadius() > width) ball.setMotion( -ball.getDX(), ball.getDY()); // Ändra rörelsevektorns y-komponent om bollen vidrör // någon av de horisontella väggarna. if (ball.getY() - ball.getRadius() < 0 || ball.getY() + ball.getRadius() > height) ball.setMotion( ball.getDX(), -ball.getDY()); } // Då Scrollbar:en modifieras anropas denna metod public void adjustmentValueChanged (AdjustmentEvent e) { // Längden av rörelsevektorn double d = Math.sqrt(ball2.getDX() * ball2.getDX() + ball2.getDY() * ball2.getDY()); // Del av maxvärdet // getValue() ger värdet från Scrollbaren, via AdjustmentEvent:et double s = (1.0 - 0.99 * e.getValue() / 255.0); // getDX() för att hastighetsvektorn ska ha samma riktning som innan ball2.setMotion(s * ball2.getDXMax() * ball2.getDX()/d, s * ball2.getDYMax() * ball2.getDY()/d); } } class Ball { private double x, y; // Bollens mittpunkt och radie private int radius; private double dx = 0.0; // Rörelsevektorns komponenter private double dy = 0.0; private Color color = Color.black; public Ball( int x, int y, int radius) { this.x = (double) x; this.y = (double) y; this.radius = radius; } public void setColor( Color color) { this.color = color; } public void setMotion( double dx, double dy) { this.dx = dx; this.dy = dy; } public int getRadius() { return radius; } public int getX() { return (int) x; } public int getY() { return (int) y; } public double getDX() { return dx; } public double getDY() { return dy; } public void move() { x += dx; y += dy; } public void paint( Graphics g) { g.setColor( color); g.fillOval( (int) x - radius, (int) y - radius, 2*radius, 2*radius); } } /* ControlledBall styrs med ett skjutreglage så att hastigheten är en bråkdel av maxhastigheten */ class ControlledBall extends Ball { private double dxMax = 5.0, dyMax = 5.0; public ControlledBall( int x, int y, int radius) { super( x, y, radius); } public double getDXMax() { return dxMax; } public double getDYMax() { return dyMax; } } class Studsboll extends Frame { public Studsboll() { // Man kan avsluta det här programmet genom att stänga // fönstret (Den här koden är mystisk och kan bara begripas // av den som känner till anonyma inre klasser. addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e) { System.exit( 0); } }); } public static void main( String[] args) { Studsboll window = new Studsboll(); BallCanvas canvas = new BallCanvas(); Scrollbar speedScroll = new Scrollbar( Scrollbar.VERTICAL, 100, 5, 0, 255); window.setSize(200, 200); window.setLayout( new BorderLayout()); window.setResizable( false); window.setBackground( Color.white); window.setTitle( "BallWindow"); window.add( "East", speedScroll); window.add( "Center", canvas); // Det är canvas (en BallCanvas) som lyssnar på Scrollbar:en speedScroll.addAdjustmentListener( canvas); window.show(); canvas.run(); } }
Femtonspelet
Följande program är det vanliga 15-spelet. 16 (4*4) rutor med 15 siffor i, en ruta tom. Det gäller att flytta siffrorna så att de hamnar i ordning. Här finns mycket nyttigt att hämta inför den frivilliga labben, som ju kan vara ett spel av något slag.
import java.awt.*; import java.awt.event.*; class Fifteen extends Frame { public static void main(String [] args) { Fifteen game15 = new Fifteen(); Square sq; Square [][] pos = new Square [4][4]; game15.setBackground(Color.red); game15.setLayout(new GridLayout(4, 4, 4, 4)); for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) if ((i != 3) || (j != 3)) { // !( j==3 && i==3) sq = new Square(String.valueOf(4*i+j+1), Label.CENTER, i, j, pos); sq.setBackground(Color.gray); pos[i][j] = sq; game15.add( sq); } sq = new Square("tom", Label.CENTER, 3,3, pos); sq.setBackground(Color.red); pos[3][3] = sq; game15.add(sq); game15.show(); } } class Square extends Label { public static Square TOM; int ipos, jpos; private Square [][] pos; // MousAdapter är en abstrakt klass som implementerar // gränssnittet MousListener. // Metoden mouseClicked(MousEvent e) anropas // då en mus som lyssnaren lyssnar på blivit nedtryckt. MouseListener l = new MouseAdapter() { public void mouseClicked(MouseEvent e) { //om en grannruta är tom skjut dit denna ruta System.out.println("Klick i "+ipos+", "+jpos); if (ipos < 3 && pos[ipos+1][jpos] == TOM) { exchange( ipos+1, jpos); } else if (ipos > 0 && pos[ipos-1][jpos] == TOM) { exchange( ipos-1, jpos); } else if (jpos < 3 && pos[ipos][jpos+1] == TOM) { exchange( ipos, jpos+1); } else if (jpos > 0 && pos[ipos][jpos-1] == TOM) { exchange( ipos, jpos-1); }; getParent().validate(); // getParent() - metod i Component, // returnerar Container:n som // innehåller komponenten. // validate() - metod i Container, // kontrollerar att Container:ns // layout fungerar. } }; Square (String t, int align, int i, int j, Square[][] p) { super(t, align); ipos = i; jpos = j; pos = p; if (t.equals("tom")) { TOM = this; System.out.println("TOM skapas med "+ipos+", "+jpos); } // Det är objektet l av den abstrakta klassen MousAdapter som // lyssnar på denna Label (Square). Varje Square har en eget // sådant objekt. addMouseListener(l); } void exchange(int i, int j) { Square sq; Fifteen game15 = (Fifteen) getParent(); //Byt (i, j) som är tom och this System.out.println("Byt med "+i+", "+j); pos[ipos][jpos] = TOM; TOM.ipos = ipos; TOM.jpos = jpos; pos[i][j] = this; ipos = i; jpos = j; boolean ready = true; game15.removeAll(); // removeAll() - metod i Container, // som tar bort alla komponenter i den. for(int ii = 0; ii < 4; ii++) for(int jj = 0; jj < 4; jj++) { game15.add(pos[ii][jj]); int kk = 4*ii+jj+1; if(ready){ if(kk == 16) ready = pos[ii][jj].getText().equals("tom"); else if(pos[ii][jj].getText().equals("tom")) ready = false; else if(kk != Integer.parseInt(pos[ii][jj].getText())) ready = false; } } if(ready) System.out.println("Spelet är klart!"); } }
Från JAVA API:Scrollbar
public Scrollbar(int orientation, int value, int visible, int minimum, int maximum) throws HeadlessException
The orientation argument must take one of the two
values Scrollbar.HORIZONTAL,
or Scrollbar.VERTICAL,
indicating a horizontal or vertical scroll bar, respectively.
The parameters supplied to this constructor are subject to the
constraints described in setValues(int, int, int, int).
orientation - indicates the orientation of the scroll bar.value - the initial value of the scroll barvisible - the size of the scroll bar's bubble, representing
the visible portion.minimum - the minimum value of the scroll barmaximum - the maximum value of the scroll bar
Upp till Alla övningar.