一、概述

用户与计算机进行交换的方式有两种:

GLI:Command lin User Interface(命令行用户接口),也就是常见的dos窗口,它需要记住一些常用的命令,操作不直观方便。

GUI:Graphical User Interface(图形用户接口),用图形的方式,来显示计算机操作的界面,这样更方便直观。

这两种交换方式就对应两种交互界面:命令行界面和图形化界面。

现在图形化界面是主流。

Java为GUI提供的对象都在java.awt和javax.swing这两个包中。

Awt和Swing

java.awt:bstractWindow ToolKit(抽象窗口工具集,需要调用本地系统方法实现功能,属于重量级控件。

java.swing:在AWT的基础上,建立的一套图形界面系统,其中提供更多的组件,而且完全由java实现,增强了移植性,属于轻量级控件。

小知识点:这里的“重量级”是指跟平台结合紧密,轻量级与之相反。

AWT继承关系图

Frame

Frame是windows的子类,它启动时,要通过setVisiable(true)方法来启动窗口。

GUI中,启动一个窗体就是启动一个前台线程,虽然main函数运行完了,但前台线程没结束,所以程序也就不会结束。

窗口布局管理器

容器中的组件的排放方式,就是布局。

常见的布局管理器:•

FlowLayout(流式布局管理器):从左到右的顺序排列。Panel默认的布局管理器。

BorderLayout(边界布局管理器):东,南,西,北,中。Frame默认的布局管理器。

GridLayout(网格布局管理器):规则的矩阵。

CardLayout(卡片布局管理器):选项卡。

GridBagLayout(网格包布局管理器):非规则的矩阵。

事件监听机制

事件监听机制由四部分组成:事件源(组件)、事件(Event)、监听器(Listener)和事件处理(引发事件后的处理方式)。

1.事件源:就是java.awt和javax.swing包中的GUI组件。

2.事件:每个事件源都有自己的特有事件和共性事件(鼠标事件和键盘事件即是它们的共性事件)。

3.监听器:将可以触发某一事件的动作(不止一个)都封装在了监听器中。
  4.事件处理:事件源、事件和监听器在java中已经定义好了,直接获取其对象来用就可以了,我们要做的是对产生的动作进行处理。

窗体事件

WindowEvent事件对于的是WindowListener,事件对象作为参数,传入监听器的处理事件方法中。

WindowListener,是一个接口,对应的Window组件体系。查看该接口发现它有7个方法需要实现,这起个方法对应7个动作。如果我仅对其中的1个动作进行处理,却需要同时复写其他的6个方法,这样不方便与编程,所以java提供了一个WindowListener的抽象子类WindowAdapter。WindowAdapter虽然是抽象的,但没有抽象方法,它定义为抽象,是为不能直接建立对象,而让你去继承,复写你要想处理的动作方法。编程中,对事件监听器用匿名内部类的比较多。

当监听器接口的方法多于3个时,一般该监听器接口都用相应的Adapter(适配器)。

程序示例:

[java] view plaincopy print?
  1. /*
  2. 创建图形化界面步骤:
  3. 1.创建fram窗体。
  4. 2.对窗体进行基本设置。
  5. 比如大小,位置,布局。
  6. 3.定义组件。
  7. 4.将组件通过窗体的add方法添加到窗体中
  8. 5.让窗体显示,通过setVisible(true)方法。
  9. */
  10. import java.awt.*;
  11. import java.awt.event.*;
  12. class  AwtDemo
  13. {
  14. public static void main(String[] args)
  15. {
  16. Frame f =new Frame("my awt");
  17. f.setSize(500,400);//设置窗体大小500是宽,400是高
  18. f.setLocation(300,200);//设置初始显示位置,300是x坐标,200是y坐标
  19. //      上边两个方法可以用它 f.setBounds(x, y, width, height)来统一设置
  20. f.setLayout(new FlowLayout());//默认的是边界布局管理器
  21. Button b = new Button("我是一个按钮");
  22. f.add(b);
  23. f.addWindowListener(new WindowAdapter()
  24. {
  25. public void windowClosing(WindowEvent e)
  26. {
  27. System.out.println("我关");
  28. System.exit(0);//这个方法的 关闭的是虚拟机,退出虚拟机,当然就退出了程序
  29. }
  30. public void windowActivated(WindowEvent e)
  31. {
  32. System.out.println("我活动的");
  33. }
  34. public  void windowOpened(WindowEvent e)
  35. {
  36. System.out.println("我被打开了");
  37. }
  38. });
  39. //设置frame显示,这时图形界面线程才启动
  40. f.setVisible(true);
  41. }
  42. }
  43. class MyWin extends WindowAdapter
  44. {
  45. public void windowClosing(WindowEvent e)
  46. {
  47. System.exit(0);
  48. //System.out.println("MyWin------------"+e.toString());
  49. }
  50. }

Action事件

按钮对应的是ActionEvent事件,ActionEvent对应的是ActionListener监听器。只用按钮活动,就能执行,而键盘和鼠标都能让按钮活动。所以,如果对按钮处理的动作只有一种,最好使用ActionListener,因为鼠标键盘都会触发它。

ActionListener监听器接口只用一个方法,所以没有相应的Adapter,它是三个没有配适器的监听器接口之一。

代码示例:

[java] view plaincopy print?
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. class  FrameDemo
  4. {
  5. //定义该图形中所需的组件的引用。
  6. private Frame f;
  7. private Button but;
  8. FrameDemo()
  9. {
  10. init();
  11. }
  12. //初始化图形界面
  13. public void init()//初始化
  14. {
  15. f= new Frame("day22-MyFrame");
  16. //对frame进行基本设置。
  17. f.setBounds(300,100,600,500);
  18. f.setLayout(new FlowLayout());
  19. but = new Button("my button");
  20. //将组件添加到Frame中
  21. f.add(but);
  22. //加载一下窗体上的事件。
  23. myEvent();
  24. //显示窗体
  25. f.setVisible(true);
  26. }
  27. //最好把事件处理和GUI组件的基本初始化分离开
  28. public void myEvent()//这些都是组件的特有事件,还有共性事件。
  29. {
  30. f.addWindowListener(new WindowAdapter()
  31. {
  32. public void windowClosing(WindowEvent e)
  33. {
  34. System.out.println("关闭窗口");
  35. System.exit(0);//这个方法的 关闭的是虚拟机,退出虚拟机,当然就退出了程序
  36. }
  37. });
  38. //让按钮具备退出程序的功能。
  39. /*
  40. 按钮就是事件源,那么选择哪一个监听器呢?通过关闭窗体实例了解到。想要知道那个组件具备什么样的特与监听器,
  41. 需要查看该组件对象的功能。那么通过查阅button的描述,发现支持一个特有监听addActionListener(ActionListener l);
  42. 是没有适配器的少数组件之一,只要事件方法超过3个的组件,都有配适器(Adapter);
  43. */
  44. but.addActionListener(new ActionListener()
  45. {
  46. public void actionPerformed(ActionEvent e)
  47. {
  48. System.out.println("退出,按钮干的");
  49. System.exit(0);
  50. }
  51. });
  52. }
  53. //主函数,用于测试
  54. public static void main(String[] args)
  55. {
  56. new FrameDemo();
  57. }
  58. }

鼠标事件

MouseEvent,它是所有组件都有的共性事件,所以它的添加监听器方法是定义在Component抽象类中,键盘事件也是共性事件。它对应的是MouseListener。

鼠标单击次数是定义在MouseEvent事件对象中的,在MouseEvent事件对象中还能还封装了触发事件的是鼠标的一些相关信息。MouseListener有对应的MouseAdapter。

键盘事件

KeyEvent事件对象,内部封装了对应于键盘各个键的字段和触发事件的具体按键的信息。

这些信息可以通过该对象对外提供的方法获取到。

keyEvent 对应的事件监听器的KeyListener·,有对应的KeyAdapter。

代码示例:

[java] view plaincopy print?
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. class MouseAndKeyEvent
  4. {
  5. //定义该图形中所需的组件的引用。
  6. private Frame f;
  7. private Button but;
  8. private TextField tf;
  9. MouseAndKeyEvent()
  10. {
  11. init();
  12. }
  13. public void init()//初始化
  14. {
  15. f= new Frame("day22-MyFrame");
  16. //对frame进行基本设置。
  17. f.setBounds(300,100,600,500);
  18. f.setLayout(new FlowLayout());
  19. but = new Button("my button");
  20. tf = new TextField(10);
  21. f.add(but);
  22. f.add(tf);
  23. myEvent();
  24. f.setVisible(true);
  25. }
  26. public void myEvent()
  27. {
  28. f.addWindowListener(new WindowAdapter()
  29. {
  30. public void windowClosing(WindowEvent e)
  31. {
  32. System.exit(0);
  33. }
  34. });
  35. //给but添加一个键盘侦听器
  36. but.addKeyListener(new KeyAdapter()
  37. {
  38. private int count;
  39. public void keyPressed(KeyEvent e)
  40. {
  41. //判断组合键
  42. if(e.isControlDown() && e.getKeyCode()==KeyEvent.VK_ENTER)//从父类InputEvent 找isControlDown
  43. //System.exit(0);
  44. System.out.println("Ctrl + Enter is down");
  45. //System.out.println("按下某个键了---"+count++);
  46. //System.out.println(e.getKeyChar());
  47. //打印按下的键上在字符串,及键值。
  48. System.out.println(KeyEvent.getKeyText(e.getKeyCode())+"....."+e.getKeyCode());
  49. }
  50. });
  51. tf.addKeyListener(new KeyAdapter()
  52. {
  53. public void keyPressed(KeyEvent e)
  54. {
  55. //限定键值的范围
  56. int code =e.getKeyCode();
  57. if(!(code>=KeyEvent.VK_0 && code<=KeyEvent.VK_9))
  58. {
  59. //不处理,取消掉事件,具有屏蔽键的作用,如果键入是字符非法则不写入文本框。
  60. e.consume();//从父类InputEvent中获取的方法consume,不按照默认的方法处理该事件。
  61. System.out.println(code + "....是非法的");
  62. }
  63. }
  64. });
  65. /*
  66. //给but添加监听器
  67. but.addActionListener(new ActionListener()
  68. {
  69. public void actionPerformed(ActionEvent e)
  70. {
  71. System.out.println("button action");
  72. }
  73. });
  74. //给but添加鼠标监听器
  75. but.addMouseListener(new MouseAdapter()
  76. {
  77. private int count;
  78. private int clickCount;
  79. public void mouseEntered(MouseEvent e)
  80. {
  81. System.out.println("鼠标进入组件区域啦--"+count++);
  82. }
  83. public void mouseClicked(MouseEvent e)
  84. {
  85. if(e.getClickCount()==2)
  86. System.out.println("鼠标双击Button了--"+clickCount++);
  87. }
  88. });
  89. */
  90. }
  91. public static void main(String[] args)
  92. {
  93. new MouseAndKeyEvent();
  94. }
  95. }

对话框

Dialog在构造时,可以设置模式,如果为true那么,在该对话框关闭前,程序的其他窗口都不能被操作。

其体系如下:

|----Dialog

|----FileDialog文件对话框,可以从中选择文件。

|----JDialog

代码示例:模拟系统文件目录浏览器

[java] view plaincopy print?
  1. package tzq;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import java.io.File;
  5. public class MyWindowDemo {
  6. private Frame f;
  7. private Button but;
  8. private TextArea ta;
  9. private TextField tf;
  10. private Dialog d;
  11. private Label lab;
  12. private Button okBut;
  13. public MyWindowDemo() {
  14. init();
  15. }
  16. private void init() {
  17. f=new Frame("My Window");
  18. f.setBounds(300, 200, 500, 400);
  19. f.setLayout(new FlowLayout());
  20. tf=new TextField(40);
  21. but=new Button("转到");
  22. ta=new TextArea(20,45);
  23. d=new Dialog(f, "提示信息", true);
  24. d.setBounds(400, 200, 300, 130);
  25. d.setLayout(new FlowLayout());
  26. lab=new Label();
  27. okBut=new Button("确定");
  28. d.add(lab);
  29. d.add(okBut);
  30. f.add(tf);
  31. f.add(but);
  32. f.add(ta);
  33. myEvent();
  34. f.setVisible(true);
  35. }
  36. public void myEvent(){
  37. //添加按钮活动事件监听器
  38. but.addActionListener(new ActionListener() {
  39. @Override
  40. public void actionPerformed(ActionEvent arg0) {
  41. showDir();
  42. }
  43. });
  44. //okBut监听器
  45. okBut.addActionListener(new ActionListener() {
  46. @Override
  47. public void actionPerformed(ActionEvent e) {
  48. d.setVisible(false);
  49. }
  50. });
  51. //添加textField的键盘监听器
  52. tf.addKeyListener(new KeyAdapter() {
  53. @Override
  54. public void keyPressed(KeyEvent e) {
  55. if(e.getKeyCode()==KeyEvent.VK_ENTER){
  56. showDir();
  57. }
  58. }
  59. });
  60. d.addWindowListener(new WindowAdapter() {
  61. @Override
  62. public void windowClosing(WindowEvent e) {
  63. d.setVisible(false);
  64. }
  65. });
  66. //frame监听器
  67. f.addWindowListener(new WindowAdapter() {
  68. @Override
  69. public void windowClosing(WindowEvent e) {
  70. System.out.println("程序关闭");
  71. System.exit(0);
  72. }
  73. });
  74. }
  75. private void showDir(){
  76. String disPath=tf.getText();
  77. File dir=new File(disPath);
  78. if(dir.exists() && dir.isDirectory()){
  79. ta.setText("");
  80. String []names=dir.list();
  81. for(String name:names){
  82. ta.append(name+"\r\n");
  83. }
  84. }else{
  85. String info="您输入的信息"+disPath+"是错误的,请重新输入!";
  86. lab.setText(info);
  87. d.setVisible(true);
  88. }
  89. tf.setText("");
  90. }
  91. public static void main(String[] args) {
  92. new MyWindowDemo();
  93. }
  94. }

菜单

主要由三个类组成:MenuBar,Menu和MenuItem。

MenuBar:菜单条,里边只能添加Menu。

Menu:可以添加MenuItem菜单条目,如果这个MenuItem是一个Menu,那么这个Menu是一个子菜单。

MenuItem:菜单条目。

注意:其继承体系如下:

|---MenuComponent

|---- MenuBar

|---- MenuItem

|-----Menu

练习:简单模拟记事本

[java] view plaincopy print?
  1. package tzq;
  2. import java.awt.*;
  3. import java.io.*;
  4. import java.awt.event.*;
  5. public class NoteTest {
  6. private Frame f;
  7. private MenuBar mb;
  8. private Menu m;
  9. private MenuItem openItem,closeItem,saveItem;
  10. private TextArea ta;
  11. private FileDialog diaOpen,diaSave;
  12. private File file;
  13. public NoteTest() {
  14. init();
  15. }
  16. private void init() {
  17. f=new Frame("记事本");
  18. f.setBounds(400, 300, 600, 500);
  19. //f.setLayout(new FlowLayout());//使用默认的边界布局管理器
  20. //设置菜单
  21. mb=new MenuBar();
  22. m=new Menu("文件");
  23. openItem=new MenuItem("打开");
  24. saveItem=new MenuItem("保存");
  25. closeItem=new MenuItem("关闭");
  26. m.add(openItem);
  27. m.add(saveItem);
  28. m.add(closeItem);
  29. mb.add(m);
  30. //设置文本区
  31. ta=new  TextArea();
  32. //建立文件打开和保存的对话框
  33. diaOpen=new FileDialog(f, "打开", FileDialog.LOAD);
  34. diaSave=new FileDialog(f, "保存", FileDialog.SAVE);
  35. //将菜单添加到Frame(窗体)中
  36. f.setMenuBar(mb);
  37. f.add(ta);
  38. //添加事件
  39. myEvent();
  40. //设置窗体显示
  41. f.setVisible(true);
  42. }
  43. private void myEvent() {
  44. //frame窗体关闭监听
  45. f.addWindowListener(new WindowAdapter() {
  46. @Override
  47. public void windowClosing(WindowEvent e) {
  48. System.exit(0);
  49. }
  50. });
  51. //关闭菜单
  52. closeItem.addActionListener(new ActionListener() {
  53. @Override
  54. public void actionPerformed(ActionEvent arg0) {
  55. System.exit(0);
  56. }
  57. });
  58. //保存文件
  59. saveItem.addActionListener(new ActionListener() {
  60. @Override
  61. public void actionPerformed(ActionEvent e) {
  62. //先判断文件是否存在?
  63. //如果文件不存在则打开文件保存对话框
  64. if(file==null){
  65. diaSave.setVisible(true);
  66. String dirPath=diaSave.getDirectory();
  67. String fileName=diaSave.getFile();
  68. //将路径封装成文件对象
  69. file=new File(dirPath,fileName);
  70. //防止点击取消按钮产生异常,这时直接返回
  71. if(dirPath==null && fileName==null){
  72. return;
  73. }
  74. //上边的代码保证了文件肯定存在,然后开始保存数据
  75. try {
  76. BufferedWriter bufw=new BufferedWriter(new FileWriter(file));
  77. bufw.write(ta.getText());
  78. bufw.close();
  79. } catch (Exception e2) {
  80. throw new RuntimeException("保存失败!");
  81. }
  82. }
  83. }
  84. });
  85. //打开文件
  86. openItem.addActionListener(new ActionListener() {
  87. /* (non-Javadoc)
  88. * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
  89. */
  90. @Override
  91. public void actionPerformed(ActionEvent arg0) {
  92. //启动文件时打开对话框
  93. diaOpen.setVisible(true);
  94. //获得所选取文件的目录
  95. String dirPath=diaOpen.getDirectory();
  96. //获得选取的文件的文件名字,如果没有选取,则返回null(即点击的是取消按钮),这要处理一下
  97. String fileName=diaOpen.getFile();
  98. if(dirPath==null && fileName==null){
  99. return;
  100. }
  101. //选取有效文件后清空文本区域
  102. ta.setText("");
  103. //将选取的文件读到文本区域中
  104. file=new File(dirPath, fileName);
  105. //对IO异常进行处理,将文件内容加到文本区域中
  106. try {
  107. BufferedReader bufr=new BufferedReader(new FileReader(file));
  108. StringBuilder sb=new StringBuilder();
  109. String line=null;
  110. while((line=bufr.readLine())!=null){
  111. sb.append(line+"\r\n");
  112. }
  113. ta.append(sb.toString());
  114. bufr.close();
  115. } catch (Exception e) {
  116. throw new RuntimeException("读取失败");
  117. }
  118. }
  119. });
  120. }
  121. public static void main(String[] args) {
  122. new NoteTest();
  123. }
  124. }

产生问题:点击保存按钮后取消时系统报错:

八、GUI双击jar包执行

写好读到GUI程序,可以封装成jar包,通过对系统进行设置,使得双击jar包后,程序可以执行。以上边的写的记事本程序为例:

操作步骤:

1.      在源文件的第一行加上包:package mymenu

2.      dos命令行中启动“javac  -d  c:\myclassMyMenuTest.java”命令。

3.      在menu包所在目录下,新建一个名为“1.txt”的文本文档,里边录入一下内容:
Main-Class: mymenu.MyMenuTest

注意:1,冒号后面要有一个空格;2,末尾一定要加换行符,即敲一下Enter键。

4.      在在dos切换到c:\myclass目录下,启动”jar –cvfm my.jar 1.txt menu”    命令,这时得到的jar包即可启动。

在此之前要先将jar文件注册的系统中,其过程如下:

xP系统:工具à文件夹选项à文件类型à新建扩展名为jar的文件类型à选中jar,

点击“高级”按钮à更改图标,图标可以任意选;点击”新建”按键à添加open操作,操行名称写完“open”,用于执行操作的程序选择JDK目录下的javaw工具,并在末尾加上–jar参数。

Win7系统:

1、选择默认程序:右击jar包,打开方式->选择默认程序->浏览,选中jre下bin文件中javaw.exe(比如我的javaw.exe在D:\ProgramFiles\Java\jre6\bin下)。

2、编辑注册表:HKEY_CLASSES_ROOT\Applications\javaw.exe\shell\open\command,修改数据数值为"D:\ProgramFiles\Java\jdk1.6.0_21\jre\bin\javaw.exe" -jar "%1"(只要在原来的数值下添加-jar即可)。

错误示例:

jar时出现: invalid header field错误提示,

原因是

Main-Class:mymenu.MyMenuTest

冒号后边少一个空格,改为

Main-Class: mymenu.MyMenuTest即可。

from: http://blog.csdn.net/u010834071/article/details/38471605?utm_source=tuicool&utm_medium=referral

java之图形化界面(GUI)相关推荐

  1. JAVA之旅(三十一)——JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件

    JAVA之旅(三十一)--JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件 有段时间没有更新JAVA了,我们今天来说一下JAVA中的图形化界面,也就是GUI ...

  2. JAVA Swing 图形化界面编程

    JAVA Swing 图形化界面编程 目录 1.组件 1.1 基本组件 1.2. 组件边框 1.3. JToolBar 工具条 1.4 JColorChooser 颜色选择器 1.5 JFileCho ...

  3. Java图形化界面GUI:初接触

    简介 图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面. JavaGUI核心技术: Swing,AWT: Jav ...

  4. java 高级 图形化界面_java高级图形化界面

    java.awt.event.WindowAdapter 是一个接口 学生的答案: C 标准答案: C 该题分数:4.0 学生得分: 4.0 分 9. 在基于 Swing 的图形用户界面设计中,面板属 ...

  5. 一、Redis入门之——介绍、安装,图形化界面(GUI)工具Redis Desktop Manager (RDM)安装

    一.Redis简介 引用官方文档的介绍: Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: ...

  6. java基础-图形化界面(一)

    JPanel 是 JComponent 的直接子类(可以用JPanel替换 JComponent) Graphics2D是Graphics的子类 Graphics2D类 getX(),getY(),g ...

  7. Java 图形化界面设计(GUI)实战练习(代码)

    关于Java图形化界面设计,基础知识网上可搜,下面简单介绍一下重点概念,然后就由浅入深代码实例. 程序是为了方便用户使用的,Java引入图形化界面编程. 1.JFrame 是容器类 2.AWT 是抽象 ...

  8. java 网格布局管理器,Java图形化界面设计——布局管理器之GridLayout(网格布局)...

    网格布局特点: l  使容器中的各组件呈M行×N列的网格状分布. l  网格每列宽度相同,等于容器的宽度除以网格的列数. l  网格每行高度相同,等于容器的高度除以网格的行数. l  各组件的排列方式 ...

  9. Java图形化界面编程之——AWT

    目录 1.AWT简介 2.AWT继承体系 3.Container容器 3.1.Container继承体系 3.2.常用API 3.2.1.Component的常用方法 3.2.2.Container的 ...

最新文章

  1. linux下sql查询的使用,sql-server – 如何在Linux上查看SQL Server中的执行计划
  2. echart css样式弄了几个月了,样式一直都没有好好解决,好激动
  3. 真AI用钱表达:这家少年班毕业生创办的AI公司三年就盈利,增速300%
  4. 图形图像显示研究(一)
  5. spring学习(36):注入简单类型
  6. 微软已确认放弃Windows 10X操作系统 新功能下放
  7. oracle的sql优化
  8. 创业失败感悟第二十七天
  9. ASP.NET MVC 4 tutorial
  10. 模糊图像退化与去模糊的数学模型
  11. python 给qq点赞_Python实现QQ自动点赞
  12. 新中大怎么修改服务器,新中大软件服务器地址修改
  13. idcnd传媒官方专业提供
  14. keras中sample_weight的使用
  15. D - Silver Cow Party J - Invitation Cards 最短路
  16. 疯狂动物消消乐html5游戏在线玩,疯狂动物消消乐
  17. 当应酬成为日常,你需要这20个技巧聪明地进食
  18. 企业基本财务指标计算
  19. C语言获取数组左上,左下,右上,右下三角形的元素
  20. 判断数组类型的方法(Array.isArray)以及Math数字对象

热门文章

  1. 【Json】json解析
  2. 经验传承:谈色彩设计方法
  3. Spring Cloud Alibaba - 26 Gateway-自定义谓词工厂RoutePredicateFactory
  4. 实战并发编程 - 04基于不可变模式解决并发问题_2
  5. Spring Cloud【Finchley】-01服务提供者与服务消费者
  6. Android开发实用工具汇总-持续更新
  7. QT设计器主界面中文介绍
  8. excel 复制数据 sql server 粘贴_数据资料复制粘贴麻烦?教你硬盘对拷资料
  9. java readtimeout_Java HttpURLConnection.getReadTimeout方法代码示例
  10. python课堂笔记手抄图片_超简单又漂亮的手抄报图片