当滚动窗格中的系统规模为125%时,Java Swing图形绘制不一致

bpzcxfmw  于 2024-01-05  发布在  Java
关注(0)|答案(1)|浏览(176)

在100%屏幕缩放时,绘制的形状总是“像素完美”。
x1c 0d1x的数据
在125%的屏幕缩放比例下,同一个形状有时会被绘制成顶部有一行额外的像素(1),而不是应该绘制的方式(2)。这些形状被绘制在滚动窗格中的列表中,当上下滚动时,它们 Flink ,从一个版本变成另一个版本,这非常明显和分散注意力。



我观察到这取决于组件的位置,也许我认为它在2个像素之间绘制形状,因此它“随机”选择一个组件的上方像素或另一个组件的下方像素。

  1. package debug;
  2. import java.awt.BorderLayout;
  3. import java.awt.Container;
  4. import java.awt.Dimension;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import java.awt.GridLayout;
  8. import javax.swing.JFrame;
  9. import javax.swing.JPanel;
  10. import javax.swing.JScrollPane;
  11. import javax.swing.SwingUtilities;
  12. import javax.swing.border.EmptyBorder;
  13. public class TestBugScaling implements Runnable {
  14. private final int size = 38;
  15. public static void main(String[] args) {
  16. SwingUtilities.invokeLater(new TestBugScaling());
  17. }
  18. @Override
  19. public void run() {
  20. JFrame frame = new JFrame();
  21. frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  22. frame.setPreferredSize(new Dimension(400, 400));
  23. Container contentPane = frame.getContentPane();
  24. contentPane.setLayout(new BorderLayout());
  25. contentPane.setPreferredSize(new Dimension(400, 400));
  26. JScrollPane scrollPane = new JScrollPane();
  27. scrollPane.setPreferredSize(new Dimension(size + 10, 400));
  28. scrollPane.getVerticalScrollBar().setUnitIncrement(size + 5);
  29. scrollPane.getVerticalScrollBar().setBlockIncrement((size + 5) * 2);
  30. JPanel container = new JPanel();
  31. container.setBorder(new EmptyBorder(5, 5, 5, 5));
  32. container.setLayout(new GridLayout(20, 0, 0, 5));
  33. container.setPreferredSize(new Dimension(size + 10, (size + 5) * 20));
  34. container.add(new CirclePanel());
  35. container.add(new CirclePanel());
  36. container.add(new CirclePanel());
  37. container.add(new CirclePanel());
  38. container.add(new CirclePanel());
  39. container.add(new CirclePanel());
  40. container.add(new CirclePanel());
  41. container.add(new CirclePanel());
  42. container.add(new CirclePanel());
  43. container.add(new CirclePanel());
  44. container.add(new CirclePanel());
  45. container.add(new CirclePanel());
  46. container.add(new CirclePanel());
  47. container.add(new CirclePanel());
  48. container.add(new CirclePanel());
  49. container.add(new CirclePanel());
  50. container.add(new CirclePanel());
  51. container.add(new CirclePanel());
  52. container.add(new CirclePanel());
  53. container.add(new CirclePanel());
  54. scrollPane.setViewportView(container);
  55. contentPane.add(scrollPane, BorderLayout.NORTH);
  56. frame.pack();
  57. frame.setVisible(true);
  58. }
  59. public class CirclePanel extends JPanel {
  60. public CirclePanel() {
  61. super();
  62. setPreferredSize(new Dimension(size, size));
  63. setMinimumSize(new Dimension(size, size));
  64. setMaximumSize(new Dimension(size, size));
  65. }
  66. @Override
  67. public void paintComponent(Graphics g) {
  68. Graphics2D g2 = (Graphics2D) g.create();
  69. g2.fillOval(0, 0, getHeight(), getHeight());
  70. g2.dispose();
  71. }
  72. }
  73. }

字符串
有了这个代码,如果你有100%的屏幕比例,你会看到一个平滑滚动的圆圈。相反,125%的屏幕比例,如果你仔细看,你会看到滚动时圆圈上下摆动1个像素。
有什么方法可以预防/解决这个问题吗?是什么原因造成的?
我不介意形状不完全完美,但我介意它 Flink ,它不是一直一致的。

lsmepo6l

lsmepo6l1#

我找到了问题所在,更重要的是,我找到了解决方案。
Graphics和Graphics2D对象需要一些余量才能正确绘制曲线形状,事后看来这实际上是很有意义的。
通过简单地将g2.fillOval(1, 1, getHeight() - 2, getHeight() - 2);替换为g2.fillOval(1, 1, getHeight() - 2, getHeight() - 2);,使其在形状周围具有1个单位的间距,它为它提供了足够的空间来处理抗锯齿,并自动修复了我遇到的故障。

相关问题