- 什麼是事件?用戶的哪些操作可能引發事件?簡述Java語言的委託事件模型。
事件就是用戶使用鼠標或鍵盤對窗口中的組件進行交互時所發生的事情。
如單擊按鈕、輸入文字、單擊鼠標等。
委託事件模型是指當事件所發生時,產生事件的對象即事件源,會把此“信息”轉給事件監聽者處理的一種方式,而這裏所指的“信息”事實上就是java.awt.event事件類庫裏某個類所創建的對象,我們把它稱爲“事件對象”(event object)。事件對象表示事件的內容,對象內部封裝了一個對事件源eventSource的引用和其他信息。 - 若要處理事件,就必須要有事件監聽者,通常哪些對象可以擔任監聽者?
1)讓包含“事件源”的對象來擔任監聽者;
2)定義內部類來擔任監聽者。 - Java語言把事件類分哪兩種?這兩種事件類的功能各是什麼?
1)語義事件:直接繼承自AWTEvent類
2)底層事件:繼承自ComponentEvent類 - 寫出組件所可能產生的事件的對應關係。
Button - ActionEvent
CheckBox - ActionEvent、ItemEvent
Component - ComponentEvent、FocusEvent、KeyEvent、MouseEvent
MenuItem - ActionEvent
Scroller - AdjustmentEvent
TextField - ActionEvent
TextArea - ActionEvent
Window - WindowEvent - 在進行事件處理時,可以使用多接口的方法,也可以儘可能地使用適配器類。使用適配器類的好處是什麼?
當需要對某種事件進行處理時,只需讓事件處理類繼承事件所對應的適配器類,覆蓋本次操作用到的事件處理方法即可,而不必實現無關的事件處理方法。 - 設計一個窗口,在窗口內擺放一個按鈕,當不斷地單擊該按鈕時,則在其上顯示它被單擊的次數。
import java.awt.*;
import java.awt.event.*;
public class exe13_6 {
static Frame frm = new Frame("習題13-6");
static Button btn = new Button("請點擊");
static int count = 1;
public static void main(String[] args) {
frm.setLayout(null);
frm.setSize(300, 200);
btn.setBounds(100, 50, 100, 100);
frm.add(btn);
frm.setVisible(true);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
btn.setLabel("已點擊" + count + "次");
count++;
}
});
}
}
- 設計一個窗口,在該窗口中添加一個List組件,該組件中有5門課程名稱的選項。然後再在窗口中添加一個文本區,當選擇List組件中的某個選項後,文本區中顯示對該課程的介紹;當雙擊List組件中的某個選項後,文本區中顯示該課程的開課時間。
import java.awt.*;
import java.awt.event.*;
public class exe13_7 extends Frame implements ItemListener, ActionListener {
static exe13_7 frm = new exe13_7();
static List list = new List();
static TextArea ta = new TextArea(5, 20);
public static void main(String[] args) {
frm.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 20));
frm.setSize(350, 200);
list.add("Course 1");
list.add("Course 2");
list.add("Course 3");
list.add("Course 4");
list.add("Course 5");
list.addItemListener(frm);
list.addActionListener(frm);
frm.add(list);
frm.add(ta);
frm.setVisible(true);
}
public void itemStateChanged(ItemEvent e) {
String course = list.getSelectedItem();
if (course == "Course 1") {
ta.setText("Course 1 introduction");
} else if (course == "Course 2") {
ta.setText("Course 2 introduction");
} else if (course == "Course 3") {
ta.setText("Course 3 introduction");
} else if (course == "Course 4") {
ta.setText("Course 4 introduction");
} else if (course == "Course 5") {
ta.setText("Course 5 introduction");
}
frm.setTitle("You choose [" + course + "]");
}
public void actionPerformed(ActionEvent e) {
String course = list.getSelectedItem();
if (course == "Course 1") {
ta.setText("Course 1 start time");
} else if (course == "Course 2") {
ta.setText("Course 2 start time");
} else if (course == "Course 3") {
ta.setText("Course 3 start time");
} else if (course == "Course 4") {
ta.setText("Course 4 start time");
} else if (course == "Course 5") {
ta.setText("Course 5 start time");
}
frm.setTitle("You double click [" + course + "]");
}
}
- 設計一個窗口,其中包含一個文本區、兩個複選框和3個橫向滾動條,其中滾動條用來調整紅、綠、藍三色的分量從0~255變化;兩個複選框分別用於設定把滾動條調出的顏色應用於文本的前景還是背景。
import java.awt.*;
import java.awt.event.*;
public class exe13_8 extends Frame implements AdjustmentListener, ItemListener {
static exe13_8 frm = new exe13_8();
static Scrollbar sbR = new Scrollbar(Scrollbar.HORIZONTAL);
static Scrollbar sbG = new Scrollbar(Scrollbar.HORIZONTAL);
static Scrollbar sbB = new Scrollbar(Scrollbar.HORIZONTAL);
static Checkbox cb1 = new Checkbox("foreground");
static Checkbox cb2 = new Checkbox("background");
static TextArea ta = new TextArea("TextArea", 10, 20);
final static int FOREGROUND = 0;
final static int BACKGROUND = 1;
static int ground = 0;
public static void main(String[] args) {
frm.setTitle("exe13_8");
frm.setLocation(200, 150);
frm.setLayout(new GridLayout(6,1));
frm.setSize(400, 300);
sbR.setValues(1, 1, 0, 255);
sbG.setValues(1, 1, 0, 255);
sbB.setValues(1, 1, 0, 255);
sbR.addAdjustmentListener(frm);
sbG.addAdjustmentListener(frm);
sbB.addAdjustmentListener(frm);
CheckboxGroup grp = new CheckboxGroup();
cb1.setCheckboxGroup(grp);
cb2.setCheckboxGroup(grp);
cb1.addItemListener(frm);
cb2.addItemListener(frm);
frm.add(ta);
frm.add(cb1);
frm.add(cb2);
frm.add(sbR);
frm.add(sbG);
frm.add(sbB);
frm.setVisible(true);
}
public void itemStateChanged(ItemEvent e) {
Checkbox cb = (Checkbox) e.getSource();
if (cb == cb1) ground = 0;
else if (cb == cb2) ground = 1;
}
public void adjustmentValueChanged(AdjustmentEvent e) {
int colorR = sbR.getValue();
int colorG = sbG.getValue();
int colorB = sbB.getValue();
if (ground == FOREGROUND) ta.setForeground(new Color(colorR, colorG, colorB));
else if (ground == BACKGROUND) ta.setBackground(new Color(colorR, colorG, colorB));
}
}
- 編寫一個應用程序,在其窗口內包含一個菜單條和一個文本區。菜單條包括“設置”和“操作”兩個菜單。“操作”菜單包括“退出”菜單項,當用戶選擇“退出”菜單項時,則關閉窗口退出整個應用程序的運行;“設置”菜單包括“字體”和“風格”兩個菜單項和一個“只讀”複選按鈕菜單項。“字體”菜單項包括TimesRoman、Courier和Helvetica3個子菜單項,“風格”菜單項包括“普通”、“黑體”、“斜體”3個子菜單項。當“只讀”菜單項未被選中時,用戶不能在文本區內輸入字符。當用戶選擇其他菜單項時,文本區內的文字隨之變化。
import java.awt.*;
import java.awt.event.*;
public class exe13_9 extends Frame implements ActionListener, ItemListener {
static exe13_9 frm = new exe13_9();
static MenuBar mb = new MenuBar();
static Menu m_settings = new Menu("設置");
static Menu m_operator = new Menu("操作");
static MenuItem mi_quit = new MenuItem("退出");
static Menu m_font = new Menu("字體");
static Menu m_style = new Menu("風格");
static CheckboxMenuItem cbmi = new CheckboxMenuItem("只讀");
static MenuItem mi_font1 = new MenuItem("TimeRoman");
static MenuItem mi_font2 = new MenuItem("Courier");
static MenuItem mi_font3 = new MenuItem("Helvetica");
static MenuItem mi_style1 = new MenuItem("普通");
static MenuItem mi_style2 = new MenuItem("黑體");
static MenuItem mi_style3 = new MenuItem("斜體");
static TextArea ta = new TextArea("菜單程序設計", 10, 30);
public static void main(String[] args) {
frm.setTitle("exe13_9");
frm.setLocation(100, 80);
frm.setLayout(null);
frm.setSize(260, 170);
frm.add(ta);
ta.setBounds(40, 65, 180, 80);
mb.add(m_settings);
mb.add(m_operator);
m_settings.add(m_font);
m_settings.add(m_style);
m_settings.addSeparator();
m_settings.add(cbmi);
m_operator.add(mi_quit);
m_font.add(mi_font1);
m_font.add(mi_font2);
m_font.add(mi_font3);
m_style.add(mi_style1);
m_style.add(mi_style2);
m_style.add(mi_style3);
frm.setMenuBar(mb);
mi_quit.addActionListener(frm);
cbmi.addItemListener(frm);
mi_font1.addActionListener(frm);
mi_font2.addActionListener(frm);
mi_font3.addActionListener(frm);
mi_style1.addActionListener(frm);
mi_style2.addActionListener(frm);
mi_style3.addActionListener(frm);
frm.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
MenuItem mi = (MenuItem) e.getSource();
if (mi == mi_quit) {
frm.dispose();
System.exit(0);
}
Font font = ta.getFont();
String fontName = font.getName();
int style = font.getStyle();
if (mi == mi_font1) {
fontName = "Times New Roman";
} else if (mi == mi_font2) {
fontName = "Courier";
} else if (mi == mi_font3) {
fontName = "Helvetica";
}
if (mi == mi_style1) {
style = Font.PLAIN;
} else if (mi == mi_style2) {
style = Font.BOLD;
} else if (mi == mi_style3) {
style = Font.ITALIC;
}
ta.setFont(new Font(fontName, style, font.getSize()));
}
public void itemStateChanged(ItemEvent e) {
boolean readOnly = cbmi.getState();
if (readOnly) {
ta.setEditable(false);
} else {
ta.setEditable(true);
}
}
}
- 在第9題的基礎上增加如下的功能:每當用戶選中“只讀”菜單項時,都將“字體”和“風格”兩個菜單項變成灰色,使之不能被選中;而每當“只讀”菜單項未被選中時,再將“字體”和“風格”兩個菜單項恢復成可選狀態。
import java.awt.*;
import java.awt.event.*;
public class exe13_10 extends Frame implements ActionListener, ItemListener {
static exe13_10 frm = new exe13_10();
static MenuBar mb = new MenuBar();
static Menu m_settings = new Menu("設置");
static Menu m_operator = new Menu("操作");
static MenuItem mi_quit = new MenuItem("退出");
static Menu m_font = new Menu("字體");
static Menu m_style = new Menu("風格");
static CheckboxMenuItem cbmi = new CheckboxMenuItem("只讀");
static MenuItem mi_font1 = new MenuItem("TimeRoman");
static MenuItem mi_font2 = new MenuItem("Courier");
static MenuItem mi_font3 = new MenuItem("Helvetica");
static MenuItem mi_style1 = new MenuItem("普通");
static MenuItem mi_style2 = new MenuItem("黑體");
static MenuItem mi_style3 = new MenuItem("斜體");
static TextArea ta = new TextArea("菜單程序設計", 10, 30);
public static void main(String[] args) {
frm.setTitle("exe13_9");
frm.setLocation(100, 80);
frm.setLayout(null);
frm.setSize(260, 170);
frm.add(ta);
ta.setBounds(40, 65, 180, 80);
mb.add(m_settings);
mb.add(m_operator);
m_settings.add(m_font);
m_settings.add(m_style);
m_settings.addSeparator();
m_settings.add(cbmi);
m_operator.add(mi_quit);
m_font.add(mi_font1);
m_font.add(mi_font2);
m_font.add(mi_font3);
m_style.add(mi_style1);
m_style.add(mi_style2);
m_style.add(mi_style3);
frm.setMenuBar(mb);
mi_quit.addActionListener(frm);
cbmi.addItemListener(frm);
mi_font1.addActionListener(frm);
mi_font2.addActionListener(frm);
mi_font3.addActionListener(frm);
mi_style1.addActionListener(frm);
mi_style2.addActionListener(frm);
mi_style3.addActionListener(frm);
frm.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
MenuItem mi = (MenuItem) e.getSource();
if (mi == mi_quit) {
frm.dispose();
System.exit(0);
}
Font font = ta.getFont();
String fontName = font.getName();
int style = font.getStyle();
if (mi == mi_font1) {
fontName = "Times New Roman";
} else if (mi == mi_font2) {
fontName = "Courier";
} else if (mi == mi_font3) {
fontName = "Helvetica";
}
if (mi == mi_style1) {
style = Font.PLAIN;
} else if (mi == mi_style2) {
style = Font.BOLD;
} else if (mi == mi_style3) {
style = Font.ITALIC;
}
ta.setFont(new Font(fontName, style, font.getSize()));
}
public void itemStateChanged(ItemEvent e) {
boolean readOnly = cbmi.getState();
if (readOnly) {
ta.setEditable(false);
m_font.setEnabled(false);
m_style.setEnabled(false);
} else {
ta.setEditable(true);
m_font.setEnabled(true);
m_style.setEnabled(true);
}
}
}
注:練習均爲博主自己編寫,不是標準答案,可能存在問題,可以留言討論。