Java Swing界面开发尘年往事

前言

Java Swing出现二十多年了,但依然屹立不倒,和Qt、Electron一起成为跨平台界面开发的三大选择。这三大阵营各代表一种GUI的技术方向,迥然不同而互不雷同,又刚好互补。

Java Swing + JFormDesigner是一对黄金搭档,犹如Qt + QtDesigner。IDEA能把Swing玩到出神入化,你就不能说Swing不行。

最近几年又出现了Jetpack Compose,包括SwiftUI,采用声明式、组合式写法,和React一样,但是,我依然没看出开发效率上有多大的提升,人类总是用不同的方式做同样的事情。

AWT/Swing/JavaFX综述

Swing

JFrame

JFrame中的层次分布及相对关系是:

  • 最底层是:JRootPane;
  • 第二层是:JlayerPane,这层上面包含一层ContentPane(默认不透明),也正是我们常说的内容面板。
  • 最上层就是:GlassPane(默认是透明的)
    一般我们拖放的控件就是在ContentPane层上。

什么是Pane

在 Java Swing 中,Pane 通常是指一个容器类组件,它可以用来包含其他 Swing 组件。Pane 继承自 JComponent 类,因此它具有绘制和布局的能力。Pane 本身不提供任何特定的布局策略,这意味着你可以自由地向其中添加子组件,并通过设置它们的边界或使用布局管理器来安排它们的位置和大小。

Swing 提供了几种 Pane 类型的容器,例如:

  • JPanel:这是最常用的 Pane 类型,通常用作其他组件的容器。JPanel 可以有边框,并且可以设置布局管理器,使其成为组织和分组其他 Swing 组件的理想选择。

  • JLayeredPane:这个容器允许你通过层(layers)来管理组件的显示顺序。组件可以被放置在不同的层上,并且可以部分或完全重叠。这在创建复杂的用户界面元素(如工具提示、弹出窗口等)时非常有用。

  • JGlassPane:这是一个透明的容器,可以覆盖在一个应用程序的窗口上。JGlassPane 通常用于创建装饰性的图形界面元素或拦截鼠标和键盘事件。

  • JEditorPane:这是一个可以显示和编辑纯文本和 HTML 格式文本的容器。它通常用于创建简单的文本编辑器或显示富文本内容。

  • JTextPane:这是一个扩展自 JEditorPane 的容器,用于显示和编辑格式化文本。它支持复杂的文本布局,如嵌入图像、表格和超链接。

  • JSplitPane:这是一个可调整大小的容器,它将窗口分割成两个(或更多)可调整的部分,通常用于同时显示多个组件或视图。

在 Swing 应用程序中,Pane 组件通常用作布局的构建块。你可以使用 Pane 来创建复杂的布局结构,并通过嵌套不同的 Pane 类型来组织你的界面。例如,你可能会有一个 JSplitPane,其中包含两个 JPanel,每个 JPanel 又包含其他子组件。

总的来说,Pane 在 Swing 中是一个通用的容器,它为组织和显示其他组件提供了灵活性和强大的功能。通过使用不同的 Pane 类型和布局管理器,你可以创建出丰富和动态的用户界面。

JLayeredPane用法

在 JLayeredPane 中,每个组件都可以被放置在不同的层上,并且每个层都有自己的可见性设置。每一层都有自己的z-order值,默认有五层,add(component, zOrder)能将组件添加到某一层。每个组件可以设置透明度。这里的层和Photoshop的层比较类似。最终你看到的就是各层叠加的效果。

界面设计神器JFormDesigner

如果没有这个工具,Java Swing开发立马索然无味。如果你还在怀念Delphi和VB的所见即所得,那JFormDesigner从此让Java界面开发一样无所不能。
在这里插入图片描述掌握了它,做界面原型开发也不无不可。

FormLayout

Java自带的几个布局管理器灵活性稍差,使用复杂,所以有了jgoodies的FormLayout。

