【多媒体】富客户端应用程序GUI框架 JavaFX 2.0 简介

news2024/12/27 11:41:20

JavaFX 最初是由 Oracle 推出的一个用于开发富客户端应用程序的框架,它提供了丰富的用户界面控件、布局容器、3D图形绘制、媒体播放和动画等功能,旨在取代较旧的 Swing 框架。JavaFX 于 2007 年推出,2011 年 10 月发布了2.0 版本。JavaFX 2.0 的一个优点是适用于跨平台,而且可以完全用 Java 语言编写代码。

2014年发布的JDK 8.0就包含了JavaFx 2.0 版本。然而,随着时间的发展和技术的变迁,JavaFx 2.0并未达到预期目标,而且在与其他的技术标准竟争中处于下风。从 JDK 11 开始,Oracle 决定不再将 JavaFX 包含在 JDK 中,如有需要JavaFX必须单独下载和使用。
尽管如此,JavaFX 仍然是一个强大的开发工具,开发者可用它来设计、编写、测试、调试和部署富客户端程序,支持跨平台使用。

我们先来看一个简单的“欢迎使用JavaFX”例程,其源代码如下:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class 欢迎使用JavaFX extends Application {

    @Override public void start(Stage stage) {
        Text text = new Text(10, 40, "欢迎使用 JavaFX !");
        text.setFont(new Font(40));
        Scene scene = new Scene(new Group(text), 400, 100);

        stage.setTitle("欢迎使用JavaFX");
        stage.setScene(scene);
        stage.sizeToScene();
        stage.show();
    }

    public static void main(String[] args) {
    	Application.launch(args);
    }
}

程序演示结果:
在这里插入图片描述

下面再来看一个“3D图像演示”例程,其源代码如下:

/***3D图像演示例程***/
import javafx.application.Application;  
import javafx.scene.*;  
import javafx.scene.paint.Color;  
import javafx.scene.paint.PhongMaterial;  
import javafx.scene.shape.*;  
import javafx.stage.Stage; 
public class Shapes3DViewer extends Application {
    @Override public void start(Stage stage) {  
        PhongMaterial material = new PhongMaterial();  
        material.setDiffuseColor(Color.LIGHTGRAY);  
        material.setSpecularColor(Color.rgb(30, 30, 30));  
   
        Shape3D[] meshView = new Shape3D[] {  
            new Box(200, 200, 200),  
            new Sphere(100),  
            new Cylinder(100, 200),  
        };  
   
        for (int i=0; i!=3; ++i) {  
            meshView[i].setMaterial(material);  
            meshView[i].setTranslateX((i + 1) * 220);  
            meshView[i].setTranslateY(200);  
            meshView[i].setTranslateZ(20);  
            meshView[i].setDrawMode(DrawMode.FILL);  
            meshView[i].setCullFace(CullFace.BACK);  
        };  
   
        PointLight pointLight = new PointLight(Color.ANTIQUEWHITE);  
        pointLight.setTranslateX(800);  
        pointLight.setTranslateY(-100);  
        pointLight.setTranslateZ(-1000);  
   
        Group root = new Group(meshView);  
        root.getChildren().add(pointLight);  
           
        Scene scene = new Scene(root, 800, 400, true);  
        scene.setFill(Color.rgb(10, 10, 40));  
        scene.setCamera(new PerspectiveCamera(false)); 
        stage.setTitle("3D图像演示");
        stage.setScene(scene);  
        stage.show();  
    }  
   
    public static void main(String[] args) {  
    	Application.launch(args);  
    }  

}

3D图像演示效果图:
在这里插入图片描述

JavaFX提供了丰富的控件来构造所需要的程序界面。JavaFX提供了一种容器控件,即面板Pane来简化解决这个问题,不同类型的面板采用不同的布局策略。我们可以根据实际的需要来选择不同的面板,从而构造出我们所需要的界面。下面就介绍几种常用的面板。

(一) FlowPane面板
它采用的布局管理器实际上就是AWT的FlowLayout:按照控件的添加次序按个摆放,按照从上到下、从左到右的次序摆放。当面板的大小发生变化后,舞台的大小也自动跟着变化,场景的大小也自动跟着调整,并且会重新计算各个控件的位置,重新摆放各个控件的位置。

