GUI

本章内容:
  AWT/组件和容器
  布局管理器
  事件处理
  JAVA图形
  Window事件
  
  AWT(Abstract window Toolkit)包括了很多类和接口,用于JAVA Application的GUI(Graphics User interface)
  图形用户界面,编程。(它是比较旧的开发包新的包是javax.swing)
  GUI的各种元素(如:窗口,按钮,文本框等)由java类来实现.
  使用AWT所涉及的类一般在java.awt包和其子包中。
  Container和Component是AWT中的两个核心类。
  组织关系:
  Component ----Button/TextArea/Lable/List
            |
            -----Container-------Window-------Frame/Dialog
            |
            --------Panel(不能做窗口独立显示)---Applet
  Component类和其子类的对象用来描述图形化的方式显示在屏幕与用户交互 的GUI元素,例如,一个按钮和标签。
  一般的Component对象不能独立地显示出来,必须将“放在”某个Container对象中才可以显示出来。
  Container是Component子类,Container子类对象可以“容纳”别的component对象。
  Container对象可使用方法add(...)向其中添加其它Component对象。
  Container也可以当成Component的子类添加到Container对象中。
  
  Frame
  Frame是Window的子类,由Frame或其子类创建的对象为一个窗体。
  Frame的常用构造方法:
   Frame()
   Frame(String s)创建标题栏为字符串S的窗口。
  常用方法:
   setBounds(int x,int y,int width,int height)设置窗口大小位置。
   setSize(int width,int height)
   setLocation(int x,int y)
   SetBackground(Color c)
   setVisible(boolean b)
   setTitle(String name)
   setResizable(boolean b)
   
 Panel:
 Panel对象可以看成可以容纳Component的空间。
 Panel地象可以拥有自己的布局管理器。
 Panel类拥有从其父类继承来的方法和frame类似。
 Panel的构造方法:
 Panel()使用默认的FlowLayout类布局管理器初始化。
 Panel(LayoutManager layout)使用指定的布局管理器。
 Panel的位置是相对于放置的容器的。如Frame。
 小示例程序:
  public class DomeFrame {
public static void main(String[] args) {
MyFrame f = new MyFrame("this is a first Frame",200,200,500,300);
}
}


class MyFrame extends Frame{
MyFrame(String s ,int x ,int y ,int width,int height){
super(s);
this.setBounds(x, y, width, height);
this.setBackground(Color.red);
this.setLayout(null);
Panel p = new Panel(null);
p.setBackground(Color.green);
int x1 = this.getWidth();  
int y1 = this.getHeight();
p.setBounds(x1/4,y1/4,x1/2,y1/2);
this.add(p);
this.setVisible(true);
}
}
 
布局管理器:
 java语言中,提供了布局管理器类的对象可以管理 。
 1.管理Component在Container中的布局,不必直接设置。Component位置和大小。
 2.每个Container都有一个布局管理对象,当容器需要对某个组件进行定位或判断其大小时,
 就会调用其对应的布局管理器,调用Continer的setLayout方法改变共布局管理器大小。
常用的五种布局管理器类:
 1.FlowLayout
 2.BorderLayout
 3.GridLayout
 4.CardLayout
 5.GridBagLayout
FlowLayout是Palnel类的默认布局管理器。
1.Flowlayout布局管理器对组件逐行定位,行内从左到右,一行排满后换行。
2.不改变组件的大小,按组件原有的尺寸显示组件,可设置不同的组件间距。行距和对齐方式。
3.FlowLayout布局管理器默认的对齐方式 是居中。
构造方法:
 new FlowLayout(FlowLayout.RIGHT,20,40);右对齐,组件水平距20个像素,垂直40.
 new FlowLayout(FlowLayout.LEFT)左对齐,水平和垂直默认(5)。
 new FlowLayout();居中,默认5.
示例:
 public static void main(String[] args) {
      Frame f = new Frame("myFrame");
      f.setLayout(new FlowLayout(FlowLayout.CENTER,20,40));
      for(int i=0;i<6;i++){
     f.add(new Button("b" + i));
      }
      f.pack();//按组件的自动大小展现
      f.setVisible(true);
}


BorderLayout:
 1.它是Frame类的默认布局管理器。
 2.整个容器分成 东、西、南、北、中。
 3.如果不指定组件的加入部分,刚默认加入到CENTER区
 4.每个区域只能加入一个组件,如加入多入,刚先前加入的会被覆盖。
示例小程序:
 public static void main(String[] args) {
      Frame f1 = new Frame("myFrame");
      f1.setLayout(new BorderLayout());
      Button b1 = new Button("b1");
      Button b2 = new Button("b2");
      Button b3 = new Button("b3");
      Button b4 = new Button("b4");
      f1.add(b1,BorderLayout.EAST);
      f1.add(b2,BorderLayout.WEST);
      f1.add(b3,BorderLayout.NORTH);
      f1.add(b4,BorderLayout.SOUTH);
      f1.pack();
      f1.setVisible(true);
 } 
 
