基于FlatLaf的HiDPI环境下组件与图形像素精准布局方案问询
DPI感知Swing应用像素精准实现问题
需求背景
- 使用FlatLaf作为主题
- 测试时强制设置
-Dsun.java2d.uiScale=2,但应用需支持任意DPI - 表单、对话框、控制面板等组件需适配缩放
- 通过布局管理器展示面板,在内部框架中渲染图形
现存问题
- 当设置
-Dsun.java2d.uiScale=2时,缩放对程序“不可见”:内部框架设为512×512,实际显示为1024×1024(坐标被Transform转换、Stroke加倍等) - 调整面板大小(拆分窗格拆分器、内部框架边缘)时,每次跳跃2像素
- 若图像尺寸为奇数,即便重绘时调整
Transform实现像素精准,也无法让内部框架完美适配图像大小
期望目标
实现类似IntelliJ IDEA或Web应用的GUI:
- 组件清晰可读
- 拆分器及尺寸调整以设备像素为单位,而非逻辑像素
补充猜测(2024-09-25)
IntelliJ IDE全程使用uiScale=1,通过动态更新单个LAF定义实现“视觉”缩放。例如,工作电脑IDE缩放系数为1.25时,主窗口宽度远超2400px,选中按钮下方的小字由17pt的UIResource样式定义。
SSCCE代码
import java.awt.*; import javax.swing.*; import java.awt.image.*; import com.formdev.flatlaf.*; public final class Scratch extends JDesktopPane { public static void main(String... args) { SwingUtilities.invokeLater(() -> { FlatLaf.setup(new FlatDarkLaf()); JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.setContentPane(new Scratch()); f.setSize(600, 600); f.setVisible(true); }); } public Scratch() { add(new MyInternalFrame()); } private static class MyInternalFrame extends JInternalFrame { public MyInternalFrame() { setResizable(true); setContentPane(new Document()); setSize(512, 512); setVisible(true); } } private static class Document extends JPanel { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // Create custom image to curcumvent any shenanigans with the Panel's g. BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D g2 = image.createGraphics(); // forgot to dispose kek g2.drawOval(0, 0, getWidth() - 1, getHeight() - 1); g2.drawString(getWidth() + "×" + getHeight(), 4, getHeight() - 4); g.drawImage(image, 0, 0, null); } } }
提问
有没有低工作量的实现方法(无需搭建完整平台)?
内容的提问来源于stack exchange,提问作者Mark Jeronimus
相关产品推荐
相关产品推荐

