【问题标题】:Bad Swing UI scaling on high resolution (MS Surface)高分辨率 (MS Surface) 上的不良 Swing UI 缩放
【发布时间】:2015-08-26 19:07:11
【问题描述】:

我目前正在开发一个涉及 Swing GUI 的小型 Java 应用程序。在我的开发 PC 上一切看起来都很好,但是当我在我的 MS Surface 上运行它时,一些图标对于组件来说似乎太大了(或者对于图标来说组件太小了)。

这就是我的意思:

Google 研究使我得出结论,这是由于 Surface 的高分辨率和 Win8 的缩放让某些项目显得更大一些。所以我将缩放重置为 100%,它实际上修复了不良缩放。

不幸的是,这并不能真正解决我的问题。没有缩放,一切都太小了,所以我宁愿不禁用它。但是有什么聪明的方法可以解决这个问题吗?我可以“取消缩放”我的程序或 Java 的图标吗?理想情况下,我什至想要放大整个框架,因为一切都相当小。

编辑:显然,我也尝试过调整实际 JFrame 的大小,但它对对话框大小没有影响。我通过

调用对话框
JOptionPane.showMessageDialog(frame, msg, "Information", JOptionPane.INFORMATION_MESSAGE);

顺便说一句。

【问题讨论】:

  • Oracle 不太可能为 Swing 添加高分辨率。你可以试试 JavaFX 或Apache Pivot
  • 1.这些图标(分布在 Java 包中,在 UIManager 中初始化)具有固定的像素大小,2. 它不会对 Win8/8.1 显示设置中的图标大小做出反应,3. 可能是 Surface 的具体问题,you can to test

标签: java swing windows-8.1 scaling screen-resolution


【解决方案1】:

这是一个令人讨厌的、hacky、快速修复的解决方案,它将通过将 Swing 自己的图标大小调整为 80% 来停止讨厌的裁剪。

main 中添加:

String[] iconOpts = {"OptionPane.errorIcon", 
  "OptionPane.informationIcon", 
  "OptionPane.warningIcon", 
  "OptionPane.questionIcon"};
for (String key : iconOpts) {
  ImageIcon icon = (ImageIcon) UIManager.get(key);
  Image img = icon.getImage();
  BufferedImage bi = new BufferedImage(
          img.getWidth(null), img.getHeight(null), 
          BufferedImage.TYPE_INT_ARGB);
  java.awt.Graphics g = bi.createGraphics();
  g.drawImage(img, 0, 0, 
          (int) (img.getWidth(null) * 0.8), 
          (int) (img.getHeight(null) * 0.8), null);
  ImageIcon newIcon = new ImageIcon(bi);
  UIManager.put(key, newIcon);
}

您可能需要首先检查这是否真的需要 - Windows 8/10 默认为 125%,但有些人会将其切换回 100%。我还没有找到一种优雅的方法来做到这一点,但是这些方面的东西会给你一个想法:

java.awt.Font font = (java.awt.Font) UIManager.get("Label.font");
if (font.getSize() != 11) {
    //resize icons in here
}

【讨论】:

  • 感谢您的提示。但它也可以将比例设置为 1.0,而不是使用 (int) (img.getWidth(null) * 0.8), (int) (img.getHeight(null) * 0.8) 如果你使用 (int) ( img.getWidth(null) * 1.0), (int) (img.getHeight(null) * 1.0) 所以,它似乎与比例无关,但与原点有关......我不知道确切。跨度>
【解决方案2】:

大多数 Swing 外观和感觉根本不支持高 DPI,即使 Nimbus 也不支持,即使它应该是可扩展的。我发现一些旧博客文章说 Nimbus 最终可能会提供高 DPI 缩放,但显然这从未发生过。

一个例外是系统 LAF,但在所有 DPI 设置下,其默认字体比实际系统字体大小小约 10%。此外,必须明确选择系统,如下所述:http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

您也无法在 Swing 中设置单一的缩放因子。特定的 LAF 必须提供代码来处理缩放。所以你能做的最好的就是选择系统并希望它足够好。

但是,JavaFX 在我的系统上可以正确地自动扩展至 150%。如果可能的话,我建议您使用 JavaFX 来构建您的 GUI。

编辑:我做了几个小测试程序,并为各种 GUI 框架、Swing 主题和 DPI 设置截取了比较截图。这可能对阅读此问题的人有用:http://kynosarges.org/GuiDpiScaling.html

【讨论】:

    【解决方案3】:

    根据 rosa 的回答,我创建了一个更短、更简洁的变体:

    String[] iconOpts = {"OptionPane.errorIcon", 
        "OptionPane.informationIcon", 
        "OptionPane.warningIcon", 
        "OptionPane.questionIcon"};
    for (String key : iconOpts) {
        ImageIcon icon = (ImageIcon) UIManager.get(key);
        Image img = icon.getImage();
        ImageIcon newIcon = new ImageIcon(img.getScaledInstance(img.getWidth(null), 
            img.getHeight(null), 0));
        UIManager.put(key, newIcon);
    }  
    

    P.S.:由于信誉系统,我无法对 rosa 的帖子发表评论。

    编辑:在我看来,Java 10 似乎包含了对 highdpi 缩放的修复。因此,在使用此处的任何解决方案之前,请先检查 java 版本。

    【讨论】:

      猜你喜欢
      • 2014-01-17
      • 1970-01-01
      • 2016-10-21
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      相关资源
      最近更新 更多