0
点赞
收藏
分享

微信扫一扫

Java学习记录 Day19(NIO流、GUI编程)


文章目录

  • ​​Day 19​​
  • ​​NIO流​​
  • ​​GUI编程​​

Day 19

2019年5月25日。
这是我学习Java的第十九天。
这一天,我学到了以下的知识。

NIO流

NIO流,是面向缓冲区的,基于通道的IO操作,这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多
以下,用一个文件复制类copyFile来说明NIO流。copyFile执行三个基本的操作:创建一个Buffer,然后从源文件读取数据到缓冲区,然后再将缓冲区写入目标文件。
详细的NIO流说明,​

public static void copyFile(String src,String dst) throws IOException{
//声明源文件和目标文件
FileInputStream fi=new FileInputStream(new File(src));
FileOutputStream fo=new FileOutputStream(new File(dst));
//获得传输通道channel
FileChannel inChannel=fi.getChannel();
FileChannel outChannel=fo.getChannel();
//获得容器buffer
ByteBuffer buffer=ByteBuffer.allocate(1024);
while(true){
//判断是否读完文件
int eof =inChannel.read(buffer);
if(eof==-1){
break;
}
//重设一下buffer的position=0,limit=position
buffer.flip();
//开始写
outChannel.write(buffer);
//写完要重置buffer,重设position=0,limit=capacity
buffer.clear();
}
inChannel.close();
outChannel.close();
fi.close();
fo.close();
}

GUI编程

GUI,即Graphical User Interface(图形用户接口编程),是指采用图形方式显示的计算机操作用户界面。
Java中的GUI编程,基本上是运用swing和AWT,在这里主要介绍AWT:

  • AWT(Abstract Window Toolkit)包括了很多类和接口,用于Java Application的GUI(Graphics User Interface 图形用户界面)编程
  • GUI的各种元素(如:窗口,按钮,文本框等)由Java类来实现
  • 使用AWT所涉及的类一般在Java.AWT包及其子包中
  • Container(容器)和Component(组件)是AWT中的两个核心类

Container和Component的关系图,如下所示:

Java学习记录 Day19(NIO流、GUI编程)_ide


接下来,分别介绍Container和LayoutManager(布局管理器)以及Component来说明GUI编程

  • Container(容器)
    Container里面分为Window和Pannel。
    Window是可以独立显示出来的,平时我们看到的各种各样的应用程序的窗口都可以称为Window,Window作为一个应用程序窗口独立显示出来。Window本身又可以分为Frame和Dialog,Frame就是我们平时看到的一般的窗口,而Dialog则是那些需要用户进行了某些操作(如点击某个下拉菜单的项)才出现的对话框,这种对话框就是Dialog。
    Pannel也可以容纳其它的图形元素,但一般看不见Pannel,Pannel不能作为应用程序的独立窗口显示出来,Pannel要想显示出来就必须得把自己装入到Window里面才能显示出来。
  • Frame
    Frame是Windows的子类,由Frame或其子类创建的对象,为一个窗体
    构造方法:​public Frame()​​:构造一个最初不可见的 Frame 新实例
    ​​​public Frame(String title)​​:构造一个新的、最初不可见的、具有指定标题的 Frame 对象
    成员方法
    ​​​public void setBounds(int x, int y, int width, int height)​​:设置窗体位置和大小,x,y是左上角坐标,width和height是宽度和高度
    ​​​public void setSize(int width, int height)​​:设置窗体的大小
    ​​​public void setLocation(int x, int y)​​:设置窗体的位置
    ​​​public void setBackground(Color c)​​:设置背景颜色,参数为Color对象
    ​​​public void setVisible(boolean b)​​:设置窗体是否可见,默认为不可见
    ​​​public void setTitle(String title)​​:设置Frame的标题
    ​​​public String getTitle()​​:获得Frame的标题
    ​​​public void setResizable(boolean resizable)​​:设置是否可以调整大小
    Frame代码实例:

