GUI学习

GUI学习

前言:本来不打算学习Gui的,不过最近需要用到还是学习一下吧

1.1 awt 与swing

java的图形化界面的对象存在于awt与swing包中,awt需要调用本地系统方法实现功能,在不同的

平台下显示不同,swing是在awt的基础上实现的一套图形化界面,提供了更多组件,由于全部都适

用java完成,所以在不同平台下显示相同,这就给移植到不同平台提供了可能。

在java gui中,所有的内容都是通过组件实现的。组件和容器

1.2 Frame的使用

package com.ch2;

import javax.swing.*;
import java.awt.*;
public class Gui {
    public static void main(String[] args){
        Frame frame =new Frame("first gui");
        frame.setVisible(true);//可视化
        frame.setSize(300,300);
        frame.setBackground(new Color(135, 36, 36));//背景颜色
        frame.setLocation(100,100);//窗口位置
        frame.setResizable(false);//不能缩放大小
    }
}

通过上述操作,我们就生成了一个窗口,并设定了大小,背景颜色等

每次都要初始化比较麻烦,我们通过继承进行封装

package com.ch2;

import java.awt.*;

public class Test {
    public static void main(String[] args)
    {
        new Nframe(100,200,300,200);
        new Nframe(380,200,300,200);
        new Nframe(700,200,300,200);
    }
}
class Nframe extends Frame{
    static int id=0;
    public Nframe(int x,int y,int w,int h){
        super("Frame"+id++);
        this.setVisible(true);
        this.setBounds(x,y,w,h);
        this.setBackground(new Color(241, 232, 232));
    }
}

1.3 Panel的使用

package com.ch2;

import javax.swing.*;
import java.awt.*;
public class Gui {
    public static void main(String[] args) {
        Frame frame =new Frame();
        Panel panel=new Panel();
        frame.setLayout(null);
        frame.setBackground(Color.red);
        frame.setBounds(100,100,500,500);
        panel.setBackground(Color.blue);
        panel.setBounds(10,10,500,500);
        frame.add(panel);
        panel.setVisible(true);
        frame.setVisible(true);
    }
}

panel并不像frame一样直接具有可见性,想要利用panel必须将其添加到容器中比如frame我们在

设置panel时 panel.setBounds(10,10,500,500);选定的是相对其父容器的位置,也就是0,0点是该

frame的左上角

1.4 关闭窗口

就比如我们上面的那个窗口,如果我们想要关闭需要怎么操作呢

