黑马程序员--Java学习日记之GUI(图形化用户界面编程)
2015-06-27 12:11
696 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1、GUI相关概述
①GUI:GraphicalUser Interface,即图形用户界面,用于计算机与用户交互的一种方式。用图形的方式,来显示计算机操作的界面,这样更方便更直观。
②java将这种界面封装为对象,放在了两个包中:java.Awt包和javax.Swing包。
java.Awt包:Abstract Window Toolkit,即抽象窗口工具包。要调用本地系统方法实现功能,属重量级控件。
javax.Swing包:在AWT的基础上建立的一套图形界面系统。其中提供了更多的组件,且完全由java实现,增强了移植性,属轻量级控件。
注:Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。
②常见的布局管理器
FlowLayout:流式布局管理器,从左向右排列。(Panel默认的布局管理器)
BorderLayout:边界式布局管理器,东南西北中的排列方式。(Frame的默认布局管理器)注:如果窗体中只有一个组件,将会覆盖整个窗体。
GridLayout:网格式布局管理器,将容器分成n行m列大小相等的网格。
CardLayout:卡片式布局管理器,即选项卡。
GridBayLayout:网格包布局管理器,非规则矩阵(一个组件可能占多个格子)。
③如果存在多种布局方式,如何创建窗体界面呢?
先将窗体Frame进行大区域的划分,设置其布局管理器,加入面板Panel。
将组件加入Panel,设置面板的布局管理器。
②对窗体进行基本设置:如大小,位置,布局等:
f.setSize(int wight,int hight):窗体大小设置:宽X,高H。
f.setLocation(int x,int y):窗体显示位置设置,离左边界x,上边界y。
f.setBounds(int x,int y,int wight,int hight):也可以直接用这个方法对大小和位置设置。
setVisible(boolean true):设置窗体可见。
f.setLayout(LayoutManager layout),参数为指定的布局管理器,如FlowLayout。
③定义组件:如Button b = new Button(“my Button”)。
④将组件通过窗体的add方法添加到窗体中:f.add(b)。
⑤让窗体显示:f.setVisible(boolean b)。
窗体创建的代码演示如下:
事件源(即组件,发生事件的场所):需将监听器注册到事件源对其进行监听。
事件(Event)(封装了GUI组件发生的特定事件,每一个事件源都有自己特有的对应事件和共性事件)。
监听器(将可触发某一事件的动作(不只一个动作)都封装到监听器中)。
事件处理(事件的处理的方式)。
注意:前三者已在java中都已经定义好了,直接获取其对象来用就可以了。
②事件监听流程图:
③事件监听流程
确定事件源(容器或组件)
通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上。
该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
一般用匿名内部类来表示。在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。
事件触发后会把事件打包成对象传递给该变量。(其中包括事件源对象。通过getSource()或者,getComponent()获取。)
④带事件监听器的窗体创建(代码示例)
想实现事件的监听机制,需定义一个类实现事件监听器的接口(Window(或Xxx)Listener),接着通过addWindow(或Xxx)Listener( 监听器对象 )方法将为事件源注册监听器对象。该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
3、事件适配器(WindowListener的子类WindowAdapter)
由于继承WindowListener需覆盖其7个方法,发现WindowAdapter已经实现了WindowListener接口, 并覆盖了其中的所有方法。所以只要自定义监听器继承Windowadapter覆盖所需要的方法即可。
4、常用事件分类
①窗体事件(WindowEvent)
②动作事件(ActionEvent)
③鼠标事件(MouseEvent)
适配器:MouseAdapter ,常用方法:
a、void mouseEntered(MouseEvent e):鼠标进入到该组件
b、void mouseClicked(MouseEvent e):单击鼠标
鼠标事件 MouseEvent 常用方法:int getClickCount():返回鼠标单击次数
④键盘事件(KeyEvent)
适配器:KeyAdapter 事件常用方法:void keyPressed(KeyEvent e):按下键调用此方法
KeyEvent 事件常用方法:
a、char getKeyChar():返回与此事件中的键关联的字符
b、int getKeyCode():返回键盘上实际键的整数代码
c、static String getKeyText(int keyCode):返回描述 keyCode 的 String,如 "HOME"、"F1" 或 "A"。
d、boolean isControlDown():返回 Control 修饰符在此事件上是为 down。(用于组合键)
e、void consume():不会按照默认的方式由产生此事件的源代码来处理此事件。如只在文本区域添加数字时,当添加字符就不会进入文本区域
f、常用字段:VK_XXX(XXX表示键盘的键)
⑤代码实例:
String getText():返回此文本组件表示的文本。
void setText(String t):将此文本组件显示的文本设置为指定文本。
②TextArea 多行文本,常用方法如下:
String getText():返回此文本组件表示的文本。
void setText(String t):将此文本组件显示的文本设置为指定文本。
void append(String str):将给定文本追加到文本区的当前文本。
②子类FileDialog(文本对话框)
a、常用构造方法
FileDialog(Dialog parent, String title, int mode): 创建一个具有指定标题的文件对话框窗口,用于加载或保存文件。
b、常用方法
String getDirectory():获取此文件对话框的目录。
String getFile():获取此文件对话框的选定文件。如果用户选择 CANCEL,则返回文件为 null。
②菜单组件概述
lMenuBar,Menu,MenuItem
先创建菜单条,再创建菜单,每一个菜单中建立菜单项。
通过setMenuBar()方法,将菜单添加到Frame中。
①首先要在java文件中导入一个包,没有则需创建一个包,如package myfile;
②生成包:通过编译javac -d f:\\ SaveFile.java (将包存放在f盘)此时则在f盘下的myfile文件夹下生成了所有的.class文件
③在此目录下新建一个文件,如1.txt或者其他任意名称任意扩展名的文件都可,然后在其中编辑固定的格式:“Main-Class: myfile.SaveFile”,只写引号中的内容。需要需要在冒号后有一个空格,在文件末尾要回车。
④编译:jar -cvfm my.jar 1.txt mymenu即可。如果想添加其他信息,则直接编译jar即可得出相应的命令
⑤此时双击即可执行。
如果无空格:在编译的时候,就会报IO异常,提示无效的头字段,即invalidheader field。这说明1.txt在被IO流读取。
如果无回车:在列表清单.MF中不会加入相应的加载主类的信息,也就是说配置清单的属性主类名称不会加载进清单中,也就不会执行。
②jar文件必须在系统中注册,才能运行。注册方法如下:
对于XP系统:
a、打开任意对话框,在菜单栏点击工具按钮,选择文件夹选项
b、选择新建--->扩展名,将扩展名设置为jar,确定
c、选择高级,可更改图标,然后点击新建,命名为open,
d、在用于可执行应用程序中,点浏览,将jdk下的bin的整个文件路径添加进来,并在路径后添加-jar即可。
对于win7/win8系统:
a、改变打开方式:右击.jar文件,点击打开方式,选择默认程序为jdk下bin中的javaw.exe应用程序。
b、修改关联程序的注册表:打开注册表(win+r),找到注册表路径\HKEY_CLASSES_ROOT\Aplications\javaw.exe\shell\open\command下的字符串值,右击点修改,在原路径的中添加-jar,如:"C:\ProgramFiles\Java\jre6\bin\javaw.exe" -jar "%1",注意-jar两边要有空格,保存。
c、双击即可执行jar程序。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、概述
1、GUI相关概述
①GUI:GraphicalUser Interface,即图形用户界面,用于计算机与用户交互的一种方式。用图形的方式,来显示计算机操作的界面,这样更方便更直观。②java将这种界面封装为对象,放在了两个包中:java.Awt包和javax.Swing包。
java.Awt包:Abstract Window Toolkit,即抽象窗口工具包。要调用本地系统方法实现功能,属重量级控件。
javax.Swing包:在AWT的基础上建立的一套图形界面系统。其中提供了更多的组件,且完全由java实现,增强了移植性,属轻量级控件。
2、GUI继承体系图
注:Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。
二、AWT概述
1.布局管理器
①什么是布局管理器?容器中的组件的排放方式,就是布局。②常见的布局管理器
FlowLayout:流式布局管理器,从左向右排列。(Panel默认的布局管理器)
BorderLayout:边界式布局管理器,东南西北中的排列方式。(Frame的默认布局管理器)注:如果窗体中只有一个组件,将会覆盖整个窗体。
GridLayout:网格式布局管理器,将容器分成n行m列大小相等的网格。
CardLayout:卡片式布局管理器,即选项卡。
GridBayLayout:网格包布局管理器,非规则矩阵(一个组件可能占多个格子)。
③如果存在多种布局方式,如何创建窗体界面呢?
先将窗体Frame进行大区域的划分,设置其布局管理器,加入面板Panel。
将组件加入Panel,设置面板的布局管理器。
2、简单的窗体创建过程
①创建Frame窗体:Frame f = new Frame("my Frame"):可设置标题,即窗体名字。②对窗体进行基本设置:如大小,位置,布局等:
f.setSize(int wight,int hight):窗体大小设置:宽X,高H。
f.setLocation(int x,int y):窗体显示位置设置,离左边界x,上边界y。
f.setBounds(int x,int y,int wight,int hight):也可以直接用这个方法对大小和位置设置。
setVisible(boolean true):设置窗体可见。
f.setLayout(LayoutManager layout),参数为指定的布局管理器,如FlowLayout。
③定义组件:如Button b = new Button(“my Button”)。
④将组件通过窗体的add方法添加到窗体中:f.add(b)。
⑤让窗体显示:f.setVisible(boolean b)。
窗体创建的代码演示如下:
import java.awt.*; 02.class FrameDemo{ 03. public static void main(String[] args){ 04. Frame f = new Frame("my frame"); 05. f.setSize(500, 400); 06. f.setLocation(400, 200); 07. f.setBounds(400, 200, 500, 400); 08. f.setLayout(new FlowLayout());//设置流式布局 09. Button but = new Button("一个按钮"); 10. f.add(but);//将按钮添加到窗体中。 11. f.setVisible(true); 12. } 13.}
三、AWT事件处理
1、事件监听机制
①事件监听机制的组成:事件源(即组件,发生事件的场所):需将监听器注册到事件源对其进行监听。
事件(Event)(封装了GUI组件发生的特定事件,每一个事件源都有自己特有的对应事件和共性事件)。
监听器(将可触发某一事件的动作(不只一个动作)都封装到监听器中)。
事件处理(事件的处理的方式)。
注意:前三者已在java中都已经定义好了,直接获取其对象来用就可以了。
②事件监听流程图:
③事件监听流程
确定事件源(容器或组件)
通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上。
该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
一般用匿名内部类来表示。在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。
事件触发后会把事件打包成对象传递给该变量。(其中包括事件源对象。通过getSource()或者,getComponent()获取。)
④带事件监听器的窗体创建(代码示例)
import java.awt.*; 02.import java.awt.event.*; 03.class FrameTest 04.{ 05. public static void main(String[] args) 06. { 07. //创建窗体 08. Frame f = new Frame("我的窗体"); 09. //对窗体进行基本设置 10. f.setBounds(400,300,350,300); 11. f.setLayout(new FlowLayout()); 12. //创建按钮对象 13. Button b = new Button("关闭"); 14. //将按钮加入窗体中 15. f.add(b); 16. 17. //设置窗体可见 18. f.setVisible(true); 19. 20. //为窗体注册监听器 21. f.addWindowListener(new MyWindowAdapter() ); 22. 23. //为按钮注册活动监听,使用匿名内部类 24. //因为ActionListener接口只有一个方法,所以不需有适配器。 25. b.addActionListener(new ActionListener() 26. { 27. public void actionPerformed(ActionEvent e) 28. { 29. System.out.println("按钮关闭窗口"); 30. System.exit(0); 31. } 32. }); 33. 34. } 35.}2、事件监听器
想实现事件的监听机制,需定义一个类实现事件监听器的接口(Window(或Xxx)Listener),接着通过addWindow(或Xxx)Listener( 监听器对象 )方法将为事件源注册监听器对象。该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
3、事件适配器(WindowListener的子类WindowAdapter)
由于继承WindowListener需覆盖其7个方法,发现WindowAdapter已经实现了WindowListener接口, 并覆盖了其中的所有方法。所以只要自定义监听器继承Windowadapter覆盖所需要的方法即可。
4、常用事件分类
①窗体事件(WindowEvent)
②动作事件(ActionEvent)
③鼠标事件(MouseEvent)
适配器:MouseAdapter ,常用方法:
a、void mouseEntered(MouseEvent e):鼠标进入到该组件
b、void mouseClicked(MouseEvent e):单击鼠标
鼠标事件 MouseEvent 常用方法:int getClickCount():返回鼠标单击次数
④键盘事件(KeyEvent)
适配器:KeyAdapter 事件常用方法:void keyPressed(KeyEvent e):按下键调用此方法
KeyEvent 事件常用方法:
a、char getKeyChar():返回与此事件中的键关联的字符
b、int getKeyCode():返回键盘上实际键的整数代码
c、static String getKeyText(int keyCode):返回描述 keyCode 的 String,如 "HOME"、"F1" 或 "A"。
d、boolean isControlDown():返回 Control 修饰符在此事件上是为 down。(用于组合键)
e、void consume():不会按照默认的方式由产生此事件的源代码来处理此事件。如只在文本区域添加数字时,当添加字符就不会进入文本区域
f、常用字段:VK_XXX(XXX表示键盘的键)
⑤代码实例:
/* 02. 鼠标事件和键盘事件演示 03. 使鼠标点击x能关闭窗口 04. 使键盘也具备关闭窗口功能 05.*/ 06.import java.awt.*; 07.import java.awt.event.*; 08.class MouseAndKeyTest 09.{ 10. private Frame f; 11. private Button b; 12. private TextField tf; 13. 14. MouseAndKeyTest() 15. { 16. init(); 17. } 18. 19. //定义方法,初始化窗体同时对其进行基本设置 20. public void init() 21. { 22. f = new Frame("我的窗体"); 23. b = new Button("按钮"); 24. tf = new TextField(10); 25. 26. //设置窗体 27. f.setBounds(400,300,600,500); 28. f.setLayout(new FlowLayout()); 29. 30. //添加文本框 31. f.add(tf); 32. //添加按钮 33. f.add(b); 34. 35. 36. f.setVisible(true); 37. 38. event(); 39. } 40. //为窗体注册监听器,为了代码规范性,将其进行封装 41. public void event() 42. { 43. //添加窗体监听器 44. f.addWindowListener(new WindowAdapter() 45. { 46. //关闭窗体功能 47. public void windowClosing(WindowEvent e) 48. { 49. System.exit(0); 50. } 51. }); 52. 53. //为按钮添加鼠标监听 54. b.addMouseListener(new MouseAdapter() 55. { 56. int count = 1;//定义计数器 57. int clickCount = 1; 58. public void mouseEntered(MouseEvent e) 59. { 60. System.out.println("鼠标进入到该组件"+count+++"次"); 61. } 62. public void mouseClicked(MouseEvent e) 63. { 64. if(e.getClickCount()==2) 65. System.out.println("鼠标双击"+clickCount+++"次"); 66. } 67. }); 68. 69. //为按钮添加键盘监听 70. b.addKeyListener(new KeyAdapter() 71. { 72. public void keyPressed(KeyEvent e) 73. { 74. //获取键盘上的字符及其整数值 75. System.out.println(e.getKeyChar()+":"+e.getKeyCode()); 76. System.out.println(e.getKeyText(e.getKeyCode())+":"+e.getKeyCode()); 77. 78. //组合建的使用,使按钮也具备关闭窗口功能 79. if(e.isControlDown() && e.getKeyCode()==KeyEvent.VK_ENTER) 80. { 81. System.out.println("contral+enter"+"关闭窗口"); 82. System.exit(0); 83. } 84. } 85. 86. }); 87. //鼠标活动事件 88. b.addActionListener(new ActionListener() 89. { 90. public void actionPerformed(ActionEvent e) 91. { 92. System.out.println("动啦!!"); 93. } 94. }); 95. 96. //为文本区域注册键盘监听器 97. tf.addKeyListener(new KeyAdapter() 98. { 99. public void keyPressed(KeyEvent e) 100. { 101. //让键盘只接受数字,当输入的不是数字,不添加进文本区域 102. int code = e.getKeyCode(); 103. if(!(code>=KeyEvent.VK_1 && code<=KeyEvent.VK_9)) 104. { 105. System.out.println(code+"非法字符"); 106. e.consume();//不按默认方式处理事件 107. } 108. } 109. }); 110. 111. } 112. public static void main(String[] args) 113. { 114. new MouseAndKeyTest(); 115. } 116.}
四、文本框、对话框及菜单
1、文本框(TextComponent)
①TextFile 单行文本,常用方法如下:String getText():返回此文本组件表示的文本。
void setText(String t):将此文本组件显示的文本设置为指定文本。
②TextArea 多行文本,常用方法如下:
String getText():返回此文本组件表示的文本。
void setText(String t):将此文本组件显示的文本设置为指定文本。
void append(String str):将给定文本追加到文本区的当前文本。
2、对话框(Dialog)
①常用构造方法:Dialog(Frame owner,String title,boolean modal):构造一个最初不可见的 Dialog,它带有指定的所有者 Frame、标题和模式(为true时,对话框不关闭,Frame不能操作)。②子类FileDialog(文本对话框)
a、常用构造方法
FileDialog(Dialog parent, String title, int mode): 创建一个具有指定标题的文件对话框窗口,用于加载或保存文件。
b、常用方法
String getDirectory():获取此文件对话框的目录。
String getFile():获取此文件对话框的选定文件。如果用户选择 CANCEL,则返回文件为 null。
3、菜单(Menu)
①菜单组建构成图②菜单组件概述
lMenuBar,Menu,MenuItem
先创建菜单条,再创建菜单,每一个菜单中建立菜单项。
通过setMenuBar()方法,将菜单添加到Frame中。
4、综合小练习
代码实现如下:/* 02.需求:在窗体中列出指定目录内容,当指定目录不存在,弹出提示窗口。 03.思路: 04. 1.创建窗体,对其进行基本设置。 05. 2.创建Button,TextFiled,TextArea对象,并加入窗体中 06. 3.分别对以上容器注册监听器 07. 4.当当指定目录不存在,弹出Diolog窗口。 08.*/ 09.import java.awt.*; 10.import java.awt.event.*; 11.import java.io.*; 12. 13.class TextTest 14.{ 15. private Frame f; 16. private Button b; 17. private TextField tf; 18. private TextArea ta; 19. 20. private Dialog d; 21. private Button okBut; 22. private Label lab; 23. 24. TextTest() 25. { 26. init(); 27. } 28. 29. public void init() 30. { 31. //创建窗体对象和其内部对象 32. f = new Frame("我的窗体"); 33. b = new Button("转到"); 34. tf = new TextField(60); 35. ta = new TextArea(20,65); 36. 37. //创建对话框对象 38. d = new Dialog(f,"文件资源管理器",true); 39. lab = new Label("您输入的信息:"+"路径不存在!"); 40. okBut = new Button("确定"); 41. 42. d.setBounds(300,200,300,200); 43. d.setLayout(new FlowLayout()); 44. d.add(lab); 45. d.add(okBut); 46. 47. f.setBounds(300,200,600,500); 48. f.setLayout(new FlowLayout()); 49. 50. f.add(tf); 51. f.add(b); 52. f.add(ta); 53. 54. f.setVisible(true); 55. 56. event(); 57. } 58. 59. public void event() 60. { 61. //为窗体注册窗体监听 62. f.addWindowListener(new WindowAdapter() 63. { 64. public void windowClosing(WindowEvent e) 65. { 66. System.exit(0); 67. } 68. }); 69. 70. //为按钮注册活动监听,触发事件则显示目录 71. b.addActionListener(new ActionListener() 72. { 73. public void actionPerformed(ActionEvent e) 74. { 75. 76. showDir(); 77. } 78. }); 79. //为文本框添加键盘监听 80. tf.addKeyListener(new KeyAdapter() 81. { 82. public void keyPressed(KeyEvent e) 83. { 84. if(e.getKeyCode()==KeyEvent.VK_ENTER) 85. showDir(); 86. } 87. }); 88. 89. //为对话框的按钮添加活动监听 90. okBut.addActionListener(new ActionListener() 91. { 92. public void actionPerformed(ActionEvent e) 93. { 94. d.setVisible(false);//隐藏对话框 95. } 96. }); 97. 98. } 99. 100. //定义方法,显示目录 101. public void showDir() 102. { 103. String dirPath = tf.getText(); 104. File dir = new File(dirPath); 105. 106. if(dir.exists() && dir.isDirectory()) 107. { 108. ta.setText(""); 109. String[] files = dir.list();//列出当前目录的文件对象的名称,listFiles会把绝对路径列出来。 110. for(String f: files) 111. { 112. ta.append(f.toString()+"\r\n"); 113. } 114. } 115. 116. else//如果目录不存在,弹出对话框提示 117. { 118. 119. String info = "您输入的信息:"+dirPath+"路径不存在!"; 120. lab.setText(info); 121. 122. d.setVisible(true);//这行一定放在最后,否则不能显示label的文本 123. } 124. } 125. 126. public static void main(String[] args) 127. { 128. new TextTest(); 129. } 130.}
五、jar包双击执行图形化程序
1、class文件打包
怎样才能通过图形化操作的方式的打开我们制作的图形化程序呢?这就需要将class文件打包了。步骤如下:①首先要在java文件中导入一个包,没有则需创建一个包,如package myfile;
②生成包:通过编译javac -d f:\\ SaveFile.java (将包存放在f盘)此时则在f盘下的myfile文件夹下生成了所有的.class文件
③在此目录下新建一个文件,如1.txt或者其他任意名称任意扩展名的文件都可,然后在其中编辑固定的格式:“Main-Class: myfile.SaveFile”,只写引号中的内容。需要需要在冒号后有一个空格,在文件末尾要回车。
④编译:jar -cvfm my.jar 1.txt mymenu即可。如果想添加其他信息,则直接编译jar即可得出相应的命令
⑤此时双击即可执行。
2、注意事项
①在固定格式中:如果无空格:在编译的时候,就会报IO异常,提示无效的头字段,即invalidheader field。这说明1.txt在被IO流读取。
如果无回车:在列表清单.MF中不会加入相应的加载主类的信息,也就是说配置清单的属性主类名称不会加载进清单中,也就不会执行。
②jar文件必须在系统中注册,才能运行。注册方法如下:
对于XP系统:
a、打开任意对话框,在菜单栏点击工具按钮,选择文件夹选项
b、选择新建--->扩展名,将扩展名设置为jar,确定
c、选择高级,可更改图标,然后点击新建,命名为open,
d、在用于可执行应用程序中,点浏览,将jdk下的bin的整个文件路径添加进来,并在路径后添加-jar即可。
对于win7/win8系统:
a、改变打开方式:右击.jar文件,点击打开方式,选择默认程序为jdk下bin中的javaw.exe应用程序。
b、修改关联程序的注册表:打开注册表(win+r),找到注册表路径\HKEY_CLASSES_ROOT\Aplications\javaw.exe\shell\open\command下的字符串值,右击点修改,在原路径的中添加-jar,如:"C:\ProgramFiles\Java\jre6\bin\javaw.exe" -jar "%1",注意-jar两边要有空格,保存。
c、双击即可执行jar程序。
相关文章推荐
- UIView的xib和UIViewController的xib的区别
- easyui datagrid显示进度条控制操作
- 泛型容器单元(Generics.Collections)[2]: TQueue<T> 队列列表
- RequireJS 参考文章
- require.js的用法
- JAVA ERROR---Access restriction: The type JOptionPane is not accessible due to restriction on requir
- 225.Implement Stack using Queues
- UITextView自适应内容的高度且实现光标总是距离键盘一段距离而滑动条却可以延伸到光盘
- require.js的用法
- Android UiAutomator 自动化环境搭建
- iOS 多线程开发之OperationQueue(二)NSOperation VS GCD
- easy=ui 树形结构案例
- 关于UIImageView不显示图片的问题小记
- UIButton 设置阴影效果
- iOS UIView非常用方法及属性详解
- ueditor 长文章分页
- Win10 Build 10154全新壁纸:海滩上奔跑的美女
- Windows 10 Build 10149手机预览版中文评测视频
- ios上 更改 状态栏(UIStatusBar)的颜色
- Windows 10 build 10154更新日志 神秘刮刮乐现身