一、第一个Frame窗口程序
setVisible
setSize
setBackground
setLocation
setResizable
package com.ctguyxr.gui.test1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/15 8:22 星期三
*/
public class MyFrame extends JFrame {
public static void main(String[] args) {
// title 就是窗口的标题文字
Frame frame = new Frame("第一个Java图形界面的窗口");
// setVisible 默认的窗口是加载在内存中,不可见的,设置为true就可见了
frame.setVisible(true);
// 设置窗口的默认大小
frame.setSize(400,400);
// 设置窗口的背景颜色
frame.setBackground(new Color(255,0,0));
// 设置窗口默认显示在屏幕上的位置
frame.setLocation(300,300);
// 设置窗口大小是否可以改变,默认为true
frame.setResizable(false);
}
}
二、panel面板
- Java GUI编程里面,除了
Frame
窗口以外,还有Panel
面板,面板有点类似于HTML
中的Div
标签 - 面板无法单独显现,只能放在
Frame
窗口中来显现 ```java package com.ctguyxr.gui.test1;
import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;
/**
- Created By Intellij IDEA *
- @author Xinrui Yu
@date 2021/12/15 8:42 星期三 */ public class PanelTest { public static void main(String[] args) {
Frame frame = new Frame("你好");
Panel panel = new Panel();
frame.setLayout(null);
frame.setBounds(100,100,500,500);
frame.setBackground(new Color(40,161,35));
panel.setBounds(50,50,400,400);
panel.setBackground(new Color(193,15,60));
frame.add(panel);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
} }
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21436600/1639529570871-9e2fc23f-d46d-4f95-867f-2eb55c3ce25a.png#clientId=ub02c8026-5dd5-4&from=paste&height=492&id=u08b93174&originHeight=492&originWidth=484&originalType=binary&ratio=1&size=12874&status=done&style=none&taskId=ud31f2209-a98d-4cae-a0b7-d4eef894475&width=484)
<a name="lFKhG"></a>
## 设置窗口关闭的监听事件
涉及到的方法是:`frame.addWindowListener()`<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/21436600/1639529653335-feb9a8a6-1b23-4fb4-b29b-204ccef210a7.png#clientId=ub02c8026-5dd5-4&from=paste&height=255&id=u3d0afb46&originHeight=255&originWidth=986&originalType=binary&ratio=1&size=232544&status=done&style=none&taskId=u14b99454-1400-4a7f-aaa2-4875149fae7&width=986)
需要传入窗体监听器对象,然而发现这个`WindowListener`实际上是接口<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/21436600/1639529700546-acca6548-8261-4b9d-af0a-36d66f512f9e.png#clientId=ub02c8026-5dd5-4&from=paste&height=197&id=u3c9319ca&originHeight=197&originWidth=844&originalType=binary&ratio=1&size=43765&status=done&style=none&taskId=u1c55410b-38f2-400e-9134-c8662a12ca6&width=844)
如果直接创建接口的匿名子类的匿名对象的话,需要重写接口中的所有方法<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/21436600/1639529799363-433ba26c-711d-411b-94af-f9229111b6ca.png#clientId=ub02c8026-5dd5-4&from=paste&height=455&id=ub3a2aa0a&originHeight=455&originWidth=498&originalType=binary&ratio=1&size=307036&status=done&style=none&taskId=u41fa650a-7e85-4734-9595-3acfbddc313&width=498)<br />但是我们只需要重写窗口关闭的方法,显然这种方法是不合理的<br />进一步查找发现,`WindowAdapter`类实现了`WindowListener`,并且所有方法提供了一个空实现,这其实就是设计模式中的缺省设计模式<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/21436600/1639530041458-b192c7bd-a29e-4024-a4dd-fc4a8385a8ff.png#clientId=ub02c8026-5dd5-4&from=paste&height=688&id=ub3e27efd&originHeight=688&originWidth=918&originalType=binary&ratio=1&size=579964&status=done&style=none&taskId=ud609bfaf-7723-460a-b482-0b1285628d3&width=918)
[设计模式 | 适配器模式及典型应用 - 掘金](https://juejin.cn/post/6844903682136342541)
> 缺省适配器模式(Default Adapter Pattern):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况,又称为单接口适配器模式。缺省适配器模式是适配器模式的一种变体,其应用也较为广泛。在JDK类库的事件处理包java.awt.event中广泛使用了缺省适配器模式,如WindowAdapter、KeyAdapter、MouseAdapter等。
现在只需要创建`WindowAdapter`类的对象并重写监听窗口关闭的事件就可以了
```java
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
三、布局管理器
1、流式布局 FlowLayout
主要是通过FloLayout
的常量属性来设置布局方式
LEFT
:0CENTER
:1RIGHT
:2
package com.ctguyxr.gui.test1;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/15 9:04 星期三
*/
public class FlowLayoutTest {
public static void main(String[] args) {
Frame frame = new Frame("hello");
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.setBounds(300,300,500,500);
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.setVisible(true);
}
}
2、边界布局 BorderLayout
package com.ctguyxr.gui.test1;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/15 9:11 星期三
*/
public class BorderLayoutTest {
public static void main(String[] args) {
Frame frame = new Frame("BorderLayoutTest");
Button button1 = new Button("EAST");
Button button2 = new Button("WEST");
Button button3 = new Button("SOUTH");
Button button4 = new Button("NORTH");
Button button5 = new Button("CENTER");
frame.add(button1,BorderLayout.EAST);
frame.add(button2,BorderLayout.WEST);
frame.add(button3,BorderLayout.SOUTH);
frame.add(button4,BorderLayout.NORTH);
frame.add(button5,BorderLayout.CENTER);
frame.setBounds(300,300,500,500);
frame.setVisible(true);
}
}
3、网格布局 GridLayout
有点类似于CSS
中的Grid
布局方式,将窗口分成一个一个的Grid
进行布局
GridLayout一共有三种构造函数
可以指定有多少行、多少列、行间距是多少和列间距是多少
参数列表
rows
行数cols
列数hgap
行间距vgap
列间距
package com.ctguyxr.gui.test1;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/15 9:19 星期三
*/
public class GridLayoutTest {
public static void main(String[] args) {
Frame frame = new Frame("grid");
// 将窗口分成3行2列进行布局
frame.setLayout(new GridLayout(3,2));
Button button1 = new Button("1");
Button button2 = new Button("2");
Button button3 = new Button("3");
Button button4 = new Button("4");
Button button5 = new Button("5");
Button button6 = new Button("6");
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
frame.setSize(500,500);
frame.setVisible(true);
}
}
四、按钮
Java中提供了Button类,来实现窗口程序中的按钮功能
常用的属性
label
按钮上显现的名字actionCommand
执行的操作名称actionListener
时间监听器
常用的两个构造器
空参构造器:按钮上不显示文字内容 有参构造器:指定按钮上显示出来的文字内容
按钮的事件监听器
一般按钮都是有特定功能的组件,比如关闭窗口,提交表单的等等
Java中进行操作首先就需要给按钮添加上事件的监听器
然后对应的进行处理
调用的方法是button.addActionListener
但是发现需要传入的参数是一个接口
且接口里面只有一个方法,
不难想到可以编写一个类(或者直接创建这个接口匿名实现类的匿名对象)然后去实现这个接口,最后把这个类的对象作为参数传入,但是我们可以用Java8的Lambda表达式更好的解决这个问题
button.addActionListener(e -> {
System.out.println("点击");
});
参数e
就是接口中actionPerformed
方法的参数,我们通过e
获取到被点击按钮上的一些信息
多个按钮共用一个事件监听器
五、输入框事件监听
文本框:
TextField textField = new TextField()
1、文本框事件监听
我们可以监听文本框的输入事件,从而获取到用户在文本框中输入了什么内容
这里直接采取Lambda表达式的写法e.getSource()
是EventObject
类中的方法
可以获取到触发事件的对象类
textField.addActionListener(e -> {
Object source = e.getSource();
if(source instanceof TextField){
TextField f = (TextField) source;
System.out.println(f.getText());
f.setText("");
}
});
当我们在文本框中输入了数据之后,按下回车
通过事件监听器拿到输入的数据,并打印到控制台之上
2、输入密码
有时候我们在表单中需要输入密码,这个时候我们对显示出来的文字进行使用*
代替textField.setEchoChar_(_'*'_)_;
对外显示的虽然是*
号,但是我们可以在程序中拿到真实输入的数据
六、画笔
1、使用画笔
主要使用到的方法是Window
类中的paint()
方法
通过重写paint()
方法,然后使用Graphics
类的对象进行绘画
package com.ctguyxr.gui.test5;
import com.ctguyxr.gui.util.CloseWindowFrame;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 13:46 星期四
*/
public class Paint extends Frame {
public Paint() {
setBounds(200,200,600,500);
setVisible(true);
CloseWindowFrame.closeWindowFrame(this);
}
@Override
public void paint(Graphics g) {
g.setColor(Color.RED);
g.drawOval(100,100,100,100);
g.fillOval(100,100,100,100);
g.setColor(Color.GREEN);
g.fillRect(200,200,100,100);
}
}
2、鼠标监听
使用适配器模式创建鼠标监听的对象,并重写里面的点击方法
private class MyMouseAdapter extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
Paint frame = (Paint) e.getSource();
list.add(new Point(e.getX(),e.getY()));
frame.repaint();
}
}
使用画笔绘画,实际是一次性的操作,如果我们想要在鼠标点击的位置再画一个图形,就需要调用repaint()
方法来重新绘画一次
package com.ctguyxr.gui.test5;
import com.ctguyxr.gui.util.CloseWindowFrame;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 13:46 星期四
*/
public class Painter extends Frame {
private ArrayList<Point> list;
public Painter() {
list = new ArrayList<>();
setBounds(200,200,600,500);
setVisible(true);
CloseWindowFrame.closeWindowFrame(this);
}
@Override
public void paint(Graphics g) {
MyMouseAdapter adapter = new MyMouseAdapter();
this.addMouseListener(adapter);
Iterator<Point> iterator = list.iterator();
while(iterator.hasNext()){
Point po = iterator.next();
g.setColor(Color.BLUE);
g.fillOval(po.x,po.y,10,10);
}
}
private class MyMouseAdapter extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
Painter frame = (Painter) e.getSource();
list.add(new Point(e.getX(),e.getY()));
frame.repaint();
}
}
}
七、键盘监听
Java窗体还提供了键盘监听事件来监听我们的键盘输入KeyListener
是接口,其同样采用的是适配器模式KeyAdapter
就是其适配器类
我们可以通过事件来获得键盘输入字符的code
,然后与内置的code
常量相比较,从而判断用户按下的是哪一个键
八、Swing
1、窗口和面板
Swing
包下的JFrame
是对Java
原有的Frame
窗口的补充,包装了一些常用的操作,添加了更多的组件
比如已经封装好了窗口的关闭事件frame.setDefaultCloseOperation_(_WindowConstants._EXIT_ON_CLOSE)_;
package com.ctguyxr.gui.test7;
import javax.swing.*;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 14:58 星期四
*/
public class MyJFrameTest {
public void init(){
JFrame frame = new JFrame("JFrame test");
frame.setVisible(true);
frame.setBounds(300,300,300,300);
JLabel label = new JLabel("这是一个文本标签");
label.setHorizontalAlignment(SwingConstants.CENTER);
frame.getContentPane().setBackground(Color.PINK);
frame.add(label);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new MyJFrameTest().init();
}
}
2、弹窗
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 15:21 星期四
*/
public class DialogTest {
public DialogTest() {
JFrame jFrame = new JFrame();
jFrame.setVisible(true);
jFrame.setBounds(300,300,300,300);
JButton button = new JButton("点我");
button.setSize(100,100);
button.addActionListener(e -> {
JDialog jDialog = new JDialog();
jDialog.setVisible(true);
jDialog.setBounds(100,100,300,300);
Container container = jDialog.getContentPane();
container.setLayout(null);
container.add(new JLabel("Hello,World"));
});
jFrame.getContentPane().add(button);
jFrame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new DialogTest();
}
}
3、Icon和ImageIcon
使用画笔画图标
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 15:40 星期四
*/
public class IconTest extends JFrame implements Icon {
private int width;
private int height;
public IconTest() throws HeadlessException {
}
public IconTest(int width, int height) throws HeadlessException {
this.width = width;
this.height = height;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.fillOval(x,y,width,height);
}
@Override
public int getIconWidth() {
return width;
}
@Override
public int getIconHeight() {
return height;
}
public void init(){
IconTest iconTest = new IconTest(15, 15);
JLabel label = new JLabel("测试", iconTest, SwingConstants.CENTER);
Container container = getContentPane();
container.add(label);
setVisible(true);
setBounds(300,300,300,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new IconTest().init();
}
}
直接使用图片当作图标
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 15:46 星期四
*/
public class ImageIconTest extends JFrame {
public ImageIconTest() throws HeadlessException {
URL resource = getClass().getResource("img.png");
assert resource != null;
ImageIcon imageIcon = new ImageIcon(resource);
JLabel label = new JLabel("ImageIcon", imageIcon, SwingConstants.CENTER);
Container container = getContentPane();
container.add(label);
setVisible(true);
setBounds(300,300,600,500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ImageIconTest();
}
}
4、面板 JPanel
可滚动面板JScrollPane
当页面内容超出窗口的大小的时候,就会出现水平或者垂直的滚动条
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 15:57 星期四
*/
public class JScrollTest extends JFrame {
public JScrollTest() throws HeadlessException {
Container container = this.getContentPane();
JTextArea textArea = new JTextArea(20, 50);
JScrollPane scrollPane = new JScrollPane(textArea);
container.add(scrollPane);
this.setVisible(true);
this.setBounds(300,300,200,200);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollTest();
}
}
5、图片按钮、单选框、复选框
5.1 图片按钮
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 16:04 星期四
*/
public class RadioButtonTest extends JFrame {
public RadioButtonTest() throws HeadlessException {
Container container = getContentPane();
URL resource = getClass().getResource("img.png");
assert resource != null;
ImageIcon imageIcon = new ImageIcon(resource);
JButton button = new JButton(imageIcon);
// 设置鼠标悬浮提示文字
button.setToolTipText("图片按钮");
container.add(button);
setBounds(100,100,600,600);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new RadioButtonTest();
}
}
5.2 单选框
一个使用了单选框的字段,应该只能选择多个单选框中的一个
这就需要我们用到组
的方法,将多个单选框分成一组
这一组中只能有一个单选框处于被选择状态
不可以同时选择多个
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 16:04 星期四
*/
public class RadioButtonTest extends JFrame {
public RadioButtonTest() throws HeadlessException {
Container container = getContentPane();
JRadioButton button1 = new JRadioButton("button1");
JRadioButton button2 = new JRadioButton("button2");
JRadioButton button3 = new JRadioButton("button3");
ButtonGroup group = new ButtonGroup();
group.add(button1);
group.add(button2);
group.add(button3);
container.add(button1,BorderLayout.NORTH);
container.add(button2,BorderLayout.CENTER);
container.add(button3,BorderLayout.SOUTH);
setVisible(true);
setBounds(100,100,500,200);
}
public static void main(String[] args) {
new RadioButtonTest();
}
}
5.3 复选框
多选框是可以重复选择的按钮
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 16:04 星期四
*/
public class RadioButtonTest extends JFrame {
public RadioButtonTest() throws HeadlessException {
Container container = getContentPane();
JCheckBox button1 = new JCheckBox("button1");
JCheckBox button2 = new JCheckBox("button2");
JCheckBox button3 = new JCheckBox("button3");
button1.setSize(200,100);
button2.setSize(200,100);
button3.setSize(200,100);
container.add(button1);
container.add(button2);
container.add(button3);
container.setLayout(new FlowLayout(FlowLayout.CENTER));
setVisible(true);
setBounds(100,100,500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new RadioButtonTest();
}
}
6、列表
6.1 下拉框
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
import java.util.List;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 16:20 星期四
*/
public class ListBoxTest extends JFrame {
public ListBoxTest() throws HeadlessException {
Container container = getContentPane();
JComboBox<String> comboBox = new JComboBox<>();
comboBox.addItem("火锅");
comboBox.addItem("烧烤");
comboBox.addItem("炸鸡");
container.add(comboBox);
setVisible(true);
setBounds(300,300,500,100);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ListBoxTest();
}
}
6.2 列表框
package com.ctguyxr.gui.test8;
import javax.swing.*;
import java.awt.*;
import java.util.List;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/16 16:20 星期四
*/
public class ListBoxTest extends JFrame {
public ListBoxTest() throws HeadlessException {
Container container = getContentPane();
String[] data = new String[]{"炸鸡","火锅","烧烤"};
JList<String> jList = new JList<>(data);
container.add(jList);
setVisible(true);
setBounds(300,300,500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ListBoxTest();
}
}