首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swing HiDPI边框渲染(Windows10/OpenJRE11)

Swing HiDPI边框渲染(Windows10/OpenJRE11)
EN

Stack Overflow用户
提问于 2021-02-18 21:39:46
回答 1查看 31关注 0票数 0

我维护了一个旧的Swing应用程序,它使用自定义的border实现作为窗口装饰,并使用扩展MetalLookAndFeellook and feel实现。look and feel覆盖initComponentDefaults(UIDefaults table)并将自定义边框安装为"RootPane.frameBorder",依此类推。

自定义边框本身通过实现paintBorder(Component c, Graphics g, int x, int y, int width, int height)将32行预定义颜色水平绘制在一起。当Settings > Display > Scale and layout中的display scaling设置为100%时,这在Windows102004或更高版本上运行良好。当display scaling设置为125%或更大时,边框将不会正确绘制,它会在应该一起绘制的线条之间显示白色线条。

Advanced scaling settings中的Fix scaling for apps似乎不会影响边框绘制。

我使用AdoptOpenJDK OpenJDK 11.0.4+11 x64。我希望Swing也能像字体一样放大线条。

为什么会发生这种情况?如何解决这个问题?

边界实现:

代码语言:javascript
复制
public class CustomWindowBorder implements Border{

   public static final int BORDER_THICKNESS = 3;
   
   private static final CustomWindowBorder globalInstance = new CustomWindowBorder();

   public static CustomWindowBorder getInstance(){

      return CustomWindowBorder.globalInstance;
   }

   private CustomWindowBorder(){}
   
   @Override
   public Insets getBorderInsets(Component c){

      return new Insets(1,
                        CustomWindowBorder.BORDER_THICKNESS,
                        CustomWindowBorder.BORDER_THICKNESS,
                        CustomWindowBorder.BORDER_THICKNESS);
   }

   @Override
   public boolean isBorderOpaque(){

      return true;
   }

   @Override
   public void paintBorder(Component c,
                           Graphics g,
                           int x,
                           int y,
                           int width,
                           int height){

      Color[] decorationColors = [ommited]; // 30 colors in total
      Color[] borderColors = [ommited]; // 3 colors in total

      int yStart = 30;

      for(int i = 0; i < decorationColors.length; i++ ){
         // top
         Color clr = decorationColors[i];
         g.setColor(clr);

         g.drawLine(0,
                    i,
                    width,
                    i);
      }

      for(int i = 0; i < borderColors.length; i++ ){
         Color clr = borderColors[i];
         g.setColor(clr);

         // left
         g.drawLine(i,
                    yStart,
                    i,
                    height - i - 1);
         // right
         g.drawLine(width - i - 1,
                    yStart,
                    width - i - 1,
                    height - i - 1);
         // below
         g.drawLine(i,
                    height - i - 1,
                    width - i - 1,
                    height - i - 1);
      }
   }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-22 19:10:39

我发现,当使用具有一个像素宽度或高度的Graphics::drawLineGraphics::fillRect时,Swing只在屏幕上绘制一个未缩放的像素宽度的线条,独立于窗口的显示缩放。

当我用Graphics::fillRect绘制边框并让它填充顶部的每30条水平线和其他边的3条线时,空白将被完全填充。

我的解决方案是在Graphics::fillRect上绘制每一条线,并用颜色填充其余的整条线,减少填充矩形的宽度/高度,同时将其移动到下一行。这不是画这个的最有效的方法,但它对我来说很有效。

修改后的paintBorder方法:

代码语言:javascript
复制
@Override
public void paintBorder(Component c,
                        Graphics g,
                        int x,
                        int y,
                        int width,
                        int height){

   Color[] decorationColors = [ommited]; // 30 colors in total
   Color[] borderColors = [ommited]; // 3 colors in total

   int yStart = 30;

   for(int i = 0; i < decorationColors.length; i++ ){
      // top
      Color clr = decorationColors[i];
      g.setColor(clr);

      g.fillRect(0,
                 i,
                 width,
                 decorationColors.length - i);
   }

   for(int i = 0; i < borderColors.length; i++ ){
      Color clr = borderColors ;
      g.setColor(clr);

      // left
      g.fillRect(i,
                 yStart,
                 borderColors.length - i,
                 height - yStart - i);

   }
   for(int i = borderColors.length - 1; i >= 0; i-- ){
      Color clr = borderColors[i];
      g.setColor(clr);

      // right
      g.fillRect(width - i - 1,
                 yStart,
                 borderColors.length - i,
                 height - yStart - i);
      // below
      g.fillRect(i,
                 height - i - 1,
                 width - i,
                 borderColors.length - i);
   }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66261145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档