public class MyTest {
public static void main(String[] args) {
//这里只是在内存里面创建了一个窗口对象 还不能真正显示出来让我们看到
Frame frame = new Frame("JAVA图形界面窗口");

//设置窗体的背景颜色
frame.setBackground(Color.blue);

//设置窗体是否可见
//要想看到在内存里面创建出来的窗口对象
//必须调用setVisble()方法
//并且把参数true传入才能看得见窗体
//如果传入的参数是false
//那么窗体也是看不见的
frame.setVisible(true);

//设置窗体的初始大小
frame.setSize(500,500);

//设置窗体出现时的位置,如果不设置则默认在左上角(0,0)位置显示
frame.setLocation(200,200);

// 设置窗体能否被改变大小
// 设置为false后表示不能改变窗体的显示大小
// 这里将窗体显示的大小设置为200X200
// 那么窗体的显示只能是这个大小了,不能再使用鼠标拖大或者缩小
frame.setResizable(false);

//设置窗体在点击右上角的“X”按钮时可以退出程序
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}}

  • Panel
    Panel对象可以看成容纳Component的空间,且可以拥有自己的布局管理器,并且拥有从父类继承来的方法
    构造方法:​public Panel()​​:使用默认的布局管理器创建新面板
    ​​​public Panel(LayoutManager layout)​​:构造一个新的、最初不可见的、具有指定标题的 Frame 对象
    成员方法
    ​​​public void setBounds(int x, int y, int width, int height)​​:设置面板位置和大小,x,y是左上角坐标,width和height是宽度和高度
    ​​​public void setSize(int width, int height)​​:设置面板的大小
    ​​​public void setLocation(int x, int y)​​:设置面板的位置
    ​​​public void setBackground(Color c)​​:设置背景颜色,参数为Color对象
    ​​​public void setLayout(LayoutManager mgr)​​:设置面板的布局管理器
    Panel代码实例:

public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame("JAVA Frame With Panel");
Panel panel = new Panel(null);
frame.setLayout(null);

//这里设置的坐标(300,300)是相对于整个屏幕的
frame.setBounds(300,300,500,500);

//设置背景颜色时使用三基色(红,绿,蓝)的比例来调配背景色
frame.setBackground(new Color(0,0,102));

//这里设置的坐标(50,50)是相对于Frame窗体的
panel.setBounds(50,50,400,400);
panel.setBackground(new Color(204,204,255));

//把Panel容器装入到Frame容器中,使其能在Frame窗口中显示出来
frame.add(panel);

frame.setVisible(true);

//解决关闭问题
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {

}

@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}

@Override
public void windowClosed(WindowEvent e) {

}

@Override
public void windowIconified(WindowEvent e) {

}

@Override
public void windowDeiconified(WindowEvent e) {

}

@Override
public void windowActivated(WindowEvent e) {

}

@Override
public void windowDeactivated(WindowEvent e) {

}
});
}
}

  • LayoutManger(布局管理器)
    Java中,提供了布局管理器类的对象可以管理,管理Component在Container中的布局,不必直接设置Component位置和大小,且每个Container都有一个布局管理器对象,当容器需要对某个组件进行定位或判断大小尺寸时,就会调用其对应的布局管理器,调用Container的setLayout方法改变其布局管理器对象。
  • FlowLayout(流式布局)
    FlowLayout是Panel类的默认布局管理器,具有如下特点:
  • FlowLayout布局管理器对组件进行定位,行内从左到右,一行排满后换行。
  • 不改变组件的大小,按组件原有尺寸显示组件,可设置不同的组件间距,行距以及对齐方式。
  • 默认的对齐方式是居中。

构造方法:​public FlowLayout()​​:使用默认的居中对齐方式,水平和垂直间距为默认值(5)
​​​public FlowLayout(int align)​​:使用指定的对齐方式,align的值必须为:FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER、FlowLayout.LEADING 或 FlowLayout.TRAILING
​​​public FlowLayout(int align, int hgap, int vgap)​​:使用指定的对齐方式以及水平和垂直间距,align的值必须为:FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER、FlowLayout.LEADING 或 FlowLayout.TRAILING
FlowLayout代码实例:

public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame("FlowLayout");

//使用Button类创建按钮
// 按钮类的其中一个构造方法:Button(String label) label为按钮显示的文本
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");

// setLayout方法的定义:public void setLayout(LayoutManager mgr)
// 使用流水(Flow)线般的布局
frame.setLayout(new FlowLayout());
// 使用了布局管理器FlowLayout,这里的布局采用默认的水平居中模式

// frame.setLayout(new FlowLayout(FlowLayout.LEFT));
// 这里在布局的时候使用了FlowLayout.LEFT常量,这样就将按钮设置为左对齐

// frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
//这里在布局的时候使用了FlowLayout.RIGHT常量,这样就将按钮设置为右对齐


frame.setSize(200,200);

frame.add(button1); // 把创建出来的按钮放置到Frame窗体中
frame.add(button2); // 这里并没有设置按钮的大小与位置
frame.add(button3); // 设置按钮的大小与位置都是由布局管理器来做的

frame.setVisible(true);
}
}

  • BorderLayout(边框布局)
    BorderLayout是Frame类的默认布局管理器,具有如下特点:
  • BorderLayout布局管理器将整个容器划分成:东(EAST)、西(WEST)、南(SOUTH)、北(NORTH)、中(CENTER)五个区域,组件只能添加到指定的区域。
  • 如果不指定组件的加入部位,则默认加入到CENTER区。
  • 每个区域只能加入一个组件,若加入多个,则先前加入的会被覆盖。