package com.ch2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Gui {
    public static void main(String[] args) {
        Frame frame =new Frame();
        Panel panel=new Panel();
        frame.setLayout(null);
        frame.setBackground(Color.red);
        frame.setBounds(100,100,500,500);
        panel.setBackground(Color.blue);
        panel.setBounds(10,10,500,500);
        frame.add(panel);
        panel.setVisible(true);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

向窗口中添加一个窗口监听器,重写在点击关闭键时需要调用的方法,我们这里只需要关闭当前窗

口即可。

1.5 布局方式

流式布局

package com.ch2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Gui {
    public static void main(String[] args) {
        Frame frame =new Frame();
        Panel panel=new Panel();
        frame.setLayout(null);
        frame.setBackground(new Color(248, 244, 244));
        frame.setBounds(100,100,500,500);
//        panel.setBackground(Color.blue);
//        panel.setBounds(10,10,500,500);
//        frame.add(panel);
//        panel.setVisible(true);
        frame.setVisible(true);
        Button button1 = new Button("Button1");
        Button button2 = new Button("Button2");
        frame.add(button1);
        frame.add(button2);
        frame.setLayout(new FlowLayout());//流式布局
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

当我们向面板中添加比如按钮等组件时(这里先放在窗口中),需要设置组件的布局方式,即这些组件需要放

的位置,通过setLayout(); 来设置,我们先学习流式布局FlowLayout(),按行从上到下进行布局,一行满

了进入下一行,如果不加参数的话,默认情况下在同一行是进行居中放置的。

我们想要靠右可以new FlowLayout(FlowLayout.RIGHT) 靠左同理

东西南北中布局

如果我们想要让组件按东西南北中分布,则可以像下面这样操作

package com.ch2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Gui {
    public static void main(String[] args) {
        Frame frame =new Frame();
        Panel panel=new Panel();
        frame.setBackground(new Color(248, 244, 244));
        frame.setBounds(100,100,500,500);
//        panel.setBackground(Color.blue);
//        panel.setBounds(10,10,500,500);
//        frame.add(panel);
//        panel.setVisible(true);
        frame.setVisible(true);
        Button button1 = new Button("Button1");
        Button button2 = new Button("Button2");
        Button button3 = new Button("Button3");
        Button button4 = new Button("Button4");
        frame.add(button1, BorderLayout.SOUTH);
        frame.add(button2, BorderLayout.NORTH);
        frame.add(button3, BorderLayout.WEST);
        frame.add(button4, BorderLayout.EAST);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

这种布局只能这样设置

表格布局

package com.ch2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Gui {
    public static void main(String[] args) {
        Frame frame =new Frame();
        Panel panel=new Panel();
        frame.setBackground(new Color(248, 244, 244));
        frame.setBounds(100,100,500,500);
//        panel.setBackground(Color.blue);
//        panel.setBounds(10,10,500,500);
//        frame.add(panel);
//        panel.setVisible(true);
        frame.setVisible(true);
        Button button1 = new Button("Button1");
        Button button2 = new Button("Button2");
        Button button3 = new Button("Button3");
        Button button4 = new Button("Button4");
        frame.setLayout(new GridLayout(2,2));
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
        frame.pack();
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}


frame.setLayout(new GridLayout(2,2));用于设置表格布局,表格布局将容器按我们要求进行划分

比如当前设置的是两行两列,然后按照我们添加顺序对其进行填充。pack()是用于自动调整窗口的大小,以适

应其内容

布局间可以进行组合,通过不同布局的组合来实现不同的布局,比如我们可以这样用:

package com.ch2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Gui {
    public static void main(String[] args) {
        Frame frame =new Frame();
        frame.setVisible(true);
        frame.setBounds(100,100,400,400);
        frame.setLayout(new GridLayout(2,1));
        Panel panel1 =new Panel(new BorderLayout());
        Panel panel2 =new Panel(new GridLayout(2,1));
        Panel panel3 =new Panel(new GridLayout(2,1));
        Panel panel4 =new Panel(new BorderLayout());
        panel1.add(new Button("left"),BorderLayout.EAST);
        panel1.add(new Button("right"),BorderLayout.WEST);
        panel4.add(new Button("right"),BorderLayout.WEST);
        panel4.add(new Button("left"),BorderLayout.EAST);
        panel2.add(new Button("up"));
        panel2.add(new Button("down"));
        panel1.add(panel2,BorderLayout.CENTER);
        panel3.add(new Button("up"));
        panel3.add(new Button("down"));
        panel4.add(panel3,BorderLayout.CENTER);
        frame.add(panel1);
        frame.add(panel4);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

1.6事件监听

监听点击事件

package com.ch2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Gui {
    public static void main(String[] args) {
        Frame frame =new Frame();
        Button button=new Button("button");
        //button.addActionListener(e -> System.out.println("111"));
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("111");
            }
        });
        frame.add(button, BorderLayout.CENTER);
        frame.setBounds(100,100,300,300);
        frame.setVisible(true);
        windowClose(frame);
    }
    private static void windowClose(Frame frame){
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

我们利用匿名内部类去实现该操作,因为该接口是一个函数接口,所以我们也可以使用lambda表达式去写,

就是注释掉的那里

触发事件时我们重构的函数中的e是事件信息,我们可以自己去设计事件信息,使用setActionComand()

e也有方法去获取该信息 getActionComand()

1.7 输入框

在java中,输入框组件是TextField,

package com.ch2;
import org.w3c.dom.Text;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Gui {
    public static void main(String[] args) {
        new Mframe();
    }
}
class Mframe extends Frame  {
    public Mframe(){
        TextField textfield = new TextField();
        add(textfield);//调用的是父类的add方
        MyListener myListener=new MyListener();
        textfield.addActionListener(myListener);
        setVisible(true);
        setBounds(100,100,300,300);
        //pack();
    }
}
class MyListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        TextField field=(TextField) e.getSource();
        System.out.println(field.getText());
    }
}

其中ActionEvent 的getSource()方法的返回值是触发事件的对象,我们获得后就可

以在触发事件时对该对象进行各种操作。不过为了方便使用是用Object来指向的,

所以我们在后面需要用到强制类型转换去转换,该事件在我们在输入框输入内容后

按下回车时触发。

如果我们不想输入的内容被直接显示,可以使用setEchoChar来给出一个char类型

字符对输入的值在显示上进行替换,实际上还是原来的值只不过显示被我们设置的

字符替代

如果我们想要回车后将输入框清空,使用setText()即可

package com.ch2;
import org.w3c.dom.Text;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Gui {
    public static void main(String[] args) {
        new Mframe();
    }
}
class Mframe extends Frame  {
    public Mframe(){
        TextField textfield = new TextField();
        add(textfield);//调用的是父类的add方
        MyListener myListener=new MyListener();
        textfield.addActionListener(myListener);
        setVisible(true);
        setBounds(100,100,300,300);
        textfield.setEchoChar('*');
    }
}
class MyListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        TextField field=(TextField) e.getSource();
        System.out.println(field.getText());
        field.setText(null);
    }
}

1.8加法计算器

既然我们学会了上面的这些内容,我们可以试着写一些小东西了,比如下面的加法

计算器

package com.ch2;
import org.w3c.dom.Text;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Gui {
    public static void main(String[] args) {
        new Calc();
    }
}
class Calc extends Frame{
     Calc() {
        TextField textField1 = new TextField(10);
        TextField textField2 = new TextField(10);
        TextField textField3 = new TextField(20);
        Button button = new Button("=");
        Label label = new Label("+");
        setLayout(new FlowLayout());
        MyActionListener myActionListener = new MyActionListener(textField1,textField2,textField3);
        button.addActionListener(myActionListener);
        add(textField1);
        add(label);
        add(textField2);
        add(button);
        add(textField3);
        setVisible(true);
        pack();
        windowClose(this);
    }
    private void windowClose(Frame frame){
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyActionListener implements ActionListener{
    private TextField num1,num2,num3;
    public MyActionListener(TextField n1,TextField n2,TextField n3){
        num1 = n1;
        num2 = n2;
        num3 = n3;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        int n1=Integer.parseInt(num1.getText());
        int n2 = Integer.parseInt(num2.getText());
        int n3= n1+n2;
        num3.setText(Integer.toString(n3));
        num1.setText(null);
        num2.setText(null);


    }
}

我们使用组合类将其结合一下:

package com.ch2;
import org.w3c.dom.Text;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Gui {
    public static void main(String[] args) {
        new Calc();
    }
}
class Calc extends Frame{
    TextField textField1,textField2,textField3;
    Calc() {
        textField1 = new TextField(10);
        textField2 = new TextField(10);
        textField3= new TextField(20);
        Button button = new Button("=");
        Label label = new Label("+");
        setLayout(new FlowLayout());
        MyActionListener myActionListener = new MyActionListener(this);
        button.addActionListener(myActionListener);
        add(textField1);
        add(label);
        add(textField2);
        add(button);
        add(textField3);
        setVisible(true);
        pack();
        windowClose(this);
    }
    private void windowClose(Frame frame){
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
class MyActionListener implements ActionListener{
    Calc calc;
    public MyActionListener(Calc calc){
        this.calc=calc;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        int n1=Integer.parseInt(calc.textField1.getText());
        int n2 = Integer.parseInt(calc.textField2.getText());
        int n3= n1+n2;
        calc.textField3.setText(Integer.toString(n3));
        calc.textField2.setText(null);
        calc.textField1.setText(null);


    }
}

如果我们使用内部类进行优化

package com.ch2;
import org.w3c.dom.Text;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Gui {
    public static void main(String[] args) {
        new Calc();
    }
}
class Calc extends Frame{
    TextField textField1,textField2,textField3;
    Calc() {
        textField1 = new TextField(10);
        textField2 = new TextField(10);
        textField3= new TextField(20);
        Button button = new Button("=");
        Label label = new Label("+");
        setLayout(new FlowLayout());
        MyActionListener myActionListener = new MyActionListener();
        button.addActionListener(myActionListener);
        add(textField1);
        add(label);
        add(textField2);
        add(button);
        add(textField3);
        setVisible(true);
        pack();
        windowClose(this);
    }
    private void windowClose(Frame frame){
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
    class MyActionListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            int n1=Integer.parseInt(textField1.getText());
            int n2 = Integer.parseInt(textField2.getText());
            int n3= n1+n2;
            textField3.setText(Integer.toString(n3));
            textField2.setText(null);
            textField1.setText(null);


        }
    }
}

1.9 画笔

在java中我们可以在窗口中进行绘画,使用的就是画笔

下面我们看一下具体的用法

package com.ch2;
import org.w3c.dom.Text;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Gui {
    public static void main(String[] args) {
        new MyPaint().loadframe();
    }
}
class MyPaint extends Frame{
    public  void loadframe(){
        this.setBounds(100,100,500,500);
        this.setVisible(true);
    }
    public void paint(Graphics g){
        g.setColor(Color.red);
        g.drawOval(100,100,100,100);//画一个圆环
        g.fillOval(300,300,100,100);//画一个实心圆
        g.drawRect(200,200,100,100);//画一个矩形框
        g.fillRect(400,400,100,100);//画一个实心矩形
        windowClose();
    }
    private void windowClose (){
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

}

2.0 鼠标监听

我们使用鼠标监听实现在画板中画一个个点

package com.ch2;
import org.w3c.dom.Text;
import  java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;

public class Gui {
    public static void main(String[] args) {
        new Myframe("paint");
    }
}
class Myframe extends Frame {
    ArrayList<Point> points = new ArrayList<Point>();
    public Myframe(String title) {
        super(title);
        setBounds(100, 100, 500, 500);
        MyMouseListener ml = new MyMouseListener();
        addMouseListener(ml);
        setVisible(true);
        windowclose();

    }
    private void windowclose(){
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
    class MyMouseListener extends MouseAdapter {
        public void mousePressed(MouseEvent e) {
            Myframe myframe = (Myframe) e.getSource();
            points.add(new Point(e.getX(), e.getY()));
            repaint();

        }
    }

    @Override
    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        Iterator<Point> it = points.iterator();
        while (it.hasNext()) {
            Point p = it.next();
            g.fillOval(p.x, p.y, 5, 5);
        }
    }
}

2.1 键盘监听

package com.ch2;
import org.w3c.dom.Text;
import  java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;

public class Gui {
    public static void main(String[] args) {
        new Myframe("paint");
    }
}
class Myframe extends Frame {
    ArrayList<Point> points = new ArrayList<Point>();
    public Myframe(String title) {
        super(title);
        setBounds(100, 100, 500, 500);
        MyKeyListener mykeylistener = new MyKeyListener();
        addKeyListener(mykeylistener);
        setVisible(true);
        windowclose();

    }
    private void windowclose(){
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                //setVisible(false);
                System.exit(0);
            }
        });
    }
    class MyKeyListener extends  KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();
            if(keyCode == KeyEvent.VK_SPACE){
                System.out.println("space");
            }
        }
    }


}

KeyEvent.VK_SPACE 空格所代表的按键代码,在keyevent类中存储了所有的按键带代

2.2 JFrame

我们看一下JFrame的基础用法

package com.ch2;
import org.w3c.dom.Text;
import  java.awt.event.MouseAdapter;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;

public class Gui {
   public void init(){
       JFrame jframe = new JFrame("TEST");
       JLabel jlabel = new JLabel("lable");
       jframe.setBounds(100,100,500,500);
       jframe.setVisible(true);
       jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//还有其他设置,比如隐藏,此处的WindowConstants是用接口定义的只存储静态常量的抽象类
       Container container = jframe.getContentPane();
       container.add(jlabel);
       jlabel.setHorizontalAlignment(JLabel.RIGHT);//和关闭窗口的设置一样,可以设置标签的位置。
       container.setBackground(Color.blue);

   }

    public static void main(String[] args) {
        new Gui().init();
    }

}

在swing中,jframe只用来触发窗口事件,设置窗口位置大小等操作,不实际操作其内

容,这是和AWT最大的区别,我们如果想要给窗口添加内容,设置颜色,应该使用内容

窗口,用getContentPane来获取,在上述代码中,我们想要更改窗口的背景颜色,直

接更改jframe是无效的,必须更改container的color才可以。

2.3 弹窗(JDialog)

弹窗也是一个新的窗口

package com.ch2;

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;

public class MyDialog extends JFrame{
    public MyDialog() {
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBounds(100,100,500,500);
        Container container = getContentPane();
        container.setLayout(null);//绝对定位,根据坐标决定布局
        JButton button = new JButton("点击");
        button.setBounds(30,30,200,50);
        container.add(button);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new Dia();
            }
        });

    }
    public static void main(String[] args) {
        new MyDialog();
    }
    class Dia extends JDialog{
        public  Dia (){
            setVisible(true);
            setLayout(null);
            setBounds(100,100,400,400);

        }
    }
}

通过该方式实现弹窗,需要注意的是当我们new一个Dialog时,已经默认有了窗口宽鼻

功能,所以弹窗的窗口关闭功能我们就不需要自己去写了。

posted @ 2024-06-25 00:46  折翼的小鸟先生  阅读(3)  评论(0编辑  收藏  举报