《Java 2 实用教程》课程学习(9)
本章内容
- Java把由Component类的子类或间接子类创建的对象称为一个组件;
- Java把由Container类的子类或间接子类创建的对象称为一个容器;
- 可以向容器添加一个组件。 Component类提供了一个public方法:add(),一个容器可以调用这个方法将组件添加到该容器中。
- 容器调用removeAll()方法可以移去容器中的全部组件,调用remove(Component c)方法可以移去容器中参数指定的组件。
- 每当容器添加新的组件或移去组件时,应当让容器调用validate()方法,以保证容器中的组件能正确显示出来。
- 容器本身也是一个组件,因此可以把一个容器添加到另一个容器中,实现容器的嵌套。
9.1 Java窗口
import java.awt.*;//为组件添加
import javax.swing.*;//为容器添加
实例方法:
import javax.swing.*;
import java.awt.*;
public class Example {
public static void main(String args[]) {
JFrame window1=new JFrame("第一个窗口");
JFrame window2=new JFrame("第二个窗口");
window1.setBounds(60,100,188,108);
window2.setBounds(260,100,188,108);
window1.setVisible(true);
window1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window2.setVisible(true);
window2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
二、菜单条、菜单、菜单项
在一个窗口中添加多个菜单条,只有最后一个被添加。 不能用add方法将菜单条添加到窗口中。
2. JMenu 菜单
3. JMenuItem 菜单项
4. 嵌入子菜单
import java.awt.*;
class FirstWindow extends Frame
{
MenuBar menubar;
Menu menu;
MenuItem item1,item2;
FirstWindow(String s)
{
super(s);
setSize(160,170);
setLocation(120,120);
setVisible(true);
menubar=new MenuBar();
menu=new Menu("文件");
item1=new MenuItem();
item2=new MenuItem("保存");
menu.add(item1);
menu.add(item2);
menubar.add(menu);
setMenuBar(menubar);
}
}
public class Example6_1
{
public static void
main(String args[])
{
FirstWindow win
=new FirstWindow
("一个简单的窗口");
}
}
MenuBar menubar=new MenuBar();
Menu fileM=new Menu("File");
Menu editM=new Menu("Edit");
Menu toolsM=new Menu("Tools");
Menu helpM=new Menu("Help");
MenuItem fileM1=new MenuItem("New");
MenuItem fileM2=new MenuItem("Open");
MenuItem fileM3=new MenuItem("Save");
Menu fileM4=new Menu("Print");
CheckboxMenuItem fileM5=new CheckboxMenuItem("Quit",true);
MenuItem printM=new MenuItem("Preview");
MenuItem setM=new MenuItem("Setting");
menubar.add(fileM);
menubar.add(editM);
menubar.add(toolsM);
menubar.add(helpM);
fileM.add(fileM1); fileM.add(fileM2);
fileM.add(fileM3); fileM.add(fileM4);
fileM.addSeparator();
fileM4.add(printM); fileM4.add(setM);
fileM.add(fileM5);
//Example.java
public class Example {
public static void main(String args[]) {
WindowMenu win=new WindowMenu("带菜单的窗口",20,30,200,190);
}
}
//WindowMenu.java
import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class WindowMenu extends JFrame {
JMenuBar menubar;
JMenu menu,subMenu;
JMenuItem itemLiterature,itemCooking;
public WindowMenu(){}
public WindowMenu(String s,int x,int y,int w,int h) {
init(s);
setLocation(x,y);
setSize(w,h);
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
void init(String s){
setTitle(s);
menubar=new JMenuBar();
menu=new JMenu("菜单");
subMenu=new JMenu("体育话题");
itemLiterature=new JMenuItem("文学话题",new ImageIcon("a.gif"));
itemCooking=new JMenuItem("烹饪话题",new ImageIcon("b.gif"));
itemLiterature.setAccelerator(KeyStroke.getKeyStroke('A'));
itemCooking.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
InputEvent.CTRL_MASK));
menu.add(itemLiterature);
menu.addSeparator(); menu.add(itemCooking);
subMenu.add( new JMenuItem( "足球",new ImageIcon("c.gif") ) );
subMenu.add(new JMenuItem("篮球",new ImageIcon("d.gif")));
menu.add(subMenu);
menubar.add(menu);
setJMenuBar(menubar);
}
}
9.2 文本框组件
其它常用实例方法:
import java.awt.*;
class WindowText extends Frame
{
TextField text1,text2;
WindowText(String s)
{
super(s);
setLayout(new FlowLayout());
setBounds(100,100,150,150);
setVisible(true);
text1=new TextField("输入密码:",10);
text1.setEditable(false);
text2=new TextField(10);
text2.setEchoChar('*');
add(text1);
add(text2);
validate();
}
}
class Example
{
public static void main(String args[])
{
WindowText win=new WindowText("窗口");
}
}
学习组件除了了解组件的属性和功能外,一个更重要的方面是学习怎样处理组件上发生的界面事件。
程序需要对组件上发生的事件做出反应,从而实现特定的任务。
在学习处理事件时,必须很好地掌握事件源、监视器、处理事件的接口这三个概念,下面通过处理文本框这个具体组件上的事件,来掌握处理事件的基本原理。
二、TextField上的ActionEvent事件
3.处理事件的接口
4.ActionEvent类中的方法
方法一:
只有一个监视器 --- MyWindow,该监视器实现接口ActionListener
import java.awt.*;
import java.awt.event.*;
class MyWindow extends Frame implements ActionListener
{
TextField text1,text2,text3;
MyWindow(String s)
{ super(s);
setLayout(new FlowLayout());
text1=new TextField(10);
text2=new TextField(10);
text3=new TextField(10);
text2.setEditable(false);
text3.setEditable(false);
add(text1);
add(text2);
add(text3);
text1.addActionListener(this);
setBounds(100,100,150,150);
setVisible(true);
validate();
}
public void actionPerformed(ActionEvent e)
{
int n=0;
try
{
n=Integer.parseInt(text1.getText());
text2.setText(n+"的平方是:"+n*n);
text3.setText(n+"的立方是:"+n*n*n);
}
catch(NumberFormatException ee)
{
text1.setText("请输入数字字符");
}
}
}
class actionDemo
{ public static void main(String args[])
{ new MyWindow("窗口"); }
}
方法二:
有两个监视器----Policeman_2,Policeman_3,这两个监视器均实现接口ActionListener
class actionDemo
{
public static void main(String args[])
{
new MyWindow("窗口");
}
}
import java.awt.*;
import java.awt.event.*;
class MyWindow extends Frame
{ TextField text1,text2,text3;
PoliceMan_2 police_2=new PoliceMan_2(this);
PoliceMan_3 police_3=new PoliceMan_3(this);
MyWindow(String s)
{ super(s);
setLayout(new FlowLayout());
text1=new TextField(20);
text2=new TextField(20);
text2.setEditable(false);
text3=new TextField(20);
text3.setEditable(false);
add(text1); add(text2); add(text3);
text1.addActionListener(police_2);
text1.addActionListener(police_3);
setBounds(100,100,300,150);
setVisible(true);
validate();
}
}
class PoliceMan_2 implements ActionListener
{
MyWindow win;
PoliceMan_2(MyWindow a)
{win=a;
}
public void actionPerformed(ActionEvent e)
{
int n=0,m=0;
try{
n=Integer.parseInt(win.text1.getText());
m=n*n;
win.text2.setText(n+"的平方是:"+m);
}
catch(Exception ee)
{
win.text1.setText("请输入数字字符");
}
}
}
class PoliceMan_3 implements ActionListener
{
MyWindow win;
PoliceMan_3(MyWindow a)
{win=a;
}
public void actionPerformed(ActionEvent e)
{
int n=0,m=0;
try{
n=Integer.parseInt(win.text1.getText());
m=n*n*n;
win.text3.setText(n+"的立方是:"+m);
}
catch(Exception ee)
{
win.text1.setText("请输入数字字符");
}
}
}
9.3 标签
9.4 按钮组件
二、Button上的ActionEvent事件
import java.awt.*;
import java.awt.event.*;
class WindowButton extends Frame implements ActionListener
{ int number;
TextField 提示条,输入框;
Button nuttonGetNumber,buttonEnter;
WindowButton(String s)
{ super(s);
setLayout(new FlowLayout());
nuttonGetNumber=new Button("得到一个随机数");
提示条=new TextField("输入你的猜测:",10);
提示条.setEditable(false);
输入框=new TextField("0",10);
buttonEnter=new Button("确定");
add(nuttonGetNumber); add(提示条); add(输入框);
add(buttonEnter);
buttonEnter.addActionListener(this);
nuttonGetNumber.addActionListener(this);
setBounds(100,100,200,200);
setVisible(true);
validate();
}
public void actionPerformed(ActionEvent e)
{ if(e.getSource()==nuttonGetNumber)
{ number=(int)(Math.random()*100)+1;
提示条.setText("输入你的猜测:");
}
else if(e.getSource()==buttonEnter)
{ int guess;
try {
guess=Integer.parseInt(输入框.getText());
if(guess==number)
{ 提示条.setText("猜对了!");
}
else if(guess>number)
{ 提示条.setText("猜大了!");
输入框.setText(null);
}
else if(guess<number)
{ 提示条.setText("猜小了!");
输入框.setText(null);
}
}
catch(NumberFormatException event)
{
提示条.setText("请输入数字字符");
}
}
}
}
class Example6_7
{
public static void main(String args[])
{
new WindowButton("窗口");
}
}
输出结果:
9.5 面板
java.awt包中的类Panel 用来建立面板的,因为Panel类是Container的子类,因此,Panel类及它的子类的实例也是一个容器。一个容器里添加若干个组件后,再放到另一个容器里,称做容器的嵌套。
import java.awt.*;
import java.awt.event.*;
public class Example6_10
{
public static void main(String args[])
{
new WindowPanel();
}
}
class Mypanel extends Panel implements ActionListener
{
Button button;
Label lab;
Mypanel( )
{
lab=new Label("单击按钮关闭程序");
button=new Button("关闭程序");
add(lab);
add(button);
button.addActionListener(this);
setBackground(Color.pink); //设置面板的底色
}
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
class WindowPanel extends Frame
{
Mypanel panel1,panel2;
Button button;
WindowPanel( )
{
setLayout(new FlowLayout());
panel1=new Mypanel();
panel2=new Mypanel();
button=new Button("我不在那些面板里");
add(panel1);
add(panel2);
add(button);
setBounds(120,125,200,200);
setVisible(true);
validate();
}
}
9.6 Component类的常用方法
二、组件的大小与位置
三、组件的激活与可见性
四、组件的字体
获取计算机上字体名字的步骤:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String fontName[] = ge.getAvailableFontFamileNames();
9.7 布局
import java.awt.*;
class WindowFlow extends Frame
{ WindowFlow(String s)
{
super(s);
setBounds(100,100,400,320);
setVisible(true);
FlowLayout flow=new FlowLayout();
flow.setAlignment(FlowLayout.LEFT);
flow.setHgap(2);
flow.setVgap(8);
setLayout(flow);
for(int i=1;i<=10;i++)
{ add(new Button("i am "+i)); }
validate();
}
}
class Example
{ public static void main(String args[])
{ WindowFlow win=new WindowFlow("FlowLayout布局窗口");
}
}
二、BorderLayout布局
import java.awt.*;
class Example6_3
{ public static void main(String args[])
{ Frame win=new Frame("窗体");
BorderLayout border=new BorderLayout();
win.setLayout(border);
win.setBounds(100,100,300,300);
win.setVisible(true);
Button bSouth=new Button("我在南边"),
bNorth=new Button("我在北边"),
bEast =new Button("我在东边"),
bWest =new Button("我在西边"),
bCenter=new Button("我在中心");
win.add(bNorth,BorderLayout.NORTH);
win.add(bSouth,BorderLayout.SOUTH);
win.add(bEast,BorderLayout.EAST);
win.add(bWest,BorderLayout.WEST);
win.add(bCenter,BorderLayout.CENTER);
win.validate();
}
}
三、CardLayout布局
import java.awt.*;
class WindowFlow extends Frame
{ WindowFlow(String s)
{ super(s);
setBounds(100,100,150,120);
setVisible(true);
CardLayout card=new CardLayout();
setLayout(card);
String str="a";
add(str,new Button("button1"));
card.show(this,str);
validate();
}
}
class Example6_4
{
public static void main(String args[])
{
WindowFlow win=new WindowFlow("CardLayout布局窗口");
}
}
四、GridLayout布局
import java.awt.*;
class WindowFlow extends Frame
{ WindowFlow(String s)
{ super(s);
setBounds(100,100,150,120);
setVisible(true);
GridLayout grid=new GridLayout(3,2);
setLayout(grid);
for(int i=1;i<7;i++)
add(new Button("button"+i));
validate();
}
}
class Example6_5
{
public static void main(String args[])
{
new WindowFlow("GridLayout布局窗口");
}
}
五、BoxLayout布局
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
class WindowBox extends Frame
{
WindowBox(String s)
{ Frame frame=new Frame(s);
frame.setBounds(120,125,200,200);
frame.setVisible(true);
BoxLayout box=new BoxLayout(frame,BoxLayout.Y_AXIS);
frame.setLayout(box);
frame.add(new Button("button1"));
frame.add(new Button("button2"));
frame.add(new Button("button3"));
frame.add(new Button("button4"));
frame.validate();
}
}
public class Example6_7
{ public static void main(String args[])
{ new WindowBox("盒式布局"); }
}
Box类中的静态方法:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
class WindowBox extends Frame
{ Box baseBox ,boxV1,boxV2;
WindowBox()
{ setLayout(new FlowLayout());
setBounds(120,125,200,200);
setVisible(true);
boxV1=Box.createVerticalBox();
boxV1.add(new Label("输入您的姓名"));
boxV1.add(Box.createVerticalStrut(8));
boxV1.add(new Label("输入email"));
boxV1.add(Box.createVerticalStrut(8));
boxV1.add(new Label("输入您的职业"));
boxV2=Box.createVerticalBox();
boxV2.add(new TextField(16));
boxV2.add(Box.createVerticalStrut(8));
boxV2.add(new TextField(16));
boxV2.add(Box.createVerticalStrut(8));
boxV2.add(new TextField(16));
baseBox=Box.createHorizontalBox();
baseBox.add(boxV1);
baseBox.add(Box.createHorizontalStrut(10));
baseBox.add(boxV2);
add(baseBox);
validate();
}
}
public class Example6_8
{
public static void main(String args[])
{
new WindowBox();
}
}
六、null布局
9.8 文本区组件
class Example
{ public static void main(String args[])
{ WindowTextArea win=new WindowTextArea("窗口"); }
}
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class WindowTextArea extends Frame implements TextListener
{
TextArea text1,text2;
WindowTextArea(String s)
{
super(s);
setLayout(new FlowLayout());
text1=new TextArea(6,15);
text2=new TextArea(6,15);
add(text1);
add(text2);
text2.setEditable(false);
text1.addTextListener(this) ;
setBounds(100,100,150,150);
setVisible(true);
validate();
}
public void textValueChanged(TextEvent e)
{ if(e.getSource()==text1)
{
String s=text1.getText();
StringTokenizer fenxi=new StringTokenizer(s," ,'\n' ");
int n=fenxi.countTokens();
String a[]=new String[n];
for(int i=0;i<=n-1;i++)
{String temp=fenxi.nextToken();
a[i]=temp;
}
Arrays.sort(a); //按字典序从小到大排序
text2.setText(null); //刷新显示
for(int i=0;i<n;i++)
{
text2.append(a[i]+"\n");
}
}
}
}
二、TextArea上的TextEvent事件
9.9 画布
import java.awt.*;
import java.awt.event.*;
public class Example6_10
{
public static void main(String args[])
{
new WindowCanvas();
}
}
class Mycanvas extends Canvas
{
Mycanvas()
{ setSize(100,100); //设置画布的初始大小
setBackground(Color.cyan); } //设置画布的背景色
public void paint(Graphics g)
{g.setColor(Color.orange);
g.fillOval(12,12,45,60); } //在画布上绘制椭圆
}
class WindowCanvas extends Frame
{ Mycanvas canvas;
WindowCanvas()
{canvas=new Mycanvas( );
setLayout(new FlowLayout());
add(canvas);
setBounds(120,125,580,300);
setBackground(Color.pink); //设置窗口的背景色
setVisible(true);
validate();
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e)
{System.exit(0);}
}
); }
}
fillOval(left, top, w, h ) 前两个参数为该椭圆外接矩形的左上顶点,后两个参数为其外接矩形的宽和高,当后两个参数的值相等时为圆
paint方法与repaint方法
Component类有一个方法:public void paint(Graphics g),我们可以在其子类中重写这个方法。
当重写这个方法时,相应的java运行环境将参数g实例化,这样我们就可以在子类中使用g调用相应的方法,进行图形的绘制。
调用repaint()方法时,程序首先清除paint()方法以前所画的内容,然后再调用paint()方法,实际上当调用repaint()方法时,程序自动先调用update()方法,该方法的功能是:清除paint()方法以前所画的内容,然后再调用paint()方法。我们可以在子类中重写update()方法,根据需要选择清除哪些部分或保留哪些部分。
9.10 窗口事件
import java.awt.*;
import java.awt.event.*;
class MyFrame extends Frame implements WindowListener
{
TextArea text;
MyFrame(String s)
{
super(s);
setBounds(100,100,200,300);
setVisible(true);
text=new TextArea();
add(text,BorderLayout.CENTER);
addWindowListener(this);
validate();
}
public void windowActivated(WindowEvent e)
{
text.append("\n我被激活");
validate();
}
public void windowDeactivated(WindowEvent e)
{
text.append("\n我不是激活状态了");
setBounds(0,0,400,400);
validate();
}
public void windowClosing(WindowEvent e)
{
System.out.println("\n窗口正在关闭呢");
dispose();
}
public void windowClosed(WindowEvent e)
{
System.out.println("程序结束运行");
System.exit(0);
}
public void windowIconified(WindowEvent e)
{
text.append("\n我图标化了");
}
public void windowDeiconified(WindowEvent e)
{
text.append("\n我撤消图标化");
setBounds(0,0,400,400);
validate();
}
public void windowOpened(WindowEvent e) { }
}
class Example6_16
{
public static void main(String args[])
{
new MyFrame("窗口");
}
}
二、WindowAdapter适配器
当一个类实现一个接口时,即使不准备处理某个方法,也必须给出接口中所有方法的实现。适配器可以代替接口来处理事件,当Java提供处理事件的接口中多于一个方法时,Java相应地就提供一个适配器类,比如WindowAdapter类。适配器已经实现了相应的接口,例如WindowAdapter实现了WindowListener接口。因此,可以使用WindowAdapter的子类创建的对象做监视器,在子类中重写所需要的接口方法即可。
import java.awt.*;
import java.awt.event.*;
class MyFrame extends Frame
{ TextArea text;
Boy police;
MyFrame(String s)
{super(s);
police=new Boy(this);
setBounds(100,100,200,300); setVisible(true);
text=new TextArea(); add(text,BorderLayout.CENTER);
addWindowListener(police);
validate(); }
}
class Boy extends WindowAdapter
{
MyFrame f;
public Boy(MyFrame f)
{ this.f=f; }
public void windowActivated(WindowEvent e)
{ f.text.append("\n我被激活"); }
public void windowClosing(WindowEvent e)
{ System.exit(0);
}
}
class Example6_17
{
public static void main(String args[])
{
new MyFrame("窗口");
}
}
适配器经常这样使用:
import java.awt.*;
import java.awt.event.*;
class MyFrame extends Frame
{ TextArea text;
MyFrame(String s)
{ super(s);
setBounds(100,100,200,300);setVisible(true);
text=new TextArea(); add(text,BorderLayout.CENTER);
addWindowListener( new WindowAdapter( )
{ public void windowActivated(WindowEvent e)
{ text.append("\n我被激活"); }
public void windowClosing(WindowEvent e)
{ System.exit(0); }
}
);
validate();
}
}
9.11 ItemEvent事件
例子 ----简单的计算器
// Example.java
public class Example {
public static void main(String args[]) {
WindowOperation win=new WindowOperation();
win.setBounds(100,100,390,360);
win.setTitle("简单计算器"); }
}
// ComputerListener.java
import java.awt.event.*;
import javax.swing.*;
public class ComputerListener implements ActionListener {
JTextField inputNumberOne,inputNumberTwo;
JTextArea textShow;
String fuhao;
public void setJTextFieldOne(JTextField t) {
inputNumberOne = t; }
public void setJTextFieldTwo(JTextField t) {
inputNumberTwo = t; }
public void setJTextArea(JTextArea area) {
textShow = area; }
public void setFuhao(String s) {
fuhao = s; }
public void actionPerformed(ActionEvent e) {
try {
double number1=Double.parseDouble(inputNumberOne.getText());
double number2=Double.parseDouble(inputNumberTwo.getText());
double result = 0;
if(fuhao.equals("+")) {
result = number1+number2;
}
else if(fuhao.equals("-")) {
result = number1-number2;
}
else if(fuhao.equals("*")) {
result = number1*number2;
}
else if(fuhao.equals("/")) {
result = number1/number2;
}
textShow.append(number1+" "+fuhao+" "+number2+" = "+result+"\n");
}
catch(Exception exp) {
textShow.append("\n请输入数字字符\n");
}
}
}
// OperatorListener.java
import java.awt.event.*;
import javax.swing.*;
public class OperatorListener implements ItemListener {
JComboBox choice;
ComputerListener workTogether;
public void setJComboBox(JComboBox box) {
choice = box; }
public void setWorkTogether(ComputerListener computer) {
workTogether = computer; }
public void itemStateChanged(ItemEvent e) {
String fuhao = choice.getSelectedItem().toString();
workTogether.setFuhao(fuhao);
}
}
// WindowOperation.java
import java.awt.*;
import javax.swing.*;
import java.io.*;
public class WindowOperation extends JFrame {
JTextField inputNumberOne,inputNumberTwo;
JComboBox choiceFuhao;
JTextArea textShow;
JButton button;
OperatorListener operator; //监视ItemEvent事件的监视器
ComputerListener computer; //监视ActionEvent事件的监视器
public WindowOperation() {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
void init() {
setLayout(new FlowLayout());
inputNumberOne = new JTextField(5);
inputNumberTwo = new JTextField(5);
choiceFuhao = new JComboBox();
button = new JButton("计算");
choiceFuhao.addItem("选择运算符号:");
String [] a = {"+","-","*","/"};
for(int i=0;i<a.length;i++) {
choiceFuhao.addItem(a[i]); }
textShow = new JTextArea(9,30);
operator = new OperatorListener();
computer = new ComputerListener();
operator.setJComboBox(choiceFuhao);
operator.setWorkTogether(computer);
computer.setJTextFieldOne(inputNumberOne);
computer.setJTextFieldTwo(inputNumberTwo);
computer.setJTextArea(textShow);
choiceFuhao.addItemListener(operator);
//choiceFuhao是事件源,operator是监视器
button.addActionListener(computer);
//button是事件源,computer是监视器
add(inputNumberOne);
add(choiceFuhao);
add(inputNumberTwo);
add(button);
add(new JScrollPane(textShow));
}
}
9.12 鼠标事件
public class Example
{ public static void main(String args[])
{
Frame f=new Frame();
f.setBounds(100,100,300,300);
f.setVisible(true);
f.addWindowListener( new WindowAdapter( )
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
} );
f.setLayout(new FlowLayout());
f.add(new MyCanvas()); //添加画布
f.validate();
}
}
import java.awt.*;
import java.awt.event.*;
class MyCanvas extends Canvas implements MouseListener
{ int left=-1,right=-1; //记录左、右键用的变量
int x=-1,y=-1; //记录鼠标位置用的变量
MyCanvas()
{ setSize(200,200);
setBackground(Color.pink) ;
addMouseListener(this); //监视画布上的鼠标事件
}
public void paint(Graphics g)
{ if (left==1)
{ g.drawString("按下了鼠标左键",x,y);
}
else if (right==1)
{ g.drawString("按下了鼠标右键",x,y);
}
}
public void mouseReleased(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseClicked(MouseEvent e){ }
public void mousePressed(MouseEvent e)
{ x=e.getX();
y=e.getY();
if (e.getModifiers()==InputEvent.BUTTON1_MASK)
{ left=1;
right=-1;
repaint(); }
else if (e.getModifiers()==InputEvent.BUTTON3_MASK)
{ right=1;
left=-1;
repaint(); }
}
public void mouseExited(MouseEvent e)
{ left=-1;
right=-1;
repaint(); }
public void update(Graphics g)
{ if (left==1||right==1) paint(g);
else super.update(g);
}
}
二、使用MouseMotionListener接口处理鼠标事件
三、鼠标事件的转移
9.13 键盘事件
e.getSource()返回值是Object类型,所以必须强制类型转换
public class E
{ public static void main(String args[ ])
{ Win win=new Win( ); }
}
import java.awt.*;
import java.awt.event.*;
class Win extends Frame implements KeyListener
{ Button b[ ]=new Button[8];
int x,y;
Win()
{ setLayout(new FlowLayout());
for(int i=0;i<8;i++)
{
b[i]=new Button(""+i);
b[i].addKeyListener(this);
add(b[i]);
}
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{System.exit(0); }
} );
setBounds(10,10,300,300);
setVisible(true);
validate();
}
public void keyPressed(KeyEvent e)
{Button button=(Button)e.getSource();
x=button.getBounds().x;
y=button.getBounds().y;
if(e.getKeyCode()==KeyEvent.VK_UP)
{ y=y-2;
if(y<=0) y=0;
button.setLocation(x,y); }
else if(e.getKeyCode()==KeyEvent.VK_DOWN)
{ y=y+2;
if(y>=300) y=300;
button.setLocation(x,y); }
else if(e.getKeyCode()==KeyEvent.VK_LEFT)
{ x=x-2;
if(x<=0) x=0;
button.setLocation(x,y); }
else if(e.getKeyCode()==KeyEvent.VK_RIGHT)
{ x=x+2;
if(x>=300) x=300;
button.setLocation(x,y); } }
public void keyTyped(KeyEvent e) { }
public void keyReleased(KeyEvent e) { } }
二、处理复合键
import java.awt.*;
import java.awt.event.*;
class Win extends Frame implements KeyListener
{ Button b;
Win( )
{
setLayout(new FlowLayout());
b=new Button("我是一个按钮");
b.addKeyListener(this);
add(b);
addWindowListener (new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
} );
setBounds(10,10,300,300);
setVisible(true);
validate();
}
public void keyPressed(KeyEvent e)
{ Button button=(Button)e.getSource();
int x=0,y=0,w=0,h=0;
x=button.getBounds().x;
y=button.getBounds().y;
w=button.getBounds().width;
h=button.getBounds().height;
if ( e.getModifiers()==InputEvent.SHIFT_MASK &&
e.getKeyCode()==KeyEvent.VK_X )
{ button.setLocation(y,x); }
else if ( e.getModifiers()==InputEvent.CTRL_MASK&&
e.getKeyCode()==KeyEvent.VK_X )
{ button.setSize(h,w); }
}
public void keyTyped(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
}
public class E
{ public static void main(String args[ ])
{ Win win=new Win( ); }}
事件总结
9.14 Java Swing简介
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Example
{ public static void main(String args[ ])
{
JButton button1=new JButton("轻组件按钮1"),
button2=new JButton("轻组件按钮2");
JTextArea text=new JTextArea("轻组件");
text.setLayout(new FlowLayout());
button1.setOpaque(false); //设置按钮透明
text.add(button1);
JFrame jframe=new JFrame("根窗体");
jframe.setSize(300,300);
jframe.setVisible(true);
jframe.addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e)
{System.exit(0);}
});
Container contentpane=jframe.getContentPane();
contentpane.add(button2,BorderLayout.SOUTH);
contentpane.add(text,BorderLayout.CENTER);
contentpane.validate();
}
}
二、JTree类
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
class Win extends JFrame
{
public Win( )
{
Container con=getContentPane();
DefaultMutableTreeNode root=new DefaultMutableTreeNode("c:\\");
DefaultMutableTreeNode t1=new DefaultMutableTreeNode("dos");
DefaultMutableTreeNode t2=new DefaultMutableTreeNode("java");
DefaultMutableTreeNode t1_1=new
DefaultMutableTreeNode("applet");
DefaultMutableTreeNode t1_2=new DefaultMutableTreeNode("jre");
root.add(t1);
root.add(t2);
t1.add(t1_1);
t1.add(t1_2);
JTree tree =new JTree(root); //创建根为root的树
JScrollPane scrollpane=new JScrollPane(tree);
con.add(scrollpane);
addWindowListener ( new WindowAdapter( )
{
public void windowClosing(WindowEvent e)
{ System.exit(0);
}
} );
setVisible(true);
setBounds(80,80,300,300);
con.validate( );
validate( );
}
}
public class Example
{ public static void main(String args[ ])
{
Win win=new Win( );
}
}
9.15 建立对话框
9.15.1 Dialog类
Dialog类和Frame都是Window的子类,二者有相似之处也有不同的地方。比如Dialog 没有添加菜单的功能,而且对话框必须要依赖于某个窗口或组件,当它所依赖的窗口或组件消失,对话框也将消失;而当它所依赖的窗口或组件可见时,对话框又会自动恢复。
1.Dialog类的主要方法
import java.awt.event.*; import java.awt.*;
class MyDialog extends Dialog implements ActionListener //建立对话框类
{ static final int YES=1,NO=0;
int message=-1; Button yes,no;
MyDialog(Frame f,String s,boolean b) //构造方法
{ super(f,s,b);
yes=new Button("Yes"); yes.addActionListener(this);
no=new Button("No"); no.addActionListener(this);
setLayout(new FlowLayout());
add(yes); add(no);
setBounds(60,60,100,100);
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ message=-1;setVisible(false);} });
}
public void actionPerformed(ActionEvent e)
{ if(e.getSource()==yes)
{ message=YES;setVisible(false); }
else if(e.getSource()==no)
{ message=NO;setVisible(false); }
}
public int getMessage()
{ return message;
}
}
class Dwindow extends Frame implements ActionListener
{ TextArea text; Button button; MyDialog dialog;
Dwindow(String s)
{ super(s);
text=new TextArea(5,22); button=new Button("打开对话框");
button.addActionListener(this);
setLayout(new FlowLayout());
add(button); add(text);
dialog=new MyDialog(this,"我有模式",true);
setBounds(60,60,300,300); setVisible(true);
validate();
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);} });
}
public void actionPerformed(ActionEvent e)
{ if(e.getSource()==button)
{ dialog.setVisible(true);
if(dialog.getMessage()==MyDialog.YES)
text.append("\n你单击了对话框的yes按钮");
else if(dialog.getMessage()==MyDialog.NO)
text.append("\n你单击了对话框的No按钮");
}
}
}
public class Example
{ public static void main(String args[])
{ new Dwindow("带对话框的窗口");
}
}
2.对话框的模式
对话框分为无模式和有模式两种。
如果一个对话框是有模式的对话框,那么当这个对话框处于激活状态时,只让程序响应对话框内部的事件,程序不能再激活它所依赖的窗口或组件,而且它将堵塞当前线程的执行,即堵塞使得对话框处于激活状态的线程,直到该对话框消失不可见。
无模式对话框处于激活状态时,程序仍能激活它所依赖的窗口或组件,它也不堵塞线程的执行。
9.15.2文件对话框
FileDialog是Dialog类的子类,它创建的对象称为文件对话框。文件对话框是一个打开文件和保存文件的有模式对话框。文件对话框必须依附一个Frame对象。
FileDialog类主要方法
import java.awt.*; import java.awt.event.*;
public class Example
{ public static void main(String args[])
{ FWindow f=new FWindow("窗口"); } }
class FWindow extends Frame implements ActionListener
{ FileDialog filedialog_save, filedialog_load; //声明2个文件对话框
MenuBar menubar; Menu menu; MenuItem itemSave,itemLoad;
TextArea text;
FWindow(String s)
{ super(s); setSize(300,400); setVisible(true);
text=new TextArea(10,10); add(text,"Center"); validate();
menubar=new MenuBar(); menu=new Menu("文件");
itemSave=new MenuItem("保存文件"); itemLoad=new MenuItem("打开文件");
itemSave.addActionListener(this); itemLoad.addActionListener(this);
menu.add(itemSave); menu.add(itemLoad);
menubar.add(menu); setMenuBar(menubar);
filedialog_save=new FileDialog(this,"保存文件话框",FileDialog.SAVE);
filedialog_save.setVisible(false);
filedialog_load=new FileDialog(this,"打开文件话框",FileDialog.LOAD);
filedialog_load.setVisible(false);
filedialog_save.addWindowListener(new WindowAdapter()//对话框增加适配器
{ public void windowClosing(WindowEvent e)
{ filedialog_save.setVisible(false); } });
filedialog_load.addWindowListener(new WindowAdapter()//对话框增加适配器
{public void windowClosing(WindowEvent e)
{ filedialog_load.setVisible(false); } });
addWindowListener(new WindowAdapter() //窗口增加适配器
{public void windowClosing(WindowEvent e)
{ setVisible(false);System.exit(0); } });
}
public void actionPerformed(ActionEvent e) //实现接口中的方法
{ if(e.getSource()==itemSave)
{ filedialog_save.setVisible(true);
String name=filedialog_save.getFile();
if(name!=null)
{ text.setText("你选择了保存文件,名字是"+name); }
else
{ text.setText("没有保存文件"); } }
else if(e.getSource()==itemLoad)
{ filedialog_load.setVisible(true);
String name=filedialog_load.getFile();
if(name!=null)
{ text.setText("你选择了打开文件,名字是"+name); }
else
{ text.setText("没有打开文件"); } }
}
}
9.15.3消息对话框
9.15.4确认对话框
9.15.5颜色对话框
import java.awt.event.*;
import java.awt.*;
import javax.swing.JColorChooser;
class Dwindow extends Frame implements ActionListener
{ Button button;
Dwindow(String s)
{ super(s);
button=new Button("打开颜色对话框");
button.addActionListener(this);
setLayout(new FlowLayout());
add(button);
setBounds(60,60,300,300);
setVisible(true); validate();
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);} } );
}
public void actionPerformed(ActionEvent e)
{ Color newColor=JColorChooser.showDialog(this,"调色板",button.getBackground());
button.setBackground(newColor); }
}
public class HelloWorld
{ public static void main(String args[])
{ new Dwindow("带颜色对话框的窗口"); }}