javaGUI基础(一)
JavaGUI基础(一)
GUI(Graphical User Interface),图形用户接口。用来做java窗口图形界面的。
java自带的开发技术分为:AWT、Swing(AWT相当于Swing的前身,Swing相较于AWT更封装了一些东西),但是由于它们做出来的界面并不美观,所以并不流行但是这是基础。
javaGUI是由java写的,所以写界面就相当于创建很多个类对象进行操作。还是基于java的,所以你的java基础要有的。
先来介绍AWT。
AWT
在AWT中一个图形界面由:组件(基本组件与容器构成)及其监听事件构成。组件的继承图如下:
这些不都是类,Button,Frame等是类,Component,Container等是接口。你可以在源码中自行查看。
Frame
先来学最基层的Frame,Frame是一个主窗口。相对的Dialog是弹出框,不是主窗口,主窗口关了那么你的程序就结束了。是比如这个文档框:
接下来介绍怎么创建以及一些基础函数:
//创建Frame对象
//调用默认构造器
Frame frame = new Frame();
//调用有参构造器 字符串参数以上图为例
Frame frame = new Frame("新建文本文档(2).txt - 记事本");
//创建了窗口并不能看见,在内存中存着。只有设置为可见才行
frame.setVisible(ture);
//设置窗口大小
frame.setSize(width, height);
//设置窗口位置
frame.setLocation(x, y);
//设置位置以及颜色
frame.setBounds(x, y, w, h);
//设置背景颜色,参数是Color对象
frame.setBackGround(new Color(...));
//设置大小固定,窗口本身可以放大缩小。
frame.setResiable(false);
//添加基本组件
frame.add(new Button("btn"));
可以往窗口中add很多东西,只要是继承自Component的就行,比如:panel、button、textarea…等等。
创建一个窗口的小示例:
public class Test {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setResizable(false);
frame.setSize(100, 100);
frame.setLocation(100, 100);
//frame.setBounds(100, 100, 100, 100);
frame.setBackground(Color.CYAN);
frame.add(new Button("111"));
}
}
在不设置布局的情况下,加入的东西会将整个frame占据,所以你看见的是一整个按钮,背景颜色被注释掉了。
Panel
Panel是一个面板,也是继承自Component接口。也是可以加入Frame的。
Frame与Panel的关系就相当于:**假如你有一幅画要图,这幅画分为了很多区域。Frame就相当于画,Panel相当于各个区域。你可以在各个区域中加入你想的一些奇思妙想,最后将各个区域拼凑起来画就好了。**当然你也可以将各个区域再次分区域,就是Panel里add Panel了。
Panel与Frame操作类似,因为Panel就相当于没有窗口的Frame。
//创建面板,默认是设置为流式布局。也可以传入布局参数。
Panel panel = new Panel();
//面板也有设置可不可见,面板的默认可见性与窗口相同。
panel.setVisible(ture);
//设置面板大小,但是这没啥用,因为panel的大小会根据装它的布局决定
panel.setSize(width, height);
//设置面板位置,位置也是根据布局决定
panel.setLocation(x, y);
//设置位置以及颜色
panel.setBounds(x, y, w, h);
//设置背景颜色,参数是Color对象
panel.setBackGround(new Color(...));
//设置大小固定,窗口本身可以放大缩小。
panel.setResiable(false);
//添加基本组件
panel.add(new Button("btn"));
创建一个面板的小示例:
public class PanelTest {
public static void main(String[] args) {
Frame frame = new Frame("MyFitstPanel");
//设置可见
frame.setVisible(true);
//设置大小以及位置
frame.setSize(350, 400);
frame.setLocation(100, 100);
frame.setBackground(new Color(100, 200, 3));
//设置大小不变
frame.setResizable(false);
frame.setLayout(new GridLayout(2,2));
Panel panel = new Panel();
panel.setBackground(Color.MAGENTA);
panel.setBounds(100, 100, 10, 10);
panel.setVisible(false);
frame.add(panel);
frame.add(new Button("11"));
frame.add(new Button("11"));
}
}
由这个示例可以看出add的过程,以及Panel不必设置大小与位置(因为没用,当然是我没见过(笑哭)。若有这样用的话,当看个笑话就行。顺便评论里说一下我也多学习,蟹蟹。)
基本组件
基本组件都可以往面板或窗口里添加。
Button按钮
Button btn = new Button("button-name");
TextField文本框
文本框不同于文本域,它是不可以换行的。
//参数是文本框里出现的内容,若无参默认文本框里是空字符串也就是"" <-这个
TextField tf = new TextField();
TextField tf = new TextField("123456");
//若参数是int型,那么重载构造就是文本框最大可以输入多少字符
TextField tf = new TextField(10);
//设置替换字符,比如密码框就是这样的:
tf.setEchoChar("*");
Label标签
标签组件就是在上边显示的,不能点也不能操作。
Label label = new Label("标签内容");
基本是不用AWT中的基本组件的,Swing中的花样、姿势更多。
三种布局管理器
不设置布局的情况下frame add啥,啥会把上一个覆盖掉,因为就一块。若设置布局,会根据布局往里面添加假如设置的是两行两列的布局,只添加两个组件那么这两个组件会平分整个框。但是加入三个那么就会分配不均剩余一个,这时你会看见窗口的背景色
流式布局
流式布局如其名,是按一条流水线布局的。
在Frame和Panel,只要是继承Container即可用。
//它们默认就是流式布局
frame.setLayout(new FlowLayout())
东西南北中
frame.setLayout(new BorderLayout());
frame.add(new Button("1"), BorderLayout.EAST);
frame.add(new Button("1"), BorderLayout.WEST);
frame.add(new Button("1"), BorderLayout.NORTH);
frame.add(new Button("1"), BorderLayout.SOUTH);
frame.add(new Button("1"), BorderLayout.CENTER);
表格布局
//两行两列
frame.setLayout(new GridLayout(2, 2));
frame.add(new Button("1"));
frame.add(new Button("1"));
frame.add(new Button("1"));
frame.add(new Button("1"));
画笔
画笔首先要有画板,frame与panel本身是可以在上边涂画的**(在paint函数中涂画)**。常规操作是在将panel作为画板,再放入窗口中。简单起见就直接在frame上操作了。
原frame或panel它的paint函数中没有操作所以他们作为窗口与面板(起到容器的作用,放东西)。但是重写paint后可以作为画板,当然add方法还存在仍可以放东西。
比如可以这样,Paint继承Panel重写paint函数作为画板
public class Test {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100, 100, 100, 100);
frame.add(new Paint());
}
}
class Paint extends Panel{
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.CYAN);
g.fillOval(10, 10, 10, 10);
}
}
这是比较简单的运用,也可以将其与监听器结合做一个简单的windows画图工具,只不过刷新频率低一些。
监听事件
监听事件,顾名思义监听一些组件。比如:按下X关闭窗口、按下按钮跳出个窗口之类的。监听事件是连接用户界面与对应操作之间的桥梁。
窗口监听
在前面的学习过程中你是否点击关闭试一试了呢?嗯!它是关闭不了的。在使用一个软件时一个窗口最基本的功能是可以关闭,放大缩小。在前面的过程中只要不设置setResiable为false就可以放大,最小化是一直存在的。但是关闭需要窗口监听器。
窗口监听器可以实现WindowListener接口来实现也可以继承WindowAdapter抽象类实现
使用WindowListener接口实现:
class MyWindowListener implements WindowListener{
public MyWindowListener() {
super();
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@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) {
}
}
既然是接口的实现类那么所有的方法都要重写。是不是太麻烦了呢!有更好的方法——适配器小盆友登场!!!(WindowAdapter)。
使用继承WindowAdapter抽象类实现:
class My extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
}
}
为什么?让我们来康康源码
public abstract class WindowAdapter
implements WindowListener, WindowStateListener, WindowFocusListener
{
public void windowOpened(WindowEvent e) {}
public void windowClosing(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowStateChanged(WindowEvent e) {}
public void windowGainedFocus(WindowEvent e) {}
public void windowLostFocus(WindowEvent e) {}
}
是的!小盆友已经帮我们实现了里面的方法,都是空方法。所以只要随便重写一个就是可new类,哪怕不重写也可以new。
有了监听器那么要与对应的设备(窗口)相关联,使用Container的实现类们的独有函数addWindowListener(WindowListener l)
//实参是一个实现类,但是形参是一个接口。还记得接口引用指向子类对象吗?
frame.addWindowLstener(new MyWindowListener);
那么来写一个小程序带窗口监听的:
public class Test {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100, 100, 100, 100);
//这是一个匿名类
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
//0正常退出,1异常退出。是个状态值用来查看的。
System.exit(0);
}
});
}
}
组件监听
除了点击窗口关闭之外,平常在软件里还有哪些应用呢?比如qq的发送键,点击一下发送按钮就发出去信息了。
首先是点击按钮,其次才发送信息。也就是说发送信息这个操作是附加在一个按钮上的。
//那么首先new一个button
Button button = new Button("111");
//其次附加操作
button.addActionListener(new MyActionListener);
int n = 0;
然后就是写操作了,与前面的窗口监听一样。但是由于动作监听器只有一个方法需要重写,所以就没有适配器。
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println"点了"+(++n));
//显示了之后再用网络编程发送过去让他也显示就成了
}
});
所有基础组件都是用的这个监听器
鼠标监听
在使用windows画板时,绘画使用到了鼠标。前面学了画板,只要与鼠标监听相关联就能实现:点一下画一个点(fillOval特小的圆)。addMouseListener(MouseListener i)
鼠标是在窗口上挥来挥去的所以说鼠标监听是加载窗口(也就是画板如果要画画的话)上的,玩射击游戏时鼠标监听监听窗口,可以得到鼠标在窗口上的坐标,这就是准心了。
鼠标监听的小程序
public class Test {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100, 100, 100, 100);
Paint paint = new Paint();
frame.add(paint);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
class Paint extends Panel{
int x, y;
public Paint(){
addMouseListener(new MyMouse());
}
@Override
public void paint(Graphics g) {
//这里的g表示画笔对象,下面的e表示对象:鼠标。获取鼠标的资源可以得到鼠标所监听的对象的一些函数
super.paint(g);
g.setColor(Color.CYAN);
g.fillOval(x, y, 5, 5);
}
class MyMouse extends MouseAdapter{
@Override
public void mousePressed(MouseEvent e) {
Panel eSource = (Panel) e.getSource();
x = e.getX();
y = e.getY();
paint(eSource.getGraphics());
eSource.repaint();
}
}
}
重要的是思想:首先要有一个画板,画板要与鼠标相关联(监听器),然后通过鼠标的参数画点。所以使用了内部类。外部类我不知道怎么传递x,y。把xy都写成静态用个静态函数可以但是不好看了就。有知道怎么写的小伙伴可以评论里说一下!3Q
这里的画板只有一组点记录所以只能点一个点,要向多个用个Vector记录即可。
键盘监听
相信经过上面的监听器的介绍,下面的键盘监听无师也能自通把。
//第一步
frame.addKeyListener(new KeyAdapter(){
@Override
public void keyPressed(KeyEvent e){
//获取键值(ASCII码)
int keyCode = e.getKeyCode();
}
})
上一篇: Qt5--多窗口编程实例