如何解决Swing HiDPI 边框渲染Windows 10/OpenJRE 11
我维护了一个旧的 Swing 应用程序,该应用程序使用自定义 border 实现作为带有扩展 MetalLookAndFeel 的 look and feel
实现的窗口装饰。 look and feel
覆盖 initComponentDefaults(UIDefaults table)
并将自定义边框安装为 "RootPane.frameBorder"
等。
自定义边框本身通过实现 paintBorder(Component c,Graphics g,int x,int y,int width,int height)
将 32 行预定义颜色水平绘制在一起。当 display scaling
在 Settings > display > Scale and layout
中设置为 100% 时,这适用于 Windows 10 2004 或更新版本。当 display scaling
设置为 125% 或更高时,边框将无法正确绘制,在应绘制在一起的线条之间出现白线。
Fix scaling for apps
中的 Advanced scaling settings
似乎不影响边框绘制。
我使用 AdoptOpenJDK OpenJDK 11.0.4+11 x64
。我希望 Swing 也能放大线条,比如字体等。
为什么会这样?如何解决这个问题?
边框实现:
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);
}
@Override
public boolean isBorderOpaque(){
return true;
}
@Override
public void paintBorder(Component c,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,height - i - 1);
// right
g.drawLine(width - i - 1,width - i - 1,height - i - 1);
// below
g.drawLine(i,height - i - 1,height - i - 1);
}
}
}
解决方法
我发现当使用具有一个像素宽度或高度的 Graphics::drawLine
或 Graphics::fillRect
时,Swing 会在屏幕上精确绘制一条未缩放的像素宽线,与 Windows 的显示缩放无关。
当我用 Graphics::fillRect
绘制边框并让它填充顶部的每 30 条水平线和其他边的 3 条线时,空白将完全填充。
我的解决方案是在 Graphics::fillRect
上绘制每条线并用颜色填充整个剩余的线,在将填充矩形移动到下一行的同时减小填充矩形的宽度/高度。这不是最有效的绘制方式,但它对我有用。
修改后的paintBorder方法:
@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,height - yStart - i);
// below
g.fillRect(i,height - i - 1,width - i,borderColors.length - i);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。