黑马程序员—java基础之GUI与前期补充

时间:2022-05-16 16:42:37

黑马程序员—java基础之GUI与前期补充

                                               ------- android培训java培训、期待与您交流! ----------

 

成功者永不放弃,放弃者绝不成功,因此,我们要坚持下去.

前期帖子补充:

什么是API

Ÿ API全名:ApplicationProgramming Interface,API是应用程序编程接口,指一些预先定义好的类。

例如我们想要一台电脑,并不需要自己生产每个零件,只要从各个厂商买到组装电脑的零件就可以,然后根据说明书学会使用,将零件安装在一起就得到了电脑。电脑就像是我们要的程序,而零件就是API,说明书就是帮助文档

Java API

Ÿ Java API就是Sun公司提供给我们使用的类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用。

Ÿ 我们可以通过查帮助文档来了解Java提供的API如何使用

Java中常用API

Ÿ String类

                  对字符串进行操作通常我们使用String类,相关的还有StringBuffer和StringBuilder

Ÿ 集合类

                  集合是一种容器,用来存取对象(Collection、Map)

Ÿ 包装类

                  Java定义了一组包装类对基本数据类型进行了包装(Integer、Double、Boolean)

Ÿ 时间类

                  Java定义了一些类方便用户对时间、日期进行处理(Date、Calendar) 

Ÿ 系统类

                  Java定义了一些类针对系统进行操作(System、Runtime)  

Ÿ IO流

                  Java定义了一些类对数据传输进行了封装(输入输出流、File文件对象)

Ÿ Socket

                  Java定义了一些类方便用户进行网络编程(Socket、DatagramSocket)

 

线程间的通信

 

 1)线程间通信:

  其实就是多个线程在操作同一个资源,但操作的动作不同。

 

 (2)等待唤醒机制:

 

 <1>wait(),notify(),notifyAll()都使用在同步中,因为只有同步才具有锁,所以要对持有锁的

   线程操作。阻塞的线程都放在线程池中。notify唤醒的都是线程池中的线程,通常是线程池中的第一个线程。notifyAll唤醒线程池中的所有阻塞线程。

 

注意:优化后锁都是Res类中的this,时刻记住,wait()、notify、notifyAll()方法操作的是以这些方法所属对象为锁的线程

 

 <2>这些用来操作线程的方法为什么定义在Object类中?

   a.这些方法存在于同步中。

   b.使用这些方法时必须要标识所属的同步的锁。

   c.等待和唤醒必须是同一个锁。

   d.锁可以是任意对象,所以任意对象调用的方法一定定义在Object中。

 

 (3)wait(),sleep()的区别:

  wait():释放资源,释放锁。

  sleep():释放资源,不释放锁。

 

JDK1.5中提供了多线程的升级解决方案:将同步synchronized替换成Lock操作;将Objec(监视器对象)的wait,notify,notifyAll,替换成Condition对象的相应操作,Condition对象可以通过Lock锁进行获取。这是一种显式的锁机制和显式的锁对象上的等待唤醒操作机制,它把等待唤醒动作封装成了Condition类对象,让一个锁可以对应多个Condition对象(监视器对象),即一个锁可以对应多组wait-notify。

 

停止线程:

 

 (1)stop方法已经过时。

 

 (2)如何停止线程?

  只有一种,就是让run方法结束,开启多线程运行,运行代码通常是循环结构。只要控制住循环,

  就可以让run方法结束,也就是线程结束。

 

 (3)特殊情况:

 <1>当线程处于了冻结状态,就不会读到标记,那么线程就不会结束。

 <2>当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除,强制让线程恢复

   到运行状态中来,这样就可以操作标记让线程结束。

 

 (4)Thread类提供该方法:interrupt()

 

 

 

 join方法:

 

 join://抢夺CPU执行权

 public final void join()

     throws InterruptedException

 

 等待该线程终止

 (1)当A线程执行到了B线程的join()方法时,A就会等待,等B线程都执行完,A才会执行。

 (2)join可以用来临时加入线程执行。

 

 

 yield:临时停止

 

 public static void yield()

  暂停当前正在执行的线程对象,并执行其他线程。yield可稍微减缓线程的运行,

  使线程达到接*均运行的效果。

通信练习:

package com.itheima.thread;

 

