Java 1.8渲染边框不正确。

11

我在从Java 1.7升级到Java 1.8后遇到了一些摇摆边框的问题:

在所有我的按钮上,我需要一个实心的背景颜色和实线的边框,因此我通过UIManager定义了它。在Java 1.7和以前的版本中,一切看起来都很好,但在Java 1.8上,边框混乱不堪。单选按钮也看起来非常奇怪和锯齿状。复选框也似乎有问题。

为了演示,我创建了一个包含几个组件的简短示例:

import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.UIManager;

public class CompDemo extends JFrame
{

    public CompDemo()
    {

        setLayout(new FlowLayout());

        add(new JButton("button"));
        add(new JTextField("txt"));
        add(new JComboBox<String>());
        add(new JRadioButton("radio"));
        add(new JToggleButton("toggle"));
        add(new JCheckBox("check"));

        pack();
        setVisible(true);

    }

    public static void main(String[] args)
    {
        UIManager.put("Button.background", Color.LIGHT_GRAY);
        UIManager.put("Button.border", BorderFactory.createCompoundBorder(BorderFactory
            .createLineBorder(Color.RED), BorderFactory.createLineBorder(Color.CYAN)));

        new CompDemo();

    }

}
这里您可以查看在不同JDK版本下的输出结果(缩放至200%,未开启抗锯齿): 第一张图片为Java 7u60,显示得非常正确。 在第二张图片中,我圈出了差异之处。 第三张图片为Java 8u11,你可以看到边框相当混乱(下拉箭头也看起来很奇怪)。
我使用了青色LineBorder和红色LineBorder,这样你就可以更清楚地看到问题所在。 我的操作系统是Windows 8 x64,如果这有关系的话。
请问有人能告诉我为什么在Java 8下会有这么大的差异吗?我是错过了什么,还是Java 1.8真的把边框搞糟了? 我需要提交错误报告吗?还是只需进行一些调整即可使其再次正常显示?
谢谢, gc

我无法使用您提供的代码在Windows 7 64位上进行重现,该代码是使用JDK 8u11编译的。 - user1071777
对我来说看起来也不错,Win8.1 x64,JDK 8u11。 - Durandal
在Win7/64,Java8u??上运行良好吗?服务热线的经典提示:“尝试关闭并重新启动...嗯...尝试更新您的图形驱动程序”(至少值得一试) - Marco13
请查看Swing在JDK 1.8中呈现出现问题,但在JDK 1.7中正确。将显卡的能量控制更改为最大性能可以解决该问题。 - MicSim
1个回答

2
感谢您的回答。
我进行了进一步测试。在运行Win7和Java 8的虚拟机上,它看起来也很好,在另一个运行Win8和Java 8的虚拟机上也是如此。
将图形卡更改为最大性能也没有改变任何内容。但是,基于此,我进行了更多的研究,最终找到了问题的原因:我的笔记本电脑(ThinkPad T540p)有两张显卡:集成的Intel GMA 4600和外部Nvidia卡。操作系统/驱动程序似乎可以决定哪个显卡用于哪个显示器,甚至用于哪些应用程序。除了3D应用程序外,我认为大多数情况下会使用Intel显卡-我猜出于节能的原因(即使它不运行在电池上)。
在Nvidia控制面板中,我可以配置一个特定的应用程序始终使用特定的显卡,因此我定义了Java始终使用Nvidia显卡,这似乎已经解决了问题:使用Nvidia卡,所有内容看起来都很好。

我有同样的问题。我打开了Nvidia控制面板,但是在哪里可以配置这个设置? - user2154420
这是我MVIDIA控制面板的截图(抱歉,我的操作系统是德语):http://i.imgur.com/JRGpKQQ.png ...所以我猜在“管理3D设置”中,您必须切换到“程序设置”,在“1.”上选择您的Java二进制文件(可能有多个),并在“2.”上选择“高性能NVIDIA处理器”。如果您没有在“2.”上选择图形处理器的选项,我猜您要么使用不同的驱动程序版本,要么只有一个图形卡,或者您的图形处理器组合不允许此类切换。 - gc_
我发现了完全相同的问题,win7 64位,i7带内置显卡。我发现java8直接计算线条结束位置时会出现错误,导致额外的像素。请注意,在java6中,我们在fillRect(0,0,10,10)和drawRect(0,0,10,10)的不同渲染大小之间也存在同样的问题。我发现唯一的解决方法是将所有Graphics2D操作包装在适配器中,并根据所使用的java版本计算不同的结束点。我别无选择,因为我有一个生产代码,而且我必须让它继续工作。 - Gee Bee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接