CheckboxGroup: Example import java.applet.Applet; import java.awt.*; public class CheckboxGroups extends Applet { public void init { setLayout new GridLayout4, 2; setBackgroundCo
Trang 1LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
Nguyễn Thị Thu Trang
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
Bài 10 Đồ họa và xử lý sự kiện
Trang 2Nội dung
1 Lập trình đồ họa và AWT
2 Xử lý sự kiện
3 Quản lý bố cục (layout)
Trang 3Lập trình đồ họa trong Java
• Giúp tạo ra các ứng dụng có giao diện đồ họa với
nhiều các điều khiển như: Button, Textbox, Label,
Checkbox, List, Tree
• Java cũng cấp 2 thư viện lập trình đồ họa
▫ java.awt
▫ javax.swing
Trang 4giao diện đồ họa AWT có sẵn
Trang 6Windows và Layout Manager
• Container
▫ Hầu hết các cửa sổ đều là một Container có thể chứa các cửa sổ khác hoặc các thành giao diện đồ họa khác Canvas là một ngoại lệ
• Layout manager
▫ Container có một LayoutManager tự động thay đổi kích thước và vị trí
của các thành phần trong cửa sổ
▫ Có thể thay đổi các hành vi của layout manager hoặc vô hiệu nó hoàn toàn
Trang 7Lớp Canvas
• Mục đích chính
▫ Một vùng để vẽ
▫ Một Component được tùy biến không cần chứa các Component khác (ví dụ như một image button)
• Default Layout Manager - None
▫ Canvas không thể chứa bất kỳ một Component nào
• Tạo và sử dụng
▫ Tạo Canvas
Canvas canvas = new Canvas();
Hoặc tạo ra lớp con của Canvas đã sửa việc vẽ thông qua phương thức paint:
SpecializedCanvas canvas = new SpecializedCanvas ();
Trang 8Lớp Canvas (2)
• Tạo và sử dụng (2)
▫ Kích thước của Canvas
canvas setSize(width, height);
▫ Thêm Canvas vào cửa sổ Window hiện tại
Trang 9Ví dụ về Canvas
import java.awt.*;
/** A Circle component built using a Canvas */
public class Circle extends Canvas {
private int width, height;
public Circle(Color foreground, int radius) {
public void paint(Graphics g) {
g.fillOval(0, 0, width, height);
}
public void setCenter( int x, int y) {
setLocation(x - width/2, y - height/2);
}
Trang 10Lớp Component
• Lớp cha trực tiếp của lớp Canvas
• “Tổ tiên” (Ancestor) của tất cả các loại Window
• Các phương thức hay được dùng
▫ getBackground/setBackground
▫ getForeground/setForeground
Thay đổi hoặc lấy về màu vẽ mặc định
Color được kế thừa từ đối tượng Graphics của component
▫ getFont/setFont
Trả về hoặc thiết lập font hiện tại
Được kế thừa từ đối tượng Graphics của component
▫ paint
Trang 11Lớp Component (2)
• Các phương thức hay được sử dụng
▫ setVisible
Hiển thị (true) hoặc ẩn (false) component
Especially useful for frames and dialogs
▫ setSize/setBounds/setLocation
▫ getSize/getBounds/getLocation
Physical aspects (size and position) of the component
▫ list
Prints out info on this component and any components it contains;
useful for debugging
Trang 12Lớp Panel
• Mục đích chính
▫ Để nhóm/tổ chức các thành phần
▫ Một thành phần yêu cầu các thành phần khác nhúng bên trong
• Default Layout Manager - FlowLayout
▫ Co các thành phần theo preferred size
▫ Đặt chúng từ trái sang phải theo các hàng được căn giữa
• Tạo và sử dụng
▫ Tạo Panel
Panel panel = new Panel();
▫ Thêm các Components vào Panel
panel.add(someComponent);
panel.add(someOtherComponent);
Trang 13Lớp Panel (2)
• Tạo và sử dụng (2)
▫ Thêm Panel vào Container
Bên ngoài một container
▫ container.add(panel);
Từ bên trong container
▫ add(panel);
• Chú ý thiếu phương thức setSize
▫ Các thành phần bên trong quyết định kích thước của panel;
panel không thể to hơn kích thước cần thiết để chứa các thành phần
▫ Một panel không chứa thành phần nào có kích thước 0
Trang 14Không có/Có Panel
import java.applet.Applet;
import java.awt.*;
public class ButtonTest1 extends Applet
{
public void init() {
String[] labelPrefixes = { "Start" ,
"Stop" , "Pause" , "Resume" };
for ( int i=0; i<4; i++) {
add( new Button(labelPrefixes[i] +
" Thread1" ));
}
for ( int i=0; i<4; i++) {
add( new Button(labelPrefixes[i] +
for ( int i=0; i<4; i++) { p2.add( new
Button(labelPrefixes[i] + "
Thread2" ));
} add(p1);
Trang 16Lớp Frame và Dialog
▫ A simplified Frame (no cursor, menu, icon image)
▫ A modal Dialog that freezes interaction with other AWT components until it is closed
Trang 17AWT GUI Controls
▫ you don’t override paint
• Positioned by layout manager
• Controls adopt look and feel of underlying
Trang 18Buttons
▫ Button(), Button(String buttonLabel)
The button size (preferred size) is based on the height and width of the label in the current font, plus some extra space determined by the OS
▫ getLabel/setLabel
Retrieves or sets the current label
If the button is already displayed, setting the label does not automatically reorganize its Container
The containing window should be invalidated and validated to force
a fresh layout
someButton setLabel ("A New Label");
Trang 19 Low-level event handling
▫ getForeground/setForeground
▫ getBackground/setBackground
▫ getFont/setFont
Trang 20Button: Example
public class Buttons extends Applet {
private Button button1, button2, button3;
public void init() {
button1 = new Button( "Button One" );
button2 = new Button( "Button Two" );
button3 = new Button( "Button Three" );
Trang 21 Creates an initially unchecked checkbox with no label
▫ Checkbox(String checkboxLabel)
Creates a checkbox (initially unchecked) with the specified label; see setState for changing it
▫ Checkbox(String checkboxLabel, boolean state)
Creates a checkbox with the specified label
The initial state is determined by the boolean value provided
A value of true means it is checked
Trang 22for ( int i=0; i<12; i++) {
box = new Checkbox( "Checkbox " + i);
Trang 23Other Checkbox Methods
• getState/setState
▫ Retrieves or sets the state of the checkbox: checked (true) or unchecked (false)
• getLabel/setLabel
▫ Retrieves or sets the label of the checkbox
▫ After changing the label invalidate and validate the
window to force a new layout (same as button)
• addItemListener/removeItemListener
▫ Add or remove an ItemListener to process ItemEvents in itemStateChanged
Trang 25CheckboxGroup: Example
import java.applet.Applet;
import java.awt.*;
public class CheckboxGroups extends Applet {
public void init() {
setLayout( new GridLayout(4, 2));
setBackground(Color.lightGray);
setFont( new Font( "Serif" , Font.BOLD, 16));
add( new Label( "Flavor" , Label.CENTER));
add( new Label( "Toppings" , Label.CENTER));
CheckboxGroup flavorGroup = new CheckboxGroup();
add( new Checkbox( "Vanilla" , flavorGroup, true ));
add( new Checkbox( "Colored Sprinkles" ));
add( new Checkbox( "Chocolate" , flavorGroup, false ));
add( new Checkbox( "Cashews" ));
add( new Checkbox( "Strawberry" , flavorGroup, false ));
add( new Checkbox( "Kiwi" ));
}
}
Trang 26List Boxes
• Constructors
▫ List ( int rows , boolean multiSelectable )
Creates a listbox with the specified number of visible rows
Depending on the number of item in the list (addItem or add), a scrollbar is automatically created
The second argument determines if the List is multiselectable
▫ List ()
Creates a single-selectable list box with a platform-dependent number of rows and a platform-dependent width
▫ List ( int rows )
Creates a single-selectable list box with the specified number
of rows and a platform-dependent width
Trang 27List Boxes: Example
setFont( new Font( "SansSerif" , Font.BOLD, 18));
List list1 = new List(3, false );
list1.add( "Vanilla" );
list1.add( "Chocolate" );
list1.add( "Strawberry" );
add(list1);
List list2 = new List(3, true );
list2.add( "Colored Sprinkles" );
Trang 28Other GUI Controls
• Choice Lists (Combo Boxes)
• Textfields
• Text Areas
• Labels
Trang 29Nội dung
1 Tổng quan về đồ họa
2 Xử lý sự kiện
3 Quản lý bố cục (layout)
Trang 30AWT Event Handling Hierarchy
Trang 31Chiến lược xử lý sự kiện
• Xác định loại lắng nghe (listener) cần thiết
▫ 11 loại lắng nghe chuẩn của AWT: ActionListener, AdjustmentListener, ComponentListener, ContainerListener, FocusListener, ItemListener, KeyListener, MouseListener, MouseMotionListener,
TextListener,WindowListener
• Định nghĩa một lớp cho loại lắng nghe đó
▫ Thực thi giao diện tương ứng, VD: KeyListener, MouseListener
▫ Kế thừa lớp tương ứng, VD: KeyAdapter, MouseAdapter,
• Đăng ký một đối tượng cho lớp lắng nghe của bạn với cửa sổ
▫ w.addXxxListener(new MyListenerClass());
Ví dụ addKeyListener, addMouseListener
Trang 32Standard AWT Event Listeners
Adapter Class Listener (If Any) Registration Method
ActionListener addActionListener
AdjustmentListener addAdjustmentListener
ComponentListener ComponentAdapter addComponentListener
ContainerListener ContainerAdapter addContainerListener
FocusListener FocusAdapter addFocusListener
ItemListener addItemListener
KeyListener KeyAdapter addKeyListener
MouseListener MouseAdapter addMouseListener
MouseMotionListener MouseMotionAdapter addMouseMotionListener TextListener addTextListener
WindowListener WindowAdapter addWindowListener
Trang 33Lớp Listener riêng – VD đơn giản
Listener không cần gọi bất kỳ phương thức nào của cửa sổ mà nó thuộc về
Trang 34Lớp Listener riêng – VD đơn giản (2)
import java.awt event *;
public class ClickListener extends MouseAdapter {
public void mousePressed(MouseEvent event ) {
System out println( "Mouse pressed at (" +
event getX() + "," + event getY() + ")." );
}
}
Trang 35Tổng quát hóa trường hợp đơn giản
• Nếu ClickListener muốn vẽ một hình tròn tại vị trí
chuột được nhấn?
• Tại sao không thể gọi phương thức getGraphics để
lấy về đối tượng Graphics để vẽ
• Giải pháp tổng quát:
▫ Gọi event.getSource để lấy về một tham chiếu tới cửa sổ
hoặc thành phần GUI tạo ra sự kiện
▫ Ép kết quả trả về theo ý muốn
▫ Gọi các phương thức trên tham chiếu đó
Trang 36Lớp Listener riêng – VD tổng quát
import java.applet.Applet;
import java.awt.*;
public class CircleDrawer1 extends Applet {
public void init() {
setForeground(Color.blue);
addMouseListener(new CircleListener());
}
}
Trang 37Lớp Listener riêng – VD tổng quát (2)
import java.applet.Applet;
import java.awt.*;
import java.awt event *;
public class CircleListener extends MouseAdapter {
private int radius = 25;
public void mousePressed(MouseEvent event ) {
Applet app = (Applet) event getSource();
Trang 38Cách 2: Thực thi giao diện Listener
import java.applet.Applet;
import java.awt.*;
import java.awt event *;
public class CircleDrawer2 extends Applet implements MouseListener { private int radius = 25;
public void init() { setForeground(Color.blue);
addMouseListener( this );
}
Trang 39Cách 2: Thực thi giao diện Listener (2)
public void mouseEntered(MouseEvent event ) {}
public void mouseExited(MouseEvent event ) {}
public void mouseReleased(MouseEvent event ) {}
public void mouseClicked(MouseEvent event ) {}
public void mousePressed(MouseEvent event ) { Graphics g = getGraphics();
g.fillOval( event getX()-radius, event getY()-radius,
2*radius, 2*radius);
} }
Trang 40Ưu và nhược điểm
• Tách riêng lớp Listener
Cần thêm bước gọi các phương thức trong cửa sổ chính
• Cửa sổ chính thực thi giao diện Listener
Trang 41(Tổng kết)
Adapter Class Listener (If Any) Registration Method
ActionListener addActionListener
AdjustmentListener addAdjustmentListener
ComponentListener ComponentAdapter addComponentListener
ContainerListener ContainerAdapter addContainerListener
FocusListener FocusAdapter addFocusListener
ItemListener addItemListener
KeyListener KeyAdapter addKeyListener
MouseListener MouseAdapter addMouseListener
MouseMotionListener MouseMotionAdapter addMouseMotionListener TextListener addTextListener
WindowListener WindowAdapter addWindowListener
Trang 44▫ Phát hiện ra các sự kiện liên quan đến bàn phím
keyPressed(KeyEvent event) any key pressed down
keyReleased(KeyEvent event) any key released
keyTyped(KeyEvent event) key for printable char released
Trang 45 mouseClicked(MouseEvent event) Nhả chuột khi không kéo
Áp dụng khi nhả chuột mà không di chuyển từ khi nhấn chuột
▫ Xử lý các sự kiện di chuyển chuột
mouseMoved(MouseEvent event)
mouseDragged(MouseEvent event)
Trang 47import java.applet.Applet;
import java.awt.*;
import java.awt event *;
public class SimpleWhiteboard extends Applet { protected int lastX=0, lastY=0;
public void init() { setBackground(Color.white);
setForeground(Color.blue);
addMouseListener( new PositionRecorder());
addMouseMotionListener( new LineDrawer());
} protected void record( int x, int y) { lastX = x; lastY = y;
}
Trang 48Ví dụ: Simple Whiteboard (2)
private class PositionRecorder extends MouseAdapter {
public void mouseEntered(MouseEvent event) {
requestFocus(); // Plan ahead for typing
record(event.getX(), event.getY());
}
public void mousePressed(MouseEvent event) {
record(event.getX(), event.getY());
}
}
Trang 49Ví dụ: Simple Whiteboard (3)
private class LineDrawer extends MouseMotionAdapter
{
public void mouseDragged(MouseEvent event) {
int x = event.getX();
int y = event.getY();
Trang 50Whiteboard: Thêm các sự kiện bàn phím
import java.applet.Applet;
import java.awt.*;
import java.awt event *;
public class Whiteboard extends SimpleWhiteboard { protected FontMetrics fm;
public void init() { super.init();
Font font = new Font( "Serif" , Font.BOLD, 20);
setFont(font);
fm = getFontMetrics(font);
addKeyListener( new CharDrawer());
}
Trang 51Whiteboard: Thêm các sự kiện bàn phím (2)
private class CharDrawer extends KeyAdapter {
// When user types a printable character,
// draw it and shift position rightwards.
public void keyTyped(KeyEvent event ) {
String s =
String.valueOf( event getKeyChar());
getGraphics().drawString(s, lastX, lastY);
record(lastX + fm.stringWidth(s), lastY);
}
}
}
Trang 52Nội dung
1 Tổng quan về đồ họa
2 Xử lý sự kiện
3 Quản lý bố cục (layout)
Trang 53Tổng quan về quản lý bố cục
• Làm thế nào để các bộ quản lý layout (layout
manager) đơn giản hóa việc thiết kế giao điện người
dùng?
• Sử dụng các layout manager chuẩn
▫ FlowLayout , BorderLayout , CardLayout, GridLayout ,
GridBagLayout , BoxLayout
• Định vị trí cho các thành phần bằng tay
• Các chiến thuật để sử dụng layout manager hiệu quả
• Sử dụng các thành phần invisible