构造方法:​public BorderLayout()​​:构造一个组件之间没有间距的新边框布局
​​​public BorderLayout(int hgap, int vgap)​​:构造一个具有指定组件间距的边框布局
BorderLayout代码实例:

public class TestBorderLayout {
public static void main(String[] args) {
Frame frame = new Frame("TestBorderLayout");

Button buttonEast = new Button("East");
Button buttonWest = new Button("West");
Button buttonSouth = new Button("South");
Button buttonNorth = new Button("North");
Button buttonCenter = new Button("Center");

//把按钮放置到Frame窗体时按照东西南北中五个方向排列好,推荐使用这种方式去排列窗体元素
//这样容易检查出错误 因为这样写如果写错了编译器会提示出错

frame.add(buttonEast,BorderLayout.EAST);
frame.add(buttonWest,BorderLayout.WEST);
frame.add(buttonSouth,BorderLayout.SOUTH);
frame.add(buttonNorth,BorderLayout.NORTH);
frame.add(buttonCenter,BorderLayout.CENTER);

//也可以使用这样的方式排列按钮 在把按钮放置到Frame窗体时使用方向定位的字符串指定按钮的放置位置
//这种使用方向定位的字符串指定按钮的放置方式不推荐使用 一旦写错了方向字符串就不好检查出来
//因为即使是写错了仍然可以编译通过
/*
frame.add(buttonEast,"EAST");
frame.add(buttonWest,"West");
frame.add(buttonSouth,"South");
frame.add(buttonNorth,"North");
frame.add(buttonCenter,"Center");
*/

frame.setSize(200,200);
frame.setVisible(true);
}
}

  • GridLayout(表格布局)
    GridLayout型布局管理器将空间划分成规则的矩形网络,每个单元格区域大小相等。组件被添加到每个单元格中,先从左到右填满一行后换行,再从上到下。
    构造方法:​public GridLayout()​​:创建具有默认值的表格布局,即每个组件占据一行一列
    ​​​public GridLayout(int rows, int cols)​​:创建具有指定行数和列数的表格布局
    GridLayout代码实例:

public class TestGridLayout {
public static void main(String[] args) {
Frame frame = new Frame("TestGridLayout");

Button btn1 = new Button("btn1");
Button btn2 = new Button("btn2");
Button btn3 = new Button("btn3");
Button btn4 = new Button("btn4");
Button btn5 = new Button("btn5");
Button btn6 = new Button("bnt6");

// 把布局划分成3行2列的表格布局形式
frame.setLayout(new GridLayout(3,2));

frame.add(btn1);
frame.add(btn2);
frame.add(btn3);
frame.add(btn4);
frame.add(btn5);
frame.add(btn6);

// Frame.pack()是JAVA语言的一个函数
// 这个函数的作用就是根据窗口里面的布局及组件的preferredSize来确定frame的最佳大小。
frame.pack();
frame.setVisible(true);
}
}

  • 布局嵌套
    这几种布局管理器可以设置在Frame里面,也可以设置在Panel里面,而Panel本身也可以加入到Frame里面,因此通过Frame与Panel的嵌套就可以实现比较复杂的布局。
    代码如下:

public class TestTenButtons {
public static void main(String[] args) {
//这里主要是对显示窗体进行设置
Frame frame = new Frame("布局管理器的嵌套使用");

//把整个窗体分成2行1列的表格布局
frame.setLayout(new GridLayout(2,1));

frame.setLocation(300,400);
frame.setSize(400,300);
frame.setVisible(true);
frame.setBackground(new Color(204,204,255));

//这里主要是对Panel进行布局的设置
Panel p1 = new Panel(new BorderLayout());
//p2使用2行1列的表格布局
Panel p2 = new Panel(new GridLayout(2,1));
Panel p3 = new Panel(new BorderLayout());
//p4使用2行2列的表格布局
Panel p4 = new Panel(new GridLayout(2,2));

//这里主要是把按钮元素加入到Panel里面
p1.add(new Button("East(p1-东)"),BorderLayout.EAST);
p1.add(new Button("West(p1-西)"),BorderLayout.WEST);

p2.add(new Button("p2-Button1"));
p2.add(new Button("p2-Button2"));

//p1里面嵌套p2,把p2里面的按钮作为p的中间部分装入到p1里面
//把p2作为元素加入到p1里面
p1.add(p2,BorderLayout.CENTER);

p3.add(new Button("East(p3-东)"),BorderLayout.EAST);
p3.add(new Button("West(p3-西)"),BorderLayout.WEST);

for(int i=0;i<4;i++){
p4.add(new Button("p4-Button"+i));
}

//p3里面嵌套p4,把p4里面的按钮作为p的中间部分装入到p3里面
p3.add(p4,BorderLayout.CENTER);

//把Panel装入Frame里面,以便于在Frame窗体中显示出来
frame.add(p1);
frame.add(p3);
}
}

