JavaGUI
参考视频:BV1DJ411B75F
关键类:Swing、AWT
技术已不常用,不过可以为了解MVC架构打基础
文章目录
1.AWT
1.1 AWT介绍
java.awt.* ,内部包含很多GUI相关的类和接口。
元素:窗口、按钮、文本框
1.2 组件和容器
注:大体学习思路是:知道有相关的类–>创建这个类的对象–>各种类方法的使用和细节可以看源码(IDEA中通过ctrl+鼠标点击相关类可以跳到类的源码)
1.2.1 Frame
/**
* 创建一个Frame窗口
*/
import java.awt.*;
public class TestFrame {
public static void main(String[] args) {
//Frame创建窗口对象,具体细节看源码
Frame frame=new Frame("My first java frame");
//设置窗口是否可见
frame.setVisible(true);
//设置窗口大小
frame.setSize(400,300);
//设置背景颜色 Color类
frame.setBackground(new Color(111,56,220));
//窗口弹出的初始位置
frame.setLocation(200,200);
}
}
下面实现一次弹出多个窗口,可以将窗口的特点进行封装,写成自己的窗口类
import java.awt.*;
public class TestFrame2 {
public static void main(String[] args) {
//弹出多个窗口
MyFrame myFrame1=new MyFrame(100,100,200,200, Color.cyan);
MyFrame myFrame2=new MyFrame(100,300,200,200, Color.pink);
MyFrame myFrame3=new MyFrame(100,500,200,200, Color.red);
MyFrame myFrame4=new MyFrame(100,700,200,200, Color.yellow);
}
}
class MyFrame extends Frame{
static int id=0; //统计创建的窗口数
public MyFrame(int x,int y,int w,int h,Color color){
super("MyFrame"+(++id));
setBackground(color);
setBounds(x,y,w,h);
setVisible(true);
}
}
1.2.2 Panel(面板)
Panel不能单独存在,可以堪称是一个空间或容器
//Panel源码定义部分
public class Panel extends Container implements Accessible {
private static final String base = "panel";
private static int nameCounter = 0;
//......
}
Panel继承了Container
public class Container extends Component {
private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Container");
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Container");
private static final Component[] EMPTY_ARRAY = new Component[0];
//......
}
Container继承了Component。因此Panel对象作为元素放入Frame对象
测试样例
import java.lang.*;
import java.util.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class TestPanel {
public static void main(String[] args) {
Frame frame=new Frame("包含Panel的窗口");
Panel panel=new Panel();
//设置布局
frame.setLayout(null);
//坐标
frame.setBounds(300,300,500,500);
frame.setBackground(Color.cyan);
//设置panel坐标,相对于frame。frame的左上角为panel的(0,0)坐标
panel.setBounds(50,50,260,260);
panel.setBackground(Color.magenta);
//将panel加入frame中
frame.add(panel);
frame.setVisible(true);
//监听事件,监听窗口关闭事件
//下面采用适配器模式,这种模式下可以在众多待重载的方法中,只重载部分需要的方法
frame.addWindowListener(new WindowAdapter() {
//窗口右上角关闭事件
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
}
1.3 布局管理器
基本布局
- 流式布局(从左往右)
import java.io.BufferedReader;
import java.lang.*;
import java.util.*;
import java.awt.*;
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame=new Frame();
//组件+按钮
Button button1=new Button("button1");
Button button2=new Button("button2");
Button button3=new Button("button3");
//设置为流式布局
//frame.setLayout(new FlowLayout());
//frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
frame.setSize(300,300);
//添加按钮
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.setVisible(true);
}
}
- 东西南北中
import java.io.BufferedReader;
import java.lang.*;
import java.util.*;
import java.awt.*;
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame=new Frame();
//组件+按钮
Button east=new Button("East");
Button west=new Button("West");
Button south=new Button("South");
Button north=new Button("North");
Button center=new Button("Center");
frame.add(east,BorderLayout.EAST);
frame.add(west,BorderLayout.WEST);
frame.add(south,BorderLayout.SOUTH);
frame.add(north,BorderLayout.NORTH);
frame.add(center,BorderLayout.CENTER);
frame.setSize(500,500);
frame.setVisible(true);
}
}
- 表格布局
import java.io.BufferedReader;
import java.lang.*;
import java.util.*;
import java.awt.*;
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame=new Frame();
Button bin1=new Button("bin1");
Button bin2=new Button("bin2");
Button bin3=new Button("bin3");
Button bin4=new Button("bin4");
Button bin5=new Button("bin5");
Button bin6=new Button("bin6");
//设置表格布局规格
frame.setLayout(new GridLayout(3,2));
frame.add(bin1);
frame.add(bin2);
frame.add(bin3);
frame.add(bin4);
frame.add(bin5);
frame.add(bin6);
frame.setSize(500,500);
frame.setVisible(true);
}
}
嵌套布局
实现下面布局
import java.lang.*;
import java.util.*;
import java.awt.*;
import java.util.concurrent.Flow;
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame=new Frame();
//上半部分
Panel panelup=new Panel(new BorderLayout());
panelup.add(new Button("West-1"),BorderLayout.WEST);
panelup.add(new Button("East-1"),BorderLayout.EAST);
Panel panelup1=new Panel(new GridLayout(2,1));
panelup1.add(new Button("center1-bin-1"));
panelup1.add(new Button("center1-bin-2"));
panelup.add(panelup1,BorderLayout.CENTER);
//下半部分
Panel paneldown=new Panel(new BorderLayout());
paneldown.add(new Button("West-2"),BorderLayout.WEST);
paneldown.add(new Button("East-3"),BorderLayout.EAST);
Panel paneldown1=new Panel(new GridLayout(2,2));
for(int i=1;i<=4;i++){
paneldown1.add(new Button("center2-bin-"+i));
}
paneldown.add(paneldown1,BorderLayout.CENTER);
//设置表格布局规格
frame.setSize(500,500);
panelup.setSize(250,250);
panelup.setLocation(0,0);
paneldown.setSize(250,250);
paneldown.setLocation(250,0);
frame.setLayout(new GridLayout(2,1));
frame.add(panelup);
frame.add(paneldown);
frame.setVisible(true);
}
}
1.4 事件监听
目的:某个事件发生时可以触发什么操作
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 TestActionEvent {
public static void main(String[] args) {
//点击按钮触发事件
Frame frame=new Frame();
Button button=new Button("button");
frame.setVisible(true);
//自定义监听事件类
MyActionListener myActionListener=new MyActionListener();
button.addActionListener(myActionListener); //添加监听器
frame.add(button,BorderLayout.CENTER);
frame.pack(); //自动调整组件布局
windowClose(frame);
}
//关闭窗体事件
private static 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){
System.out.println("xxxxx");
}
}
/**
* 两个按钮共用一个监听器
*/
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 TestActionTwo {
public static void main(String[] args) {
Frame frame=new Frame();
Button bin1=new Button("Start");
Button bin2=new Button("End");
//修改bin2的内部信息。默认值为按钮名
bin2.setActionCommand("button2-stop");
MyMonitor myMonitor=new MyMonitor();
bin1.addActionListener(myMonitor);
bin2.addActionListener(myMonitor);
frame.add(bin1,BorderLayout.NORTH);
frame.add(bin2,BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
class MyMonitor implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
//e.getActionCommand() 可以获取按钮的信息
System.out.println(e.getActionCommand());
if(e.getActionCommand().equals("Start")){
System.out.println("1111111111111111");
}
else if(e.getActionCommand().equals("End")){
System.out.println("2222222222222222");
}
}
}
1.5 TextField(输入框)
不可换行的文本框
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TextTest {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends Frame{
public MyFrame(){
TextField textField=new TextField();
add(textField);
setVisible(true);
pack();
//监听文本框输入的内容
MyActionListener myActionListener=new MyActionListener();
//写入内容后按回车触发事件
textField.addActionListener(myActionListener);
//设置替换编码
textField.setEchoChar('*');
}
}
class MyActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
TextField field=(TextField) e.getSource(); //e.getSource()返回Object类型
System.out.println(field.getText());
//field.setText("");
}
}
案例:简易计算器
涉及组合、内部类的内容
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 TestCal {
public static void main(String[] args) {
new Calculator();
}
}
//计算器类
class Calculator extends Frame {
public Calculator(){
//3个文本框
TextField num1 = new TextField(10); //10为限制字符数
TextField num2 = new TextField(10);
TextField num3 = new TextField(20);
//1个按钮
Button button=new Button("=");
button.addActionListener(new MyCalculatorListener(num1,num2,num3));
//1个标签
Label label=new Label("+");
//布局
setLayout(new FlowLayout());
add(num1);add(label);add(num2);add(button);add(num3);
pack();
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
}
//监听器类
class MyCalculatorListener implements ActionListener{
private TextField num1,num2,num3;
public MyCalculatorListener(TextField num1, TextField num2, TextField num3) {
this.num1 = num1;
this.num2 = num2;
this.num3 = num3;
}
@Override
public void actionPerformed(ActionEvent e){
//获取两个加数
int n1=Integer.parseInt(num1.getText());
int n2=Integer.parseInt(num2.getText());
//计算结果放到第三个文本框
num3.setText(""+(n1+n2));
//清除前两个框
num1.setText("");
num2.setText("");
}
}
上述代码以面向过程为主,下面通过组合形式优化成面向对象的代码
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 TestCal {
public static void main(String[] args) {
new Calculator();
}
}
//计算器类
class Calculator extends Frame {
TextField num1,num2,num3;
public Calculator(){
//3个文本框
num1 = new TextField(10); //10为限制字符数
num2 = new TextField(10);
num3 = new TextField(20);
//1个按钮
Button button=new Button("=");
button.addActionListener(new MyCalculatorListener(this));
//1个标签
Label label=new Label("+");
//布局
setLayout(new FlowLayout());
add(num1);add(label);add(num2);add(button);add(num3);
pack();
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
}
//监听器类
class MyCalculatorListener implements ActionListener{
//获取对象,在一个类中组合另一个类
Calculator calculator=null;
public MyCalculatorListener(Calculator calculator) {
this.calculator = calculator;
}
@Override
public void actionPerformed(ActionEvent e){
//获取两个加数
int n1=Integer.parseInt(calculator.num1.getText());
int n2=Integer.parseInt(calculator.num2.getText());
//计算结果放到第三个文本框
calculator.num3.setText(""+(n1+n2));
//清除前两个框
calculator.num1.setText("");
calculator.num2.setText("");
}
}
进一步,还可以使用内部类方法将监听器类放到计算器类中,从而更好地封装类
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 TestCal {
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算器类
class Calculator extends Frame {
TextField num1,num2,num3;
public void loadFrame(){
//3个文本框
num1 = new TextField(10); //10为限制字符数
num2 = new TextField(10);
num3 = new TextField(20);
//1个按钮
Button button=new Button("=");
button.addActionListener(new MyCalculatorListener());
//1个标签
Label label=new Label("+");
//布局
setLayout(new FlowLayout());
add(num1);add(label);add(num2);add(button);add(num3);
pack();
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
//监听器内部类
public class MyCalculatorListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
//获取两个加数
int n1=Integer.parseInt(num1.getText());
int n2=Integer.parseInt(num2.getText());
//计算结果放到第三个文本框
num3.setText(""+(n1+n2));
//清除前两个框
num1.setText("");
num2.setText("");
}
}
}
1.6 Paint(画笔)
import java.awt.*;
public class TestPaint {
public static void main(String[] args) {
new MyPaint().loadFrame();
}
}
class MyPaint extends Frame{
public void loadFrame(){
setBounds(200,200,600,500);
setVisible(true);
}
//画笔
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.cyan);
g.fillOval(100,100,100,100); //实心圆
g.setColor(Color.magenta);
g.fillRect(150,200,200,200);
}
}
1.7 常用监听
1.7.1 鼠标监听
/**
* 简易画板
*/
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;
public class TestMouseListener {
public static void main(String[] args) {
new MyFrame("画图");
}
}
class MyFrame extends Frame{
//画笔。需要监听鼠标当前的位置,还需要一个存储所画点的集合
ArrayList points;
public MyFrame(String title) {
super(title);
setBounds(200,200,400,300);
setVisible(true);
//存储鼠标点击的位置
points=new ArrayList();
//鼠标监听器
addMouseListener(new MyMouseListener());
}
@Override
public void paint(Graphics g) {
//监听鼠标的事件
Iterator iterator=points.iterator();
while(iterator.hasNext()){
Point point=(Point)iterator.next();
g.setColor(Color.cyan);
g.fillOval(point.x,point.y,10,10);
}
}
public void addPoint(Point point){
points.add(point);
}
//适配器模式
private class MyMouseListener extends MouseAdapter{
//鼠标事件:按下、弹起、按住不放
@Override
public void mousePressed(MouseEvent e) {
MyFrame myFrame=(MyFrame)e.getSource();
//鼠标的位置
addPoint(new Point(e.getX(),e.getY()));
//每次点击鼠标都需要重新调用paint函数
myFrame.repaint();
}
}
}
1.7.2 窗口监听
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestWindow {
public static void main(String[] args) {
new WindowFrame();
}
}
class WindowFrame extends Frame{
public WindowFrame(){
setBackground(Color.cyan);
setBounds(200,200,200,200);
setVisible(true);
this.addWindowListener(new WindowAdapter() {
//匿名内部类
@Override
public void windowOpened(WindowEvent e) {
System.out.println("窗口打开");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口正在关闭");
System.exit(0);
}
});
}
}
1.7.3 键盘监听
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class TestKeyListener {
public static void main(String[] args) {
new KeyFrame();
}
}
class KeyFrame extends Frame {
public KeyFrame(){
setBounds(200,200,200,200);
setVisible(true);
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();
if(keyCode==KeyEvent.VK_UP){
System.out.println("👆");
}
else if(keyCode==KeyEvent.VK_LEFT){
System.out.println("👈");
}
else if(keyCode==KeyEvent.VK_RIGHT){
System.out.println("👉");
}
else if(keyCode==KeyEvent.VK_DOWN){
System.out.println("👇");
}
}
});
}
}
2.Swing
功能比AWT更强。
大体用法相近
2.1 窗口、面板
import javax.swing.*;
import java.awt.*;
public class JFrameDemo {
public static void main(String[] args) {
new MyJframe().init();
}
}
class MyJframe extends JFrame{
public void init(){
setBounds(200,200,200,200);
setVisible(true);
JLabel label=new JLabel("A JLabel");
add(label);
//将label设为居中
label.setHorizontalAlignment(SwingConstants.CENTER);
//获取一个容器
Container container=this.getContentPane();
container.setBackground(Color.cyan);
}
}
2.2 弹窗
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class DialogDemo extends JFrame {
public DialogDemo(){
setVisible(true);
setSize(700,500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//JFrame 容器
Container container=this.getContentPane();
//绝对布局
container.setLayout(null);
//按钮
JButton button=new JButton("点击弹出一个对话框");
button.setBounds(30,30,200,50);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//按下按钮显示弹窗
new MyDialogDemo();
}
});
container.add(button);
}
public static void main(String[] args) {
new DialogDemo();
}
}
//弹窗类
class MyDialogDemo extends JDialog{
public MyDialogDemo() {
setVisible(true);
setBounds(100,100,500,500);
//这句话的功能在JDialog中已实现,不用再添加
//setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container container=this.getContentPane();
container.setLayout(null);
container.add(new Label("弹窗文本"));
}
}
2.3 标签(Icon)
JLabel
图标Icon
import javax.swing.*;
import java.awt.*;
public class IconDemo extends JFrame implements Icon {
private int width;
private int height;
public IconDemo(){}//无参构造
public IconDemo(int width,int height){
this.width=width;
this.height=height;
}
public void init(){
IconDemo iconDemo=new IconDemo(13,15);
JLabel label=new JLabel("icontest",iconDemo,SwingConstants.CENTER);
Container container=this.getContentPane();
container.add(label);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new IconDemo().init();
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.drawImage(new ImageIcon("C:\\Users\\96955\\Desktop\\tempblog\\chigua.png").getImage(),10,10,new JPanel());
}
@Override
public int getIconWidth() {
return this.width;
}
@Override
public int getIconHeight() {
return this.height;
}
}
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class ImageIconDemo extends JFrame{
public ImageIconDemo(){
//获取图片地址
JLabel label=new JLabel("ImageIcon");
URL url=ImageIconDemo.class.getResource("chigua.png");
ImageIcon imageIcon=new ImageIcon(url);
label.setIcon(imageIcon);
label.setHorizontalAlignment(SwingConstants.CENTER);
Container container=new Container();
container.add(label);
setBounds(100,100,100,100);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ImageIconDemo();
}
}
2.4 面板
JPanel
import javax.swing.*;
import java.awt.*;
public class JPanelDemo extends JFrame {
public JPanelDemo(){
Container container=this.getContentPane();
container.setLayout(new GridLayout(2,1,10,10));
JPanel panel1=new JPanel(new GridLayout(1,3));
JPanel panel2=new JPanel(new GridLayout(1,2));
JPanel panel3=new JPanel(new GridLayout(2,1));
JPanel panel4=new JPanel(new GridLayout(3,2));
panel1.add(new JButton("1"));
panel1.add(new JButton("1"));
panel1.add(new JButton("1"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel3.add(new JButton("3"));
panel3.add(new JButton("3"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
container.add(panel1);container.add(panel2);
container.add(panel3);container.add(panel4);
setVisible(true);
setSize(500,500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JPanelDemo();
}
}
注:JButton可以通过setIcon方法设置按钮图标
JScrollPanel
import javax.swing.*;
import java.awt.*;
public class JScrollDemo extends JFrame {
public JScrollDemo(){
Container container=this.getContentPane();
//文本域
JTextArea jTextArea=new JTextArea(20,50);
jTextArea.setText("测试测试测试测试测试测试测试测试");
//Scroll面板
JScrollPane jScrollPane=new JScrollPane(jTextArea);
container.add(jScrollPane);
setVisible(true);
setBounds(100,100,300,350);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollDemo();
}
}
3.5 按钮
- 单选按钮
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class JButtonDemo extends JFrame {
public JButtonDemo(){
Container container=this.getContentPane();
//将一个图片变为图标
URL url=JButtonDemo.class.getResource("chigua.png");
//单选框
JRadioButton radioButton1=new JRadioButton("单选1");
JRadioButton radioButton2=new JRadioButton("单选2");
JRadioButton radioButton3=new JRadioButton("单选3");
//单选只能选一个,因此可以对其进行分组
ButtonGroup buttonGroup=new ButtonGroup();
buttonGroup.add(radioButton1);
buttonGroup.add(radioButton2);
buttonGroup.add(radioButton3);
container.add(radioButton1,BorderLayout.CENTER);
container.add(radioButton2,BorderLayout.NORTH);
container.add(radioButton3,BorderLayout.SOUTH);
setVisible(true);
setSize(500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo();
}
}
- 多选按钮
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class JButtonDemo extends JFrame {
public JButtonDemo(){
Container container=this.getContentPane();
//将一个图片变为图标
URL url=JButtonDemo.class.getResource("chigua.png");
//多选框
JCheckBox checkBox1=new JCheckBox("多选1");
JCheckBox checkBox2=new JCheckBox("多选2");
JCheckBox checkBox3=new JCheckBox("多选3");
container.add(checkBox1,BorderLayout.CENTER);
container.add(checkBox2,BorderLayout.NORTH);
container.add(checkBox3,BorderLayout.SOUTH);
setVisible(true);
setSize(500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo();
}
}
3.6 列表
- 下拉框
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class TestComboboxDemo extends JFrame{
public TestComboboxDemo(){
Container container=this.getContentPane();
JComboBox subject=new JComboBox();
subject.addItem("高等数学");
subject.addItem("线性代数");
subject.addItem("数据库");
subject.addItem("数据结构");
subject.addItem("计算机网络");
container.add(subject);
setVisible(true);
setSize(500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestComboboxDemo();
}
}
- 列表框
import javax.swing.*;
import java.awt.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Vector;
public class TestComboboxDemo extends JFrame{
public TestComboboxDemo(){
Container container=this.getContentPane();
//生成列表内容
Vector contents=new Vector();
contents.add("操作系统");
contents.add("数字电子技术");
//列表中添加内容
JList jList=new JList(contents);
//可以实现动态添加内容
contents.add("高等数学");
contents.add("线性代数");
contents.add("计算机网络");
container.add(jList);
setVisible(true);
setSize(500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestComboboxDemo();
}
}
3.7 文本框
- 文本框(单行)
import javax.swing.*;
import java.awt.*;
public class TestTextDemo extends JFrame {
public TestTextDemo(){
Container container=this.getContentPane();
JTextField textField1=new JTextField("hello");
JTextField textField2=new JTextField("world",20);
container.add(textField1,BorderLayout.NORTH);
container.add(textField2,BorderLayout.SOUTH);
setVisible(true);
setSize(500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo();
}
}
- 密码框
import javax.swing.*;
import java.awt.*;
public class TestTextDemo extends JFrame {
public TestTextDemo(){
Container container=this.getContentPane();
JPasswordField jPasswordField=new JPasswordField();
jPasswordField.setEchoChar('*');
container.add(jPasswordField);
setVisible(true);
setSize(500,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo();
}
}
- 文本域
JTextArea
2.4的JScrollPanel测试中已用过,可以回看。
实践:贪吃蛇
定时器:Timer,用于划分游戏的帧数
- 定义数据结构
- 添加素材
- 添加监听事件
package Snake;
import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
//游戏的主启动类
public class StartGame {
public static void main(String[] args) {
JFrame frame=new JFrame();
frame.setResizable(false); //锁定窗口大小
frame.setBounds(10,10,900,720);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//游戏的主要内容写在面板类中
frame.add(new GamePanel());
frame.setVisible(true);
}
}
package Snake;
import javax.swing.*;
import java.net.URL;
//数据中心类(图片素材相关数据)
public class Data {
public static URL headerURL=Data.class.getResource("static/chigua.png");
public static URL bodyURL=Data.class.getResource("static/body.png");
public static URL downURL=Data.class.getResource("static/down.png");
public static URL foodURL=Data.class.getResource("static/food.png");
public static URL leftURL=Data.class.getResource("static/left.png");
public static URL rightURL=Data.class.getResource("static/right.png");
public static URL upURL=Data.class.getResource("static/up.png");
public static ImageIcon header=new ImageIcon(headerURL);
public static ImageIcon body=new ImageIcon(bodyURL);
public static ImageIcon down=new ImageIcon(downURL);
public static ImageIcon food=new ImageIcon(foodURL);
public static ImageIcon left=new ImageIcon(leftURL);
public static ImageIcon right=new ImageIcon(rightURL);
public static ImageIcon up=new ImageIcon(upURL);
}
package Snake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
//游戏面板
public class GamePanel extends JPanel implements KeyListener, ActionListener {
//设计🐍的数据结构
int length; //🐍的长度
int[] snakeX=new int[600]; //🐍的x坐标 25*25
int[] snakeY=new int[500]; //🐍的y坐标 25*25
String fx; //初始方向向右
//食物的坐标
int foodX,foodY;
Random random=new Random();
//游戏的状态:开始、停止
boolean isStart=false;
boolean isFail=false; //游戏失败状态
int score; //游戏得分
//定时器
Timer timer=new Timer(100,this); //100ms刷新一次
//构造器
public GamePanel() {
init();
//获取焦点和键盘事件
this.setFocusable(true); //获取焦点事件
//this.addKeyListener(this); //获取键盘监听事件
this.addKeyListener(this);
timer.start();
}
//初始化方法
public void init(){
length=3;
snakeX[0]=100;snakeY[0]=100; //头的坐标
snakeX[1]=75;snakeY[1]=100; //第一节身体的坐标
snakeX[2]=50;snakeY[2]=100; //第二节身体的坐标
fx="R";
//事务位置随机分布
foodX=25+25*random.nextInt(24);
foodY=75+25*random.nextInt(24);
score=0;
}
//绘制面板
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); //清屏
//绘制静态面板
this.setBackground(Color.BLACK);
Data.header.paintIcon(this,g,25,11); //头部栏
g.fillRect(25,75,850,600); //默认游戏界面
//画积分
g.setColor(Color.WHITE);
g.setFont(new Font("微软雅黑",Font.BOLD,18));
g.drawString("长度"+length,750,35);
g.drawString("分数"+score,750,50);
//根据方向添加蛇头
switch (fx) {
case "R" -> Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
case "L" -> Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
case "U" -> Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
case "D" -> Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
}
for(int i=1;i<length;i++){
//第i节身体
Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
}
Data.food.paintIcon(this,g,foodX,foodY);
//游戏状态判断
if(!isStart){
g.setColor(Color.WHITE);
g.setFont(new Font("微软雅黑",Font.BOLD,40));
g.drawString("点击空格开始游戏",300,300);
}
if(isFail){
g.setColor(Color.RED);
g.setFont(new Font("微软雅黑",Font.BOLD,40));
g.drawString("游戏失败,按下空格重新开始",300,300);
}
}
//键盘监听事件
@Override
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode(); // 获取键盘内容
if(keyCode==KeyEvent.VK_SPACE){
if(isFail){
isFail=false;
init();
}
else {
isStart = !isStart;
}
repaint();
}
//🐍移动
if(keyCode==KeyEvent.VK_UP){
fx="U";
}
else if(keyCode==KeyEvent.VK_DOWN){
fx="D";
}
else if(keyCode==KeyEvent.VK_LEFT){
fx="L";
}
else if(keyCode==KeyEvent.VK_RIGHT){
fx="R";
}
}
//事件监听 需要超过固定事件来刷新,1秒10次
@Override
public void actionPerformed(ActionEvent e){
if(isStart && !isFail){ //当前游戏是开始状态。小蛇运动
//吃食物
if(snakeX[0]==foodX && snakeY[0]==foodY){
length++;
score+=10;
//再生成一个食物
foodX=25+25*random.nextInt(24);
foodY=75+25*random.nextInt(24);
}
//身体移动
for(int i=length-1;i>0;i--){
snakeX[i]=snakeX[i-1];
snakeY[i]=snakeY[i-1];
}
//走向
if(fx.equals("R")){
snakeX[0]=snakeX[0]+25;
if(snakeX[0]>850) snakeX[0]=25;
}
else if(fx.equals("L")){
snakeX[0]=snakeX[0]-25;
if(snakeX[0]<25) snakeX[0]=850;
}
else if(fx.equals("U")){
snakeY[0]=snakeY[0]-25;
if(snakeY[0]<25) snakeY[0]=650;
}
else if(fx.equals("D")){
snakeY[0]=snakeY[0]+25;
if(snakeY[0]>650) snakeY[0]=75;
}
//失败判断
for(int i=1;i<length;i++){
if(snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
isFail=true;
}
}
repaint();
}
timer.start(); //定时器开启
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {}
}