GridLayout:
 GridLayout型布局管理器将空间划分成规则的矩形风格,每个单元格区域相等。
 组件被添加到每个单元格中,先从械到右添满一行后换下一行,再从上到下。
 在GridLayout构造方法中指定分割的行数和列数。
 如:GridLayout(3,4)
 示例:
  public static void main(String[] args) {
Frame f3 = new Frame("myFrame");
f3.setLocation(200,200);
f3.setLayout(new GridLayout(3,2));
Button bb1 = new Button("bb1");
Button bb2 = new Button("bb2");
Button bb3 = new Button("bb3");
Button bb4 = new Button("bb4");
Button bb5 = new Button("bb5");
Button bb6 = new Button("bb6");
f3.add(bb1);
f3.add(bb2);
f3.add(bb3);
f3.add(bb4);
f3.add(bb5);
f3.add(bb6);
f3.pack();
f3.setVisible(true);
}
  
  
布局管理器总结:
 1.Frame 是一个顶级窗口,Frame的缺省布局管理器为BorderLayout
 2.Panel无法单独显示,必须加到某个容器中。Panel的默认管理器为FlowLayout.
   当把Panel作为一个组件添加到某个容器中后,该Panel仍然可以有自己的布局管理器。
 3.使用布局管理器时,布局管理器负责各个组件的大小和位置,因此这种情况下无法设置组件大小
   和位置,因为里面的setLocation(),setSize(),setBounds()等方法,都会被布局管理器覆盖。
 4.如果用户想自己设置组件大小和位置应该取消布局管理器:setLayout(null);
 
事件监听:在java.awt.event(子包里)
 事件源对象--------------->实现了某种监听器材接口类的对象
 理解事件的处理流程:
 
public static void main(String[] args) {
Frame f4 = new Frame("test");
Button button = new Button("press me");
Moniter m = new Moniter();
button.addActionListener(m);
f4.add(button,BorderLayout.CENTER);
f4.pack();
f4.setVisible(true);
}
}
class Moniter implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("a button is pressed!!!");
}

TextField事件监听:
 示例小程序:
 public class DomeTextField {


public static void main(String[] args) {
Frame f6 = new Frame("TextFiled");
TextField tf = new TextField();
tf.setEchoChar('*');
TFMoniter tfm = new TFMoniter();
f6.add(tf);
tf.addActionListener(tfm);
f6.pack();
f6.setVisible(true);
}
}


class TFMoniter implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
TextField tf = (TextField) e.getSource();
String str = tf.getText();
System.out.println(str);
tf.setText("");
}
}


持有对方引用 :非常重要的设计模式(门面模式)
 public class DomeTest {


public static void main(String[] args) {
      new MyFrame2().launchframe();
}
}


class MyFrame2 extends Frame{
TextField num1,num2,num3;
public void launchframe(){
num1 = new TextField(15);
num2 = new TextField(15);
num3 = new TextField(15);
Label label = new Label("+");
Button equals = new Button("=");
equals.addActionListener(new MyMoniter2(this));
this.setLayout(new FlowLayout());
this.add(num1);
this.add(label);
this.add(num2);
this.add(equals);
this.add(num3);
this.pack();
this.setVisible(true);
}
}


class MyMoniter2 implements ActionListener{
MyFrame2 my ;
MyMoniter2(MyFrame2 my){
this.my = my;
}
@Override
public void actionPerformed(ActionEvent e) {
int num1 = Integer.parseInt(my.num1.getText());
int num2 = Integer.parseInt(my.num2.getText());
int num3Int = num1 + num2;
my.num3.setText(num3Int+"");
}
}


内部类:1.内部类的好处可以直接访问包装类的成员变量。
  2.防止其它不应该调用该类的类调用该类(从语言上防止)加private
  3.类要实现A接口,又要实现B接口,两个接口都有相同方法名但返回值不同。不能构成重载那么就要用内部类了。
 
Graphics类(机制原理一样):
 每个Component都有一个paint(Graphics g)用来实现绘图目的,每次重画Component时都会调用paint方法。
 paint():当Frame要被重画的时候就会调用,改变窗口大小时会调用。它是Container类里的方法。
 示例:
  public static void main(String[] args) {
new PaintFrame().launchframe();
}
}


class PaintFrame extends Frame{
    public void launchframe(){
    this.setBounds(200,100,300,200);
    this.setBackground(Color.GREEN);
    this.setVisible(true);
    }
@Override
public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.red);
g.drawOval(10, 10,30,50);
g.setColor(Color.GRAY);
g.drawRect(30, 80,30,20);
g.setColor(c);
}
}


鼠标事件适配器:
 抽象类java.awt.event.MouseAdapter实现了MouseListener接口,可以使用其子类作为
 MouseEvent的监听器,只要重写其相应的方法。
 对于其它的监听器,也有对应的适配器。
 作用适配器可以避免监听器类定义没有必要的空方法。
 repaint()----update() -----paint()
 示例:
 public class DomeRepaint {
   
public static void main(String[] args) {
new RepaintFrame().lanchframe();
}
}




class RepaintFrame extends Frame{
List<Point> list = new ArrayList<Point>();
public void lanchframe(){
this.setBounds(200,100,200,100);
this.setLayout(null);
this.addMouseListener(new MouseEV());
this.setVisible(true);
}


@Override
public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.blue);
Iterator<Point> it = list.iterator();
while(it.hasNext()){
Point p = it.next();
g.fillOval(p.x, p.y, 10, 10);
}
}

class MouseEV extends MouseAdapter{
@Override
public void mousePressed(MouseEvent e) {
     list.add(new Point(e.getX(),e.getY()));  
     repaint();
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值