FlowPane测试例程:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class PaneTest extends Application {
	public static Pane FlowPaneTest() {
		FlowPane pane = new FlowPane();
		 
		pane.setPadding(new Insets(11, 12, 13, 14));
		 
		//设置控件之间的垂直间隔距离
		pane.setHgap(5);
		 
		//设置控件之间的水平间隔距离
		pane.setVgap(5);
		
		Label lbName = new Label("姓名:");
		 
		TextField tfName = new TextField();
		 
		Label lbPassword = new Label("密码:");
		 
		TextField tfPassword = new TextField();   
		 
		Button okbtn = new Button("递交");
		
		pane.getChildren().addAll(lbName,tfName,lbPassword,tfPassword,okbtn);
		
		return pane;
	}
	
	
    @Override
    public void start(Stage stage) {
    	Pane pane = FlowPaneTest();

        // 创建场景
        Scene scene = new Scene(pane, 600, 150);

        // 设置舞台
        stage.setScene(scene);
        stage.setTitle("JavaFX面板演示");
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

例程演示结果图一:
例程结果图01
当程序主窗口宽度变小时,例程演示结果图二:
在这里插入图片描述

(二) GridPane面板
它采用的布局管理器实际上就是AWT中的GridLayout:将整个面板划分为若干个格子,每个格子的大小是一样的,每个格子中可以放置一个控件,类似于网格的形式。
GridPane测试例程:


import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class PaneTest extends Application {
	public static Pane FlowPaneTest() {
		FlowPane pane = new FlowPane();
		 
		pane.setPadding(new Insets(11, 12, 13, 14));
		 
		//设置控件之间的垂直间隔距离
		pane.setHgap(5);
		 
		//设置控件之间的水平间隔距离
		pane.setVgap(5);
		
		Label lbName = new Label("姓名:");
		 
		TextField tfName = new TextField();
		 
		Label lbPassword = new Label("密码:");
		 
		TextField tfPassword = new TextField();   
		 
		Button okbtn = new Button("递交");
		
		pane.getChildren().addAll(lbName,tfName,lbPassword,tfPassword,okbtn);
		
		return pane;
	}
	
	public Pane GridPaneTest() {
	    GridPane pane = new GridPane();
	    
	    pane.setAlignment(Pos.CENTER);
	 
	    pane.setPadding(new Insets(11.5, 12.5, 13.5, 14.5));
	 
	    pane.setHgap(5.5);
	 
	    pane.setVgap(5.5);
	    
	    pane.add(new Button("按钮A"), 0, 0);
	    
	    pane.add(new Button("按钮B"), 1, 0);
	 
	    pane.add(new Button("按钮C"), 0, 1);
	 
	    pane.add(new Button("按钮D"), 1, 1);
	 
	    pane.add(new Button("按钮E"), 0, 2);
	 
	    pane.add(new Button("按钮F"), 1, 2);
	    
	    return pane;
	}
	
	public void BorderPaneTest() {
		
	}
	
	public void HBoxTest() {
		
	}
	
	public void VBoxTest() {
		
	}
	
    @Override
    public void start(Stage stage) {
    	//Pane pane = FlowPaneTest();
    	Pane pane = GridPaneTest();

        // 创建场景
        Scene scene = new Scene(pane, 320, 150);

        // 设置舞台
        stage.setScene(scene);
        stage.setTitle("JavaFX面板演示");
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

测试演示结果页面:
在这里插入图片描述

(三) BorderPane面板
它采用的布局管理器实际上就是AWT中的BorderLayout:将整个面板划分五个区域,分别是上、下、左、右、中,每个区域可以放置一个控件。
在此我们提供一个综合性的演示例程,它还组合使用了后续将要介绍的“HBox面板”和“VBox面板”,请看源代码:

/***BorderPane演示例程***/
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.Separator;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class BorderPaneExample extends Application {
    private BorderPane root;
    
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        root = new BorderPane();        
        root.setTop(getMenu());
        root.setRight(getRightHBox());
        root.setBottom(getFooter());
        root.setLeft(getLeftHBox());
        root.setCenter(getCenterPane());
        
        Scene scene = new Scene(root, 900, 500);        
        primaryStage.setTitle("BorderPane演示");
        primaryStage.setScene(scene);
        primaryStage.show();    
    }
    
    private MenuBar getMenu()
    {
        MenuBar menuBar = new MenuBar();
        
        Menu menuFile = new Menu("文件");                
        Menu menuEdit = new Menu("编辑");
        Menu menuHelp = new Menu("帮助");        
        menuBar.getMenus().addAll(menuFile, menuEdit, menuHelp);
        
        return menuBar;
    }
    
    private HBox getRightHBox()
    {
        HBox hbox = new HBox();
        
        VBox vbox = new VBox(50);
        vbox.setPadding(new Insets(0, 20, 0, 20));
        vbox.setAlignment(Pos.CENTER);
        
        vbox.getChildren().addAll(new Text("其他提示信息A"), 
                new Text("其他提示信息B"), new Text("其他提示信息C"));    
        hbox.getChildren().addAll(new Separator(Orientation.VERTICAL), vbox);     
 
        return hbox;
    }
    
    private HBox getLeftHBox()
    {
        HBox hbox = new HBox();
        
        VBox vbox = new VBox(10);
        vbox.setPadding(new Insets(10));
        
        Text text = new Text("导航");
        text.setFont(Font.font("Helvetica", FontWeight.BOLD, 20));
        
        VBox vboxText = new VBox(10);
        for (int i = 1; i <= 10; i++)
        {
            vboxText.getChildren().add(new Text("目录 " + i));
        }        
        
        Text text2 = new Text("结束位");
        text2.setFont(Font.font("Helvetica", FontWeight.BOLD, 20));
        
        vbox.getChildren().addAll(text, vboxText, text2);         
        hbox.getChildren().addAll(vbox, new Separator(Orientation.VERTICAL));
        
        return hbox;
    }
    
    private VBox getFooter()
    {
        VBox vbox = new VBox();
        
        HBox hbox = new HBox(20);
        hbox.setPadding(new Insets(5));
        hbox.setAlignment(Pos.CENTER);
        
        hbox.getChildren().addAll(new Text("状态信息01")
                , new Text("状态信息02"), new Text("状态信息03"));        
        vbox.getChildren().addAll(new Separator(), hbox);
                
        return vbox;
    }
    
    private StackPane getCenterPane()
    {
        StackPane stackPane = new StackPane();
        stackPane.setAlignment(Pos.CENTER);
        
        Rectangle rec = new Rectangle(200, 200);
        rec.setFill(Color.DODGERBLUE);
        rec.widthProperty().bind(stackPane.widthProperty().subtract(50));
        rec.heightProperty().bind(stackPane.heightProperty().subtract(50));
        
        stackPane.getChildren().addAll(rec);
        
        return stackPane;
    }
    
    public static void main(String[] args)
    {
        Application.launch(args);
    } 

}

例程的演示页面:
在这里插入图片描述

(四) HBox面板
HBox采用的布局管理器,我称其为行式布局管理器,这种布局管理器是对AWT的FlowLayout做了一些限制,它将所有的控件放在同一行,各控件横向布置,无论有多少个控件都是放在同一行,不允许换行。而AWT的FlowLayout布局管理器当一行放不下时是允许换行的。
HBox面板测试例程:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class PaneTest extends Application {
	public static Pane FlowPaneTest() {
		FlowPane pane = new FlowPane();
		 
		pane.setPadding(new Insets(11, 12, 13, 14));
		 
		//设置控件之间的垂直间隔距离
		pane.setHgap(5);
		 
		//设置控件之间的水平间隔距离
		pane.setVgap(5);
		
		Label lbName = new Label("姓名:");
		 
		TextField tfName = new TextField();
		 
		Label lbPassword = new Label("密码:");
		 
		TextField tfPassword = new TextField();   
		 
		Button okbtn = new Button("递交");
		
		pane.getChildren().addAll(lbName,tfName,lbPassword,tfPassword,okbtn);
		
		return pane;
	}
	
	public Pane GridPaneTest() {
	    GridPane pane = new GridPane();
	    
	    pane.setAlignment(Pos.CENTER);
	 
	    pane.setPadding(new Insets(11.5, 12.5, 13.5, 14.5));
	 
	    pane.setHgap(5.5);
	 
	    pane.setVgap(5.5);
	    
	    pane.add(new Button("按钮A"), 0, 0);
	    
	    pane.add(new Button("按钮B"), 1, 0);
	 
	    pane.add(new Button("按钮C"), 0, 1);
	 
	    pane.add(new Button("按钮D"), 1, 1);
	 
	    pane.add(new Button("按钮E"), 0, 2);
	 
	    pane.add(new Button("按钮F"), 1, 2);
	    
	    return pane;
	}
	

	public Pane HBoxTest() {
		HBox pane = new HBox(15);
		 
	    pane.setPadding(new Insets(15, 15, 15, 15));
	 
	    pane.setStyle("-fx-background-color: blue");
	    
	    pane.getChildren().add(new Button("按钮A"));
	    
	    pane.getChildren().add(new Button("按钮B"));
	 
	    pane.getChildren().add(new Button("按钮C"));
	 
	    pane.getChildren().add(new Button("按钮D"));
	 
	    pane.getChildren().add(new Button("按钮E"));
	 
	    pane.getChildren().add(new Button("按钮F"));
	    
	    return pane;
	}
	
    @Override
    public void start(Stage stage) {
    	//Pane pane = FlowPaneTest();
    	//Pane pane = GridPaneTest();
    	Pane pane = HBoxTest();
    	
        // 创建场景
        Scene scene = new Scene(pane, 320, 150);

        // 设置舞台
        stage.setScene(scene);
        stage.setTitle("JavaFX面板演示");
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

例程测试效果图:
在这里插入图片描述
当框架窗口足够宽时,显示效果如下 :
在这里插入图片描述
当框架窗口宽度不足以显示所有组件时,绝不换行显示,超出窗体部分不可见。其显示效果如下 :
在这里插入图片描述

(五) VBox面板

VBox的布局策略与HBox有些类似,不过VBox是将所有的控件放在同一列,各控件纵向布置。

不同面板的布局策略各有特点,在应用开发中,可以根据实际需求选取合适的面板进行布局。很多情形可能需要将多种不同类型的面板组合起来使用,才能符合需求效果。

JavaFx 2.0 还可用Java编程实现音频和视频播放器,下一篇博客:
【多媒体】Java实现MP4和MP3音视频播放器【JavaFX】【音视频播放】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1889827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何创建移动类型

第一步打开事务代码&#xff1a; OMJJ 下面这个工作区可以不填&#xff0c;或者填入你的范围&#xff08;例如我准备copy Z52成为Z54 那么就可以输入从Z52到Z54&#xff0c;SAP的这个操作就是这么怪&#xff0c;哈哈&#xff09;不然就会出现一个这样的报错“在工作区中指定关…

YOLOv8改进 | 卷积模块 | SAConv可切换空洞卷积

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

[数据集][目标检测]螺丝螺母检测数据集VOC+YOLO格式2400张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2400 标注数量(xml文件个数)&#xff1a;2400 标注数量(txt文件个数)&#xff1a;2400 标注…

JavaSE (Java基础):面向对象(上)

8 面向对象 面向对象编程的本质就是&#xff1a;以类的方法组织代码&#xff0c;以对象的组织&#xff08;封装&#xff09;数据。 8.1 方法的回顾 package com.oop.demo01;// Demo01 类 public class Demo01 {// main方法public static void main(String[] args) {int c 10…

为什么有些人思考得多,决策反而不好?避免过度拟合的终极指南:决策高手的秘密:灰度认知,黑白决策

在决策过程中&#xff0c;过度关注细节可能导致决策效果不佳&#xff0c;这被称为“过度拟合”。为了避免这种情况&#xff0c;我们需要进行“灰度认知&#xff0c;黑白决策”&#xff0c;即接受不确定性&#xff0c;关注整体趋势&#xff0c;设定明确目标&#xff0c;简化选择…

微信小程序 调色板

注意&#xff1a;是在uniapp中直接使用的一个color-picker插件&#xff0c;改一下格式即可在微信小程序的原生代码中使用 https://github.com/KirisakiAria/we-color-picker 这是插件的地址&#xff0c;使用的话先把这个插件下载下来&#xff0c;找到src&#xff0c;在项目创…

STM32CubeMX实现矩阵按键(HAL库实现)

功能描述&#xff1a; 实现矩阵按键验证&#xff0c;将矩阵按键的按键值&#xff0c;通过串口显示&#xff0c;便于后面使用。 实物图 原理图&#xff1a; 编程原理&#xff1a; 原理很简单&#xff0c;就是通过循环设置引脚为低电平&#xff0c;另外引脚扫描读取电平值&…

[Leetcode 128][Medium] 最长连续序列

目录 题目描述 整体思路 具体代码 题目描述 原题链接 整体思路 首先看到找连续升序排序的最长序列长度&#xff0c;想到对数组进行排序预处理。但是排序算法时间复杂度需要O(nlogn)&#xff0c;题目要求时间复杂度为O(n)。因此不能进行排序与处理 接着想到数据结构哈希表&a…

苹果电脑内存满了怎么清理空间垃圾 苹果电脑内存不足怎么办 MacBook优化储存空间

在日常使用苹果电脑过程中&#xff0c;某些用户可能经常会遇到存储空间不足的问题&#xff0c;尤其是当硬盘存储了大量的文件。这不仅影响电脑的运行速度&#xff0c;还可能导致应用程序运行不稳定。 一、节省 MacBook Pro 的空间 苹果电脑的操作系统&#xff08;macOS&#x…

PDF 生成(6)— 服务化、配置化

当学习成为了习惯&#xff0c;知识也就变成了常识。 感谢各位的 关注、点赞、收藏和评论。 新视频和文章会第一时间在微信公众号发送&#xff0c;欢迎关注&#xff1a;李永宁lyn 文章已收录到 github 仓库 liyongning/blog&#xff0c;欢迎 Watch 和 Star。 回顾 前面我们分…

Android 15 应用适配默认全屏的行为变更(Android V的新特性)

简介 Android V 上默认会使用全面屏兼容方式&#xff0c;影响应用显示&#xff0c;导致应用内跟导航标题重合&#xff0c;无法点击上移的内容。 默认情况下&#xff0c;如果应用以 Android 15&#xff08;API 级别 35&#xff09;为目标平台&#xff0c;在搭载 Android 15 的设…

鸿蒙应用笔记

安装就跳过了&#xff0c;一直点点就可以了 配置跳过&#xff0c;就自动下了点东西。 鸿蒙那个下载要12g个内存&#xff0c;大的有点吓人。 里面跟idea没区别 模拟器或者真机运行 真机要鸿蒙4.0&#xff0c;就可以实机调试 直接在手机里面跑&#xff0c;这个牛逼&#xf…

现代智能宠物喂食器方案定制

现代智能宠物喂食器不仅具备定时喂食功能&#xff0c;帮助宠物主人管理宠物的饮食时间和食量&#xff0c;还加入了录音功能和摄像头&#xff0c;使得宠物主人即使不在家也能与宠物保持互动&#xff0c;并实时监控宠物的状况。此外&#xff0c;一些产品还具备紧急预警功能&#…

数据分析:基于聚类的LASSO预测模型包----clustlasso

介绍 clustlasso是结合lasso和cluster-lasso策略的R包&#xff0c;并发表在Interpreting k-mer based signatures for antibiotic resistance prediction。 标准交叉验证lasso分类或回归流程如下&#xff1a; 选择交叉验证数据集&#xff08;数据分割&#xff09;&#xff1…

【计算机网络】网络层(作业)

【一】 1、某主机的 IP 地址为 166.199.99.96/19。若该主机向其所在网络发送广播 IP 数据报&#xff0c; 则目的地址可以是&#xff08;D&#xff09;。 A. 166.199.99.255B. 166.199.96.255C. 166.199.96.0D. 166.199.127.255 解析&#xff1a; 166.199.99.96/19166.199.0…

YOLOv5初学者问题——用自己的模型预测图片不画框

如题&#xff0c;我在用自己的数据集训练权重模型的时候&#xff0c;在训练完成输出的yolov5-v5.0\runs\train\exp2目录下可以看到&#xff0c;在训练测试的时候是有输出描框的。 但是当我引用训练好的best.fangpt去进行预测的时候&#xff0c; 程序输出的图片并没有描框。根据…

nginx转发的问题

我在项目配置的时候遇到一个问题&#xff1a; 配置了域名转发&#xff0c;且配置了https nginx配置如下&#xff1a; server {listen 443 ssl;server_name yourdomain.com;ssl_certificate /path/to/your/certificate.crt;ssl_certificate_key /path/to/your/private.key;loca…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01 环境搭建验证码倒计时短信服务邮件服务验证码短信形式&#xff1a;邮件形式&#xff1a; 异常机制MD5参考 环境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…

2024年软件测试面试题,精选100道,内附文档。。。

测试技术面试题 1、我现在有个程序&#xff0c;发现在 Windows 上运行得很慢&#xff0c;怎么判别是程序存在问题还是软硬件系统存在问题&#xff1f; 2、什么是兼容性测试&#xff1f;兼容性测试侧重哪些方面&#xff1f; 3、测试的策略有哪些&#xff1f; 4、正交表测试用…

lua中判断2个表是否相等

当我们获取 table 长度的时候无论是使用 # 还是 table.getn 其都会在索引中断的地方停止计数&#xff0c;而导致无法正确取得 table 的长度&#xff0c;而且还会出现奇怪的现象。例如&#xff1a;t里面有3个元素&#xff0c;但是因为最后一个下表是5和4&#xff0c;却表现出不一…