个人理解吧,作为程序员,和计算机进行“交流”就那么几种方式吧,一是通过命令行的方式去指导计算机执行各种动作,还有一种就是通过各种带有UI(UserInterface 用户界面)的更加直接直观的方式,而第二种也是如今比较流行的一种方式,这也是技术发展所必需的,是的计算机不再那么让人敬而远之了,好了,废话少说,看看我们的java GUI都有些什么呢?
一,什么是GUI?
图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。与早期计算机使用的命令行相比,图形界面对于用户来说在视觉上更易于接受(来自百度百科)。当然java作为一种强大变成语言,自然也为我们程序员提供了界面开发工具类库(java.awt),早期呢,java提供的GUI类库为Abstract Window Tookit(简单翻译为抽象窗体工具包) ,就是AWT,AWT功能的扩展性不是很好,而且是一种重量级的组件,不能很好的访问OS中一些高级的GUI特性,而且不能很好的支持跨平台,所以,sun就对awt进行了升级,在JDK1.2yihou便产生了Swing组件,swing“轻量级”(全部是 Java 语言)组件,支持了扩平台,也就是很好的解决了awt的一些缺点,而且也有扩展,使用起来方便,界面更加美观。
二、GUI有什么?
GUI包含两类组件(Component)对象:容器和控件。
容器(container):用于放置其他组件,eg. Frame ,JFrame ,Applet;
控件:Label(标签) Button(按钮)等等
三、AWT和Swing包中的类结构
Component
| ————Label
| ————Button
| ————Checkbox
| ————Scrollbar
| ————Container
|--Panel
|--Window ——|---Dialog
|---Frame
是的,还没有完,还有像Menu,TextArea,TextField,就不一一列举了,Swing中的类结构AWT类似,只是在AWT类前增加J,以示区别,就比如JFrame、JButton等等,实际上可能Swing组件使用的更加广泛。
JComponent
| ————JLabel
| ————JButton
| ————JCheckbox
| ————JScrollbar
| ————JContainer
|--JPanel
|--JWindow ——|---JDialog
|---JFrame
四、布局管理器(Layout)
有了这些组件,那就有一个问题摆在我们面前了,这些组件该怎么放置呢,顺序又是什么呢?等等。Java便通过布局管理器给了我们很好地回答。
布局管理器负责安排GUI组件的位置,java中布局管理器提供以下几种布局功能:
lFlowLayout:从左到右的次序放置组件;
lBorderLayout:将容器的分成东、西、南、北、中5个区域;
lGridLayout:按行和列排列;
lBoxLayout:从左到右或从上到下放置组件;
lCardLayout:将组件重叠堆放;
lGridBagLayout:与GridLayout类似,但组件的次序可变,并且能以任何次序添放组件。
java中默认的布局是BorderLayout布局,要想指定特定的布局可以通过,比如setLayout(new FlowLayout())来完成。
举一例说明布局,我们在这里用JFrame(更主流一些),毕老师为了让我理解awt和swing,就以awt为对象讲授了。
import javax.swing.*;
import java.awt.*;
public class FlowlayoutFrame extends JFrame{
public FlowlayoutFrame(){
//setTitle("BorderLayout 布局");
setTitle("FlowLayout 布局");
setLayout(new FlowLayout());
add(new JButton("B1")/*,"Center");
add(new JButton("B2"),"West"*/);
add(new JButton("B3")/*,"East"*/);
add(new JButton("B4")/*,"North"*/);
add(new JButton("B5")/*,"South"*/);
}
public static void main(String[]args){
FlowlayoutFrame f = new FlowlayoutFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(300,120);
f.setVisible(true);
}
}
这是一个简单的流式布局的例子,效果如下图:
将流式布局的部分setLayout(new FlowLayout())注释,把原来注释的部分打开,就是边界布局的效果了,
其他几个布局也可以同样做几个Demo了解效果。
五、GUI对事件的处理
有了这几个界面之后,我们就想要操作这些界面了,这种想法很自然,那么我们怎么才能让点击的按钮有反应呢?别急,我们慢慢来。
先来了解一下Java对GUI的事件处理采用事件源-事件监听者模式,其实现机制:
1.通过事件监听者来监听事件源产生的事件;
2.事件监听者实现对应的事件监听接口,处理相应的消息;
二话不说,举一例子说明,上源码:其实很简单,图形很简单就一个文本框和按钮,当点击键盘control+enter键时推出程序。
import java.awt.*;
import java.awt.event.*;
public class MouseAndKeyEvent
{
//定义该图形中所需的组件的引用。
private Frame f;
private Button but;
private TextField tf;
MouseAndKeyEvent()
{
init();
}
public void init()
{
f = new Frame("my Frame");
//对frame进行基本设置。
f.setBounds(300,100,600,500);
f.setLayout(new FlowLayout());
but = new Button("My button");
tf = new TextField(20);
//将组件添加到frame中
f.add(but);
f.add(tf);
//加载一下窗体事件
myEvent();
//显示窗体
f.setVisible(true);
}
private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(!(e.getKeyCode() >= KeyEvent.VK_0 && e.getKeyCode() <= KeyEvent.VK_9))
{
System.out.println(e.getKeyCode()+".....非法的");
e.consume();
}
}
});
but.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Action OK");
}
});
but.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER)
{
System.exit(0);
}
//组合键的使用
//System.out.println(KeyEvent.getKeyText(e.getKeyCode()) + "..." + e.getKeyCode());
}
});
}
public static void main(String[] args)
{
new MouseAndKeyEvent();
}
}
六、扩展 菜单 对话框
这两个其实也很重要,这两个类以一个例子说明,最典型的莫过于简单记事本开发了,就只先实现打开保存和退出功能了。二话不说,上源码:
package mymenu;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class MyMenuTest
{
private Frame f;
private MenuBar mb;
private TextArea ta;
private Menu fileMenu;
private MenuItem closeItem , openItem,saveItem; //子菜单项Item
private FileDialog openDia,saveDia;
private File file;
MyMenuTest()
{
init();
}
public void init()
{
f = new Frame("My Window");
f.setBounds(300,100,500,600);
mb = new MenuBar();
ta = new TextArea();
fileMenu = new Menu("文件");
openItem = new MenuItem("打开");
saveItem = new MenuItem("保存");
closeItem = new MenuItem("退出");
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(closeItem);
mb.add(fileMenu);
openDia = new FileDialog(f,"我要打开",FileDialog.LOAD);
saveDia = new FileDialog(f,"我要保存",FileDialog.SAVE);
f.setMenuBar(mb);
f.add(ta);
f.setVisible(true);
myEvent();
}
private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
closeItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
openItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
openDia.setVisible(true);
String dirPath = openDia.getDirectory();
String fileName = openDia.getFile();
System.out.println(dirPath +"..."+ fileName);
if(dirPath == null || fileName == null)
return ;
ta.setText("");
File file = new File(dirPath , fileName);
try
{
BufferedReader bufr = new BufferedReader(new FileReader(file));
String line = null;
while((line = bufr.readLine())!= null)
{
ta.append(line + "\r\n");
}
bufr.close();
}
catch (IOException ioe)
{
throw new RuntimeException("读取失败!");
}
}
});
saveItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(file==null)
{
saveDia.setVisible(true);
String dirPath = saveDia.getDirectory();
String fileName = saveDia.getFile();
if(dirPath == null || fileName == null)
return ;
file = new File(dirPath,fileName);
}
try
{
BufferedWriter bufw = new BufferedWriter(new FileWriter(file));
String text = ta.getText();
bufw.write(text);
bufw.close();
}
catch (IOException ioe)
{
throw new RuntimeException("保存失败!");
}
}
});
}
public static void main(String[] args)
{
new MyMenuTest();
}
}
运行效果