nextprevious
Grafiska interaktiva applikationer
GRIP 2000Föreläsning 5
InnehållFörst går vi igenom avslutningen, bla med
exempel från föreläsning 4
AWTKomponenter
Layout
previous next 2
AWT-komponenter och layout
Klasshierarki AWT
Object
Component
Container List
Panel
Applet
Label
Window
Dialog Frame
Button Checkbox TextComponent
TextField TextArea
previous next 3
AWT-komponenter och layout
Grafiska komponenter• Det finns flera olika typer av komponenter i Java
– Button
– Checkbox
– List
– Choice
– Label
– TextField
– TextArea
– Scrollbar
• För illustration och exempel se exempel: komponenter nedan sidan 35
previous next 4
AWT-komponenter och layout
Containers• En container är en komponent som kan innehålla andra
komponenter• Ett objekt läggs in i containern med meddelandet
– add(component)
• Instanser av Panel brukar användas för att organisera komponenter på olika sätt inom appleten
panel1panel1 panel2panel2
previous next 5
AWT-komponenter och layout
Exampel: komponenter• Ett test av att skapa olika typer av komponenter och låta
det hela placeras automatiskt
previous next 6
AWT-komponenter och layout
... (den här gången varierar vi oss och gör det som en applet, fast koden blir ungefär densamma som för en Frame)
import java.awt.*;
import java.applet.*;
public class DemoComponents extends Applet {
private Button button;
private Checkbox checkbox;
private Label label;
private List list;
private Choice choice;
private Scrollbar scrollbar;
private TextField textField;
private TextArea textArea;
previous next 7
AWT-komponenter och layout
...
public void init() {
super.init();
resize(300, 200);
button = new Button("En knapp");
add(button);
checkbox = new Checkbox("En checkbox");
add(checkbox);
label = new Label("En label");
add(label);
previous next 8
AWT-komponenter och layout
...
list = new List();
list.addItem("List 1");
list.addItem("List 2");
add(list);
choice = new Choice();
choice.addItem("A");
choice.addItem("B");
add(choice);
scrollbar = new Scrollbar();
add(scrollbar);
previous next 9
AWT-komponenter och layout
...
textField = new TextField("Textfält");
add(textField);
textArea = new TextArea("Textruta", 4, 15);
add(textArea);
}
}
• Om du vill "göra klart" appleten– Skapa en HTML-fil och kör med en appletviewer eller
nätbläddrare
previous next 10
AWT-komponenter och layout
Layoutmanagers för att kontrollera placering av komponenter
LayoutManager
BorderLayout
GridLayout
GridBagLayout
CardLayout
FlowLayout
previous next 11
AWT-komponenter och layout
...• FlowLayout
– är default för Panelobjekt
– placerar komponenter från vänster till höger. Vid full rad så ny rad
• GridLayout– ser till att alla komponenter har samma storlek. Rutnät (rad, kolumn)
• BorderLayout– är default för Window-klasser (ex Frame och Dialog)
– Placerar komponenter i ”vädersträck”
• CardLayout– Placerar objekten i en ”kortlek” där endast ett kort i taget synlikt
• GridBagLayout– Mest generell (och komplex). Delar in ytan i flera celler.
– Använder restriktioner (eng. constraints) för att beskrivahur komponenter placeras samt deras utsträckning
previous next 12
AWT-komponenter och layout
Exempel: Flowlayoutimport java.awt.*;
import java.applet.*;
public class DemoFlowlayout extends Applet {
Button buttons[];
public void init() {
super.init();
setLayout(new FlowLayout());
buttons = new Button[10];
for (int i = 0; i < 10; i++) {
buttons[i] = new Button("Knapp " + i);
add(buttons[i]);
}
}
}
previous next 13
AWT-komponenter och layout
...• Layouten ”följer med” förändringar av fönsterstorlek
previous next 14
AWT-komponenter och layout
Exempel: Gridalyoutpublic class DemoGridlayout extends Applet {
Button buttons[];
public void init() {
super.init();
setLayout(new GridLayout(5, 2));
buttons = new Button[10];
for (int i = 0; i < 10; i++) {
buttons[i] = new Button("Knapp " + i);
add(buttons[i]);
}
}
}
previous next 15
AWT-komponenter och layout
Exempel: Borderlayoutpublic class DemoBorderlayout extends Applet {
public void init() {
super.init();
resize(300, 400);
setLayout(new BorderLayout());
add("North", new Button("Knapp " + "Norr"));
add("South", new Button("Knapp " + "Söder"));
add("East", new Button("Knapp " + "Öster"));
add("West", new Button("Knapp " + "Väster"));
add("Center", new Button("Knapp " + "Centrum"));
}
}
previous next 16
AWT-komponenter och layout
Metoder för att hantera komponenter• förutom layout kan komponenter också bla
– visas eller döljas• setVisible(boolean)
– göras aktiva eller passiva• setEnabled(boolean)
– omritas, ritas eller markeras som “korrupta”• repaint(), paint(Graphics), invalidate()
– layout kan anges för containerbaserade komponenter också
– fönster kan visas, läggas i för- eller bakgrunden, titel kan anges, mm• show(), toFront(), toBack()
– cursor kan ändras
– storlek kanges (tänk på layout null)
– ...
previous next 17
AWT-komponenter och layout
Blandat exempelimport java.awt.*;
import java.awt.event.*;
public class TestOfFrame extends Frame {public TestOfFrame(String s) {
super(s);}
protected void delay(int ms) {// Vi måste ta hand om exceptions, vilket görs med ett try-catch-par
try{
Thread.currentThread().sleep(ms);
}
catch(Exception e) {}
}
previous next 18
AWT-komponenter och layout
...
protected void testLayoutes() { /* Lite urartat visar vi hur man kan fråga om komponenter. I det här fallet vet vi att det är en Container och "kastar" */ Container panel = (Container) this.getComponents()[0]; int delayTime = 3000;
delay(delayTime);
panel.setLayout(new GridLayout(5, 4, 10, 20)); this.setTitle("Gridlayout"); this.validate();
delay(delayTime);
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 7, 7));
this.setTitle("Flowlayout"); this.validate();
Gridlayout
Flowlayout
previous next 19
AWT-komponenter och layout
...
Component[] panelComponents = panel.getComponents(); for (int i = 0; i < panelComponents.length; i++) {
Component component = panelComponents[i];component.setBounds((i % 5) * 40, i * 25, 50, 20);
}
delay(delayTime);
panel.setLayout(null); this.setTitle("null layout"); this.validate(); }
Ingen layout
previous next 20
AWT-komponenter och layout
...
public static void main(String args []){
TestOfFrame frame = new TestOfFrame("Test of frame layout"); Panel panel; frame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) {
System.exit(0);}
}); frame.setSize(200, 300); frame.show();
// Vi skapar en panel
panel = new Panel();frame.add(panel);
previous next 21
AWT-komponenter och layout
...
//Vi skapar några knappar for (int i = 0; i < 10; i++) {
Button button = new Button("Button-" +
new Integer(i).toString());panel.add(button);
// Alla knappar får bli "stängknappar"button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){
System.exit(0);
}});
/* För att ett nytt objekt skall visas på skärmen måste vi göravalidate på framen (repaint eller invalidate hjälper inte! Bug??)
*/ frame.validate();/* Vi skulle ju kunna göra validate efter slingan och visa alla nya knappar på en gång förstås! */
}
previous next 22
AWT-komponenter och layout
...
//Vi skapar några fält for (int i = 0; i < 10; i++) {
TextField field = new TextField("Field-" +
new Integer(i).toString());
panel.add(field); } // Den här gången gör vi "det" efter slingan frame.validate();
// Nu testar vi att ändra layouten frame.testLayoutes(); }}
previous next 23
AWT-komponenter och layout
Exempel: Studsande bollarimport java.applet.*;
import java.awt.*;
/** An applet that displays a simple animation */
public class BouncingCircle extends Applet implements Animation {
int x = 150, y = 50, r=50; // position and radius of the circle int dx = 11, dy = 7; // trajectory of circle
/** A timer for animation: call our animate() method every 100 milliseconds. Creates a new thread. */
AnimationTimer timer = new AnimationTimer(this, 100);
previous next 24
AWT-komponenter och layout
...
/** Draw the circle at its current position */
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillOval(x-r, y-r, r*2, r*2);
}
/** Move and bounce the circle and request a redraw.
* The timer calls this method periodically. */
public void animate() {
// Bounce if we've hit an edge.
if ((x - r + dx < 0) || (x + r + dx > bounds().width))
dx = -dx;
if ((y - r + dy < 0) || (y + r + dy > bounds().height))
dy = -dy;
previous next 25
AWT-komponenter och layout
...
// Move the circle.
x += dx; y += dy;
// Ask the browser to call our paint() method to draw the circle at its new position.
repaint();
}
/** Start the timer when the browser starts the applet */
public void start() { timer.start_animation(); }
/** Pause the timer when browser pauses the applet */
public void stop() { timer.pause_animation(); }
}
previous next 26
AWT-komponenter och layout
...
/** This interface for objects that can be animated by an AnimationTimer */
interface Animation { public void animate(); }
/** The thread class that periodically calls the animate() method */
class AnimationTimer extends Thread {
Animation animation; // The animation object we're serving as timer for
int delay; // How many milliseconds between "animation frames"
public AnimationTimer(Animation animation, int delay) {
this.animation = animation;
this.delay = delay;
}
previous next 27
AWT-komponenter och layout
...
public void start_animation() {
if (isAlive()) super.resume();
else start();
}
public void pause_animation() { suspend(); }
/** Loop forever, calling animate(), and then pausing the specified time. */
public void run() {
for(;;) {
animation.animate();
try { Thread.sleep(delay); }
catch (InterruptedException e) { ; }
}
}
}
previous next 28
AWT-komponenter och layout
Exempel: Studsande bollar med dubbelbuffringimport java.applet.*;
import java.awt.*;
/* An applet that displays a simple animation using double-buffering and clipping */
public class SmoothCircle extends Applet implements Runnable {
int x = 150, y = 100, r=50; // Position and radius of the circle
int dx = 8, dy = 5; // Trajectory of circle
Dimension size; // The size of the applet
Image buffer; // The off-screen image for double-buffering
Graphics bufferGraphics; // A Graphics object for the buffer
Thread animator; // Thread that performs the animation
boolean please_stop; // A flag asking animation thread to stop
previous next 29
AWT-komponenter och layout
... /** Set up an off-screen Image for double-buffering */
public void init() {
size = this.size();
buffer = this.createImage(size.width, size.height);
bufferGraphics = buffer.getGraphics();
}
previous next 30
AWT-komponenter och layout
... /** Draw the circle at its current position, using double-buffering
*/
public void paint(Graphics g) {
// Draw into the off-screen buffer.
bufferGraphics.setClip(g.getClip());
// clear the buffer
bufferGraphics.setColor(this.getBackground());
bufferGraphics.fillRect(0, 0, size.width, size.height);
bufferGraphics.setColor(Color.red);
// draw the circle
bufferGraphics.fillOval(x-r, y-r, r*2, r*2);
// Then copy the off-screen buffer onto the screen
g.drawImage(buffer, 0, 0, this);
}
previous next 31
AWT-komponenter och layout
...
/** Don't clear the screen; just call paint() immediately * It is important to override this method like this for double-
buffering */
public void update(Graphics g) {
paint(g);
}
/** The body of the animation thread */
public void run() {
while(!please_stop) {
// Bounce the circle if we've hit an edge.
if ((x - r + dx < 0) || (x + r + dx > size.width))
dx = -dx;
if ((y - r + dy < 0) || (y + r + dy > size.height))
dy = -dy;
// Move the circle.
x += dx; y += dy;
previous next 32
AWT-komponenter och layout
...
/* Ask the browser to call our paint() method to redraw the circle at its new position. Tell repaint what portion of the applet needs be redrawn: the rectangle containing the old circle and the the rectangle containing the new circle. These two redraw requests will be merged into a single call to paint() */
// repaint old position of circle
repaint(x-r-dx, y-r-dy, 2*r, 2*r);
// repaint new position of circle
repaint(x-r, y-r, 2*r, 2*r); // Now pause 1/10th of a second before drawing the circle again.
try { Thread.sleep(100); }
catch (InterruptedException e) { ; }
}
animator = null;
}
previous next 33
AWT-komponenter och layout
...
/** Start the animation thread */
public void start() {
if (animator == null) {
please_stop = false;
animator = new Thread(this);
animator.start();
}
}
/** Stop the animation thread */
public void stop() { please_stop = true; }