public classDemo4_Notify{

 

   public static void main(String[] args) {

      final Demo4_Printer p = new Demo4_Printer();

 

      new Thread() {

        public void run() {

           while (true)

              try {

                 p.print1();

              }catch(InterruptedExceptione) {

                 e.printStackTrace();

              }

        }

      }.start();

 

      new Thread() {

        public void run() {

           while (true)

              try {

                 p.print2();

              }catch(InterruptedExceptione) {

                 e.printStackTrace();

              }

        }

      }.start();

     

      new Thread() {

        public void run() {

           while (true)

              try {

                 p.print3();

              }catch(InterruptedExceptione) {

                 e.printStackTrace();

              }

        }

      }.start();

   }

 

}

 

class Demo4_Printer{

   private int flag = 1;       // 标记, 用来标记应该执行哪个方法

  

   public synchronized void print1() throws InterruptedException {

      if (flag != 1) {     // 如果不该1

        wait();             // 等待(让出CPU),等到notify()为止

      }

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("\r\n");

      flag = 2;             // 1结束后轮到2

      notifyAll();          // 通知

   }

 

   public synchronized void print2() throws InterruptedException {

      while (flag != 2) {     // 如果不该2

        wait();             // 等待(让出CPU),等到notify()为止

      }

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("\r\n");

      flag = 3;             // 2结束后轮到3

      notifyAll();          // 通知

   }

  

   public synchronized void print3() throws InterruptedException {

      while (flag != 3) {     // 如果不该3

        wait();             // 等待(让出CPU),等到notify()为止

      }

      System.out.print("C");

      System.out.print("S");

      System.out.print("D");

      System.out.print("N");

      System.out.print("\r\n");

      flag = 1;             // 3结束后轮到1

      notifyAll();          // 通知

   }

}

1.5之后的通信代码

Jdk1.5之后有了完善的通信方式:

package com.itheima.thread.jdk5;

 

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

 

public classDemo4_Notify{

 

   public static void main(String[] args) {

      final Demo4_Printer p = new Demo4_Printer();

 

      new Thread() {

        public void run() {

           while (true)

              try {

                 p.print1();

              }catch(InterruptedExceptione) {

                 e.printStackTrace();

              }

        }

      }.start();

 

      new Thread() {

        public void run() {

           while (true)

              try {

                 p.print2();

              }catch(InterruptedExceptione) {

                 e.printStackTrace();

              }

        }

      }.start();

     

      new Thread(new Runnable(){

        public void run() {

           while (true)

              try {

                 p.print3();

              }catch(InterruptedExceptione) {

                 e.printStackTrace();

              }

        }

      }).start();

   }

 

}

 

class Demo4_Printer{

   private int flag = 1;       // 标记, 用来标记应该执行哪个方法

    ReentrantLock lock= newReentrantLock();

   private Conditionc1 = lock.newCondition();

   private Conditionc2 = lock.newCondition();

   private Conditionc3 = lock.newCondition();

// privateCondition c4 = lock.newCondition();

  

   public void print1() throws InterruptedException {

      lock.lock();

      if (flag != 1)        // 如果不该1

        c1.await();         // 等待(让出CPU),等到notify()为止

     

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("\r\n");

      flag = 2;             // 1结束后轮到2

      c2.signal();            // 通知

      lock.unlock();

   }

 

   public void print2() throws InterruptedException {

      lock.lock();

      if (flag != 2) {     // 如果不该2

        c2.await();         // 等待(让出CPU),等到notify()为止

      }

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.print("");

      System.out.println();

      flag = 3;             // 2结束后轮到1

      c3.signal();            // 通知

      lock.unlock();

   }

  

   public void print3() throws InterruptedException {

      lock.lock();

      if (flag != 3) {     

        c3.await();        

      }

      System.out.print("C");

      System.out.print("S");

      System.out.print("D");

      System.out.print("N");

      System.out.print("\r\n");

      flag = 1;            

      c1.signal();            

      lock.unlock();

   }

}

 

 

 

GUI

Ÿ GUI是GraphicalUser Interface的缩写,图形化用户界面

awt和swing

Ÿ Java为GUI提供的对象都存在java.awt,javax.swing两个包中

Ÿ awt依赖于本地系统平台,如颜色样式显示

swing跨平台

组件与容器

Ÿ 组件Component,是GUI图形界面的组成单元。

容器Container,可以存放组件,也可以存放容器

 

布局管理

