【问题标题】:Java / Swing how to deal with different screen DPI and density settings?Java/Swing如何处理不同的屏幕DPI和密度设置?
【发布时间】:2013-02-06 02:52:05
【问题描述】:

大家好,我最近遇到了一个问题,即现在有些显示器具有不同的 DPI 设置,有些显示器的密度要高得多,例如 Apple 的 Retina 显示器。

如何使用 Java 补偿各种显示器上的不同 DPI 设置和密度?是否可以在任何显示器上将控件缩放为相同大小。我知道在为 Android 编程时,所有测量值都在“DP”中,您可以为三种不同的显示密度指定不同的图像。

有没有一种方法可以使用 Java / Swing 为不同的显示密度选择不同的图像,这样我的应用程序在更高密度的显示器上看起来就不会模糊?或者这不是那么重要或可能吗?我知道 Chrome 目前不考虑 DPI,但 Internet Explorer 和其他应用会考虑。

感谢您的帮助,我是一名长期的 Java 开发人员,我以前从未考虑过 DPI,我想知道我该怎么做 :)

【问题讨论】:

    标签: java swing dpi


    【解决方案1】:

    通过使用

    System.setProperty( "sun.java2d.uiScale", "1.0" );
    

    在您的 java 代码中,应该禁用 ui 缩放。

    【讨论】:

      【解决方案2】:

      使用 JRE 9(或更高版本)。

      这是因为 Java 运行时(旧版本)宣称自己是“DPI-aware”,但并不真正支持 AWT 和 Swing。 Java 应用程序的大小和渲染基于像素而不是适当缩放,这包括 HiDPI 显示。 无论如何,最近已经解决了这个问题。 查看问题JEP 263: HiDPI Graphics on Windows and Linuxupgrade

      所以,增加字体大小不起作用(因为它不会增加其余的东西); jvm 参数-Dsun.java2d.dpiaware=false 不起作用(因为它不被真正支持);并且清单文件 + 注册表编辑(对于 Windows)不起作用。

      然后,您需要在 JRE 9 上运行它,因为它确实支持此功能。

      【讨论】:

        【解决方案3】:

        首先感谢trashgod,您提供的有用链接对他们很有帮助。

        下面我列出了一些关于如何处理我遇到的与 DPI 更改有关的问题的细节。

        字体问题:

        如果字体不适合组件,请查看下面的组件大小问题,因为组件通常不适合内部大小。否则,在 JLabel 中,您可以应用 HTML 标签来自动换行文本(还有其他解决方案,但这对我有用)。

        如果组件的文本自然是默认字体、大小和样式(Tahoma 11 plain),那么一切都会自动为您完成。知道 user574171 在他对How to set the DPI of Java Swing apps on Windows/Linux? 的回答中,在他指向http://kynosarges.org/GuiDpiScaling.html 的链接中提供了显示不同字体和布局管理器问题和优势的图片。这个问题在这里询问“Swing”问题,但他的链接在比较 WPF、JavaFX 和 Swing 布局与基本组件和不同字体时也很有用。你可以看到那里的“Swing a”字体是最好的,那就是 Tahoma 11 Plain。但是,它仅在组件自然是默认字体、大小和样式(Tahoma 11 Plain)时才有效。这意味着文本的粗体、下划线、调整大小和不同的字体会导致针对不同 DPI 自动调整大小。

        如果文本是默认字体 (Tahoma) 但加粗、下划线或不同大小,则文本不会针对不同的 DPI 进行缩放。要修复不同 DPI 的缩放比例,请选中标有“从默认字体导出字体”的框。 “相对”选项将采用默认的 DPI 缩放字体并应用您的相对更改,例如更大或更小、粗体和下划线。还要知道,如果组件是 JLabel,则 DPI 缩放是使用 HTML 标记自动进行的,不管您如何格式化文本(也换行)。

        如果组件不是自然默认的字体、样式和大小(Tahoma 11 plain)或者您想要不同的字体(即不是 Tahoma),那么您需要关联另一个自然默认的组件中的更改,例如J标签。因此,如果 125 DPI 将字体增加 3,那么您将所需的字体增加相同。

        组件尺寸问题:

        所有组件都有首选、最小和最大尺寸属性,但我发现它们不能很好地适应 DPI 更改。垃圾神回答中的“尊重组件的preferred size”项目符号会告诉您所有相关信息。总而言之,让组件的默认大小自行处理,因为它会尝试调整到内部的大小。

        如果组件可以使用默认大小,则可以为您完成 DPI 处理。正如trashgod 所说:“首先,相信平台的外观设计人员会为文本和控件选择合理的默认大小。然后,避免挫败这些默认设置的诱惑。”同样,默认大小的组件通常按内部大小调整(或重新调整大小)。根据我自己的经验,当我设置可调整大小的组件时,我通过“水平调整大小”或“垂直调整大小”来实现,因为我发现它在 DPI 更改和窗口调整大小方面效果很好。

        如果组件的默认大小不起作用,那么首先尝试查看下面我发现的一些具体问题。或者尝试根据正确缩放的组件的变化来缩放组件。 IE,应用您期望缩放组件为 100% DPI 的比率以及对新 DPI 的更改。需要缩放以适应其他组件更改的组件示例是其文本由代码填充或它是图像。

        作为最后的手段,使用 JScrollPane 允许用户滚动查看整个内容。如果窗口/对话框相当大,那么 JScrollPane 是一个好主意,因为如果 DPI 对于用户的视力来说较高,那么窗口通常会比屏幕大。

        注意: 我发现在 JPanel 中封装组件组有助于更好地处理 DPI 变化。

        JTextField 大小问题:

        如果您愿意,可以设置 columns 属性,只设置文本。 columns 属性是要显示的字母或数字的数量。通常在允许用户输入数字时使用。知道 columns 属性适用于多个平台。

        JSpinner 大小问题:

        将模型设置为准确、有效和默认值。因此,组件的自动调整大小是针对最大值完成的,并且适用于 DPI 更改和其他平台。

        表格行高问题:

        表格行高不会随着 DPI 的提高而变化。我遇到了这个问题,这似乎是因为我试图与旧版本的 Java 兼容。修复因 DPI 变化导致的字体大小比例变化或 JLabel 高度比例变化的倍增问题。

        【讨论】:

          【解决方案4】:

          首先,相信平台的外观设计人员会为文本和控件选择合理的默认大小。然后,避免挫败这些默认设置的诱惑。以下是一些启发式方法:

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多