FormLayout layout = new FormLayout( 
        "right:pref, 6dlu, 50dlu, 4dlu, center:50dlu", // columns
        "pref, 3dlu, pref, 3dlu, pref"); // rows   

参数解释
列与行的参数都由三个部分组成:对齐方式、固定尺寸、调整方式。
对齐方式中,列对齐有left, center, right, fill.行对齐有:top, center, bottom, fill. 其中fill表示填充至整个区域。列的默认对齐方式是fill,行是center。

关于列尺寸的问题最麻烦,有很多种单位,pref表示preferred size,即首选尺寸大小。
min表示minimum size,dlu 表示dialog units,(px, pt, in, mm, cm)分别表示Pixel, Points, Inches, Millimeter, Centimeter。

其实不用去查文档,直接通过designer就能掌握这些参数的含义。

jxbrowser

import static com.teamdev.jxbrowser.engine.RenderingMode.*;
 
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.view.swing.BrowserView;
 
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
 
/**...*/
public final class HelloWorld {
public static void main(String[] args) {
Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);
Browser browser = engine.newBrowser();
 
SwingUtilities.invokeLater(() -> {
  BrowserView view = BrowserView.newInstance(browser);
 
  JFrame frame = new JFrame("Swing BrowserView");
  frame.add(view, BorderLayout.CENTER);
  frame.setSize(700, 500);
  frame.setVisible(true);
 
  browser.navigation().loadUrl(
      "https://html5test.teamdev.com");
});
}
}

Look and Feel

使用FlatLaf库即可极大改善界面美观程度:

import com.formdev.flatlaf.FlatLightLaf;
import javax.swing.UIManager;
try {
    UIManager.setLookAndFeel( new FlatLightLaf() );
} catch( Exception ex ) {
    System.err.println( "Failed to initialize theme. Using fallback." );
}

常见问题

Swing无法启动

一个gradle项目中创建了一个swing应用,但启动报错:

Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException: 
The application is not running in a desktop session,
but this program performed an operation which requires it.

于是加上参数:-Djava.awt.headless=false,结果调试模式可以运行起来,但运行模式无法。

worker线程操作界面

SwingUtilities.invokeLater(()-> {
	// 此处刷新界面
});

JavaFX有自带的runLater可以处理非窗体线程操作窗体的操作。

JTextArea追加内容无显示

正确写法如下:

SwingUtilities.invokeLater(() -> {
            textArea.append(msg + "\r\n");
 });

//或者调用paintImmediately()
public static void appendJTextArea(String info) {
	promptContent.append(info+"\n");
	promptContent.paintImmediately(promptContent.getBounds()); 
}

应该包含哪些java module?

根据你用到的JDK 类,查一下https://docs.oracle.com/en/java/javase/11/docs/api/index.html即可。

界面库

  • https://github.com/JFormDesigner
  • https://github.com/JFormDesigner/FlatLaf

学习IDEA和Netbeans

IntelliJ Platform是一个开源的,可以构建IDE的平台,基于该平台的产品有 IntelliJ IDEA,Android Studio from Google 等。
IntelliJ Platform的能力来源于Program Structure Interface (简称PSI),源码解析为PSI,包含构建语法和和语义模型,为代码创建索引等提代了一系列的接口,并提供了快速导航,快速查找,自动完成代码,自动关联,代码检查,代码重写,快速修复和重构等等功能。

IntelliJ Platform包含了很多编程语言的解析器和PSI模型,可以方便的扩展,来支持其它的编程语言。

IDEA的界面实现在:intellij-community/platform/ide-core-impl/src/com/intellij/ide和platform/platform-impl/src目录下面EditorTextField是编辑器的基础。可以参照intellij-sdk-code-samples了解常用UI组件的用法。

其它

Lightweight Java Game Library

优秀开源

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北极象

如果觉得对您有帮助,鼓励一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值