FlowLayout(流式布局管理器)

Ÿ 从左到右的顺序排列。

BorderLayout(边界布局管理器)  

Ÿ 东,南,西,北,中

GridLayout(网格布局管理器)

Ÿ 规则的矩阵

CardLayout(卡片布局管理器)

Ÿ 选项卡

GridBagLayout(网格包布局管理器)

窗体的建立:

 

Ÿ 非规则的矩阵

Ÿ 窗体中可以存放各种组件,所以窗体是容器Container。创建时我们使用的是它的子类

Ÿ Container的常用子类有两个,Window和Panel。Window是我们常用的窗体,Panel是用来布局的不可见的。

Ÿ Window也有两个常用子类,Frame和Dialog。Frame是我们常用的带有标题和边框的顶层窗口,Dialog是对话框。

Ÿ 所有AWT包中的类都会运行在AWT线程上

 

事件处理

 

Ÿ    事件:用户对组件的一个操作。

Ÿ 事件源:发生事件的组件。

Ÿ 监听器:我们需要处理某个事件,就需要在发生事件的组件上添加监听器,也就是java.awt.event包中XxxListener接口的子类。

事件处理器:监听器中的方法。监听器被添加在组件上之后,组件上发生了对应事件就会执行指定方法

 

常用事件分类

Ÿ 窗体事件,WindowEvent,窗体打开、关闭、正在关闭、激活、最小化等。

Ÿ 鼠标事件,MouseEvent,鼠标按下、抬起、进入、移出等。

Ÿ 键盘事件,KeyEvent,键盘按下、抬起等。

动作事件,ActionEvent,在某一组件上发生了定义好的动作,例如按钮上鼠标点击或按空格,菜单上鼠标点击或按回车等

 

Adapter

通常Listener接口中都是有多个抽象方法的,而我们使用的时候有可能不会全部需要,如果定义子类实现接口那么就必须重写所有方法,这是比较麻烦的。Java中为我们提供了一些抽象的实现类,在类中对接口的抽象方法进行了空的实现,我们再定义监听器时只要继承这些抽象类就可以,这样那些不需要的方法就可以不再去重写了

 

理清思路, 主要还是要运用.

练习及代码分享:

1.创建一个GUI程序:

package com.itheima.gui;

 

import java.awt.Button;

import java.awt.FlowLayout;

import java.awt.Frame;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

 

public classDemo1_Frame{

   public static void main(String[] args) {

      Frame frame = newFrame("这是我的第一个GUI程序");    // 创建一个窗口

      frame.setSize(400,300);                  // 设置大小

      frame.setLocation(800,100);                 // 设置位置

      frame.setLayout(newFlowLayout());              // 设置布局方式

      Button button = newButton("退出");            // 创建一个按钮

      frame.add(button);                        // frame中添加按钮

     

      frame.addWindowListener(newMyWindowListener());  // 给窗口添加一个窗体监听器

//    button.addMouseListener(newMyMouseListener());   //给按钮添加鼠标监听器

//    button.addKeyListener(newMyKeyListener());       //给按钮添加键盘监听器

      button.addActionListener(newMyActionListener()); // 给按钮添加动作监听器(默认事件就是鼠标点击和键盘上空格键抬起)  

      frame.setVisible(true);                     // 设置可见

   }

}

class MyWindowListenerextendsWindowAdapter/*implements WindowListener*/ {  // 定义类实现监听器接口或者继承适配器

   public void windowClosing(WindowEvent e) {  // 实现事件处理方法

//    Frameframe = (Frame) e.getSource(); //获取事件源

//    frame.setVisible(false);          //隐藏, 暂时不显示

//    frame.dispose();               //摧毁, 释放资源

      System.exit(0);                  // 退出程序

   }

}

class MyMouseListenerextendsMouseAdapter/*implements MouseListener*/ {

   public void mouseClicked(MouseEvent e) {

      System.exit(0);

   }

}

class MyKeyListenerextendsKeyAdapter/*implements KeyListener*/ {

   public void keyReleased(KeyEvent e) {

      if (e.getKeyCode() ==KeyEvent.VK_SPACE// 如果按下的是空格键

        System.exit(0);

   }

}

class MyActionListenerimplementsActionListener {// 由于只有1个方法,没有适配器

   public void actionPerformed(ActionEvent e) {

      System.exit(0);

   }

}

 

2. 简单事件处理

做一个窗体

要求,点击X 按钮时会弹出新窗口

具备两个按钮,一个为关闭当前,点击关闭当前按钮,

一个为关闭所有,点击关闭所有窗口

package com.itheima.gui.exercise;

 

import java.awt.Button;

import java.awt.FlowLayout;

import java.awt.Frame;

import java.awt.Point;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

public classExercise1{

   private static int x = 100;

   private static int y = 100;

   public static void main(String[] args) {

      final Frame frame = new Frame("练习1");// 创建窗体

      frame.setSize(400,300);          // 设置大小

      frame.setLocation(x,y);          // 设置位置

      frame.setLayout(newFlowLayout());     //设置布局

      Button currentButton = new Button("关闭当前"); // 创建按钮(关闭当前)

      Button allButton = new Button("关闭所有");  // 创建按钮(关闭所有)

      frame.add(currentButton);              // 把按钮添加到窗体

      frame.add(allButton);            

      frame.addWindowListener(newWindowAdapter(){ // 给窗体添加监听器

        public void windowClosing(WindowEvent e) {

           Point p = frame.getLocation();     // 获取当前位置

           x = p.x + 30;                 // 改变下次弹出的x

           y = p.y + 30;                 // 改变下次弹出的y

           main(null);                   // 窗体关闭的时候,弹出相同的窗体

        }

      });  

      currentButton.addActionListener(new ActionListener() { // 给按钮(关闭当前)添加监听器

        public void actionPerformed(ActionEvent e) {

           Button button = (Button) e.getSource();     // 获取事件源(发生事件的对象)

           Frame frame = (Frame) button.getParent();   // 获取按钮的父级容器(Frame)

           frame.dispose();                    // 关闭1Frame

        }

      });

      allButton.addActionListener(new ActionListener() {  // 给按钮(关闭所有)添加监听器

        public void actionPerformed(ActionEvent e) {

           System.exit(0);                       // 点击时,退出程序

        }

      });  

      frame.setVisible(true);          // 显示窗体

   }

}

3.设置窗体背景色

建立三个按钮,颜色各不相同

要求鼠标进入时背景为按钮色,移出还原,点击时为按钮色并不再还原.

package com.itheima.gui.exercise;

 

import java.awt.Button;

import java.awt.Color;

import java.awt.FlowLayout;

import java.awt.Frame;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

 

public classExercise3{

 

   public static void main(String[] args) {

      // 创建窗体,设置....

      Frame frame = newFrame("练习3");

      frame.setSize(400,300);

      frame.setLocation(600,100);

      frame.setLayout(newFlowLayout());

     

      // 创建3个按钮,设置颜色, 添加到窗体

      Button redButton = new Button("Red");

      Button greenButton = new Button("Green");

      Button blueButton = new Button("Blue");

     

      redButton.setBackground(Color.RED);

      greenButton.setBackground(Color.GREEN);

      blueButton.setBackground(Color.BLUE);

     

      frame.add(redButton);

      frame.add(greenButton);

      frame.add(blueButton);

     

      // 窗体关闭事件处理

      frame.addWindowListener(newWindowAdapter() {

        public void windowClosing(WindowEvent e) {

           System.exit(0);

        }

      });

     

      // 按钮添加鼠标监听器

      MouseListenerlistener = newMyMouseListener();

      redButton.addMouseListener(listener);

      greenButton.addMouseListener(listener);

      blueButton.addMouseListener(listener);

     

      // 显示

      frame.setVisible(true);

   }

 

}

 

class MyMouseListenerextendsMouseAdapter{

   private Color color = Color.WHITE;        // 窗体的颜色, 默认为白色

   public void mouseEntered(MouseEvent e) { // 把窗体颜色改为按钮颜色

      Button button = (Button) e.getSource();

      Frame frame = (Frame) button.getParent();

      frame.setBackground(button.getBackground());

   }

   public void mouseExited(MouseEvent e) {  // Frame的颜色改为color记住的颜色

      Button button = (Button) e.getSource();

      Frame frame = (Frame) button.getParent();

      frame.setBackground(color);

   }

   public void mouseClicked(MouseEvent e) { // color记住Button的颜色

      Button button = (Button) e.getSource();

      color =button.getBackground();

   }

}

 

                                               ------- android培训java培训、期待与您交流! ----------