欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javaGUI基础(一)

程序员文章站 2022-05-28 11:35:55
...

JavaGUI基础(一)

GUI(Graphical User Interface),图形用户接口。用来做java窗口图形界面的。

java自带的开发技术分为:AWT、Swing(AWT相当于Swing的前身,Swing相较于AWT更封装了一些东西),但是由于它们做出来的界面并不美观,所以并不流行但是这是基础。

javaGUI是由java写的,所以写界面就相当于创建很多个类对象进行操作。还是基于java的,所以你的java基础要有的。

先来介绍AWT。

AWT

在AWT中一个图形界面由:组件(基本组件与容器构成)及其监听事件构成。组件的继承图如下:

javaGUI基础(一)

这些不都是类,Button,Frame等是类,Component,Container等是接口。你可以在源码中自行查看。

Frame

先来学最基层的Frame,Frame是一个主窗口。相对的Dialog是弹出框,不是主窗口,主窗口关了那么你的程序就结束了。是比如这个文档框:

javaGUI基础(一)

接下来介绍怎么创建以及一些基础函数:

//创建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啥,啥会把上一个覆盖掉,因为就一块。若设置布局,会根据布局往里面添加假如设置的是两行两列的布局,只添加两个组件那么这两个组件会平分整个框。但是加入三个那么就会分配不均剩余一个,这时你会看见窗口的背景色

流式布局

流式布局如其名,是按一条流水线布局的。

javaGUI基础(一)

在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);

javaGUI基础(一)

表格布局

//两行两列
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"));

javaGUI基础(一)

画笔

画笔首先要有画板,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();
    }
})
相关标签: GUI