效果如下:

Java学习记录 Day19(NIO流、GUI编程)_java_02

  • Component(组件)
    Component,即可以实现各种功能的特殊组件。
  • Button(按钮)
    这里主要介绍按钮监听器的使用方法
    原理图如下:
  • Java学习记录 Day19(NIO流、GUI编程)_ide_03

  • 代码示例如下:

public class TestActionEvent {
public static void main(String[] args) {
Frame frame = new Frame("TestActionEvent");

Button button = new Button("Press Me");
// 创建一个监听对象
MyActionListener listener = new MyActionListener();

// 把监听加入到按钮里面,监听按钮的动作,
// 当按钮触发打击事件时,就会返回一个监听对象e
// 然后就会自动执行actionPerformed方法
button.addActionListener(listener);

frame.add(button, BorderLayout.CENTER);
frame.pack();

addWindowClosingEvent(frame);

frame.setVisible(true);

}

//点击窗体上的关闭按钮关闭窗体

private static void addWindowClosingEvent(Frame frame){
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}

// 自定义Monitor(监听)类实现事件监听接口ActionListener
// 一个类要想成为监听类,那么必须实现ActionListener接口
class MyActionListener implements ActionListener{

//重写ActionListener接口里面的actionPerformed(ActionEvent e)方法
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("A Button has been Pressed");
}
}

  • TextField(文本编辑框)
    这里主要介绍文本监听器的使用方法
    原理图如下:
  • Java学习记录 Day19(NIO流、GUI编程)_Java_04

  • 代码示例如下:

public class TestTextField {
public static void main(String[] args) {
new MyFrameTextField();
}
}

class MyFrameTextField extends Frame{
MyFrameTextField(){
TextField textField = new TextField();
add(textField);
textField.addActionListener(new MyMonitor2());

//这个setEchoChar()方法是设置文本框输入时显示的字符,这里设置为*,
//这样输入任何内容就都以*显示出来,不过打印出来时依然可以看到输入的内容
textField.setEchoChar('*');
setVisible(true);
pack();
}
}

class MyMonitor2 implements ActionListener{

//接口里面的所有方法都是public(公共的)
//所以从API文档复制void actionPerformed(ActionEvent e)时 要在void前面加上public
@Override
public void actionPerformed(ActionEvent e) {
//事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息

//getSource()方法是拿到事件源,注意:拿到这个事件源的时候
//是把它当作TextField的父类来对待
//getSource()方法的定义是:“public Object getSource()”返回值是一个Object对象
//所以要强制转换成TextField类型的对象
//在一个类里面想访问另外一个类的事件源对象可以通过getSource()方法
TextField textField = (TextField) e.getSource();

// textField.getText()是取得文本框里面的内容
System.out.println(textField.getText());

// 把文本框里面的内容清空
textField.setText("");
}
}

  • paint(绘图方法)
    每个Component都有一个paint(Graphics g)用于实现绘图目的,每次重画该Component时都自动调用paint方法
    代码示例如下:

public class TestPaint {
public static void main(String[] args) {
new MyPaint().launchFrame();
//在main()方法里面并没有显示调用paint(Graphics g)方法
//可是当创建出Frame窗体后却可以看到Frame窗体上画出了圆和矩形
//这是因为paint()方法是一个比较特殊的方法
//在创建Frame窗体时会自动隐式调用
//当我们把Frame窗体最小化又再次打开时
//又会再次调用paint()方法重新把圆和矩形在Frame窗体上画出来
//即每次需要重画Frame窗体的时候就会自动调用paint()方法
}
}

class MyPaint extends Frame{
public void launchFrame(){
setBounds(200,200,640,480);
setVisible(true);
}

public void paint(Graphics g){
//paint(Graphics g)方法有一个Graphics类型的参数g
//我们可以把这个g当作是一个画家,这个画家手里拿着一只画笔
//我们通过设置画笔的颜色与形状来画出我们想要的各种各样的图像

/*设置画笔的颜色*/
g.setColor(Color.red);
g.fillOval(100,100,100,100);/*画一个实心椭圆*/
g.setColor(Color.green);
g.fillRect(150,200,200,200);/*画一个实心矩形*/

//这下面的两行代码是为了写程序的良好编程习惯而写的
//前面设置了画笔的颜色,现在就应该把画笔的初始颜色恢复过来
//就相当于是画家用完画笔之后把画笔上的颜色清理掉一样
Color c = g.getColor();
g.setColor(c);

System.out.println("gogoogo");

}

}


举报

相关推荐

day19

Day19 Java方法重载

机器学习随记【day19】

寒假:Day19

日撸 Java 三百行学习笔记day19

day19//快乐数

0 条评论