0

我遇到了 java.awt.ScrollPane 类的 SCROLLBARS_AS_NEEDED 显示策略处理组件调整大小的问题。理想情况下,如果我有一个包含明显小于 Scrollpane 的 Component 的 ScrollPane,并且我将 Scrollpane 缩小到仍然大于子组件的大小,则不会出现滚动条。然而,实际上,在调整大小操作发生时,两个滚动条似乎都会闪烁,甚至可能会一直持续到操作完成后的下一次重绘。这是一个小例子来说明我的意思:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.ScrollPane;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Tester implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.setProperty("sun.awt.noerasebackground", "true");
        Tester t = new Tester();
        SwingUtilities.invokeLater(t);
    }

    @SuppressWarnings("serial")
    @Override
    public void run() {
        JFrame frame = new JFrame("Tooltip tester");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 800);
        Canvas c = new Canvas(){
            @Override
            public void paint(Graphics g){
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
            }
        };
        c.setPreferredSize(new Dimension(400, 400));
        ScrollPane s = new ScrollPane();
        s.add(c);
        frame.add(s);
        frame.setVisible(true);
    }
}

在上面的应用程序中缩小窗口应该会导致滚动条闪烁。我相信这是由 ScrollPane 对等点的实现中的错误引起的。(来源在这里)我已经复制了我认为有错误的方法(链接中的第 145 行)。

Dimension getChildSize() {
   ScrollPane sp = (ScrollPane)target;
    if (sp.countComponents() > 0) {
        Component c = sp.getComponent(0);
        return c.size();
    } else {
        return new Dimension(0, 0);
    }
}

对我来说,getChildSize() 方法似乎应该调用 c.getPreferredSize() 而不是 c.size()。如果 ScrollPane 子项的大小大于其当前首选大小,它应该能够在不显示滚动条的情况下缩小(在我看来)。为了测试这个理论,我在上面的示例中覆盖了 size() 方法:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.ScrollPane;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Tester implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.setProperty("sun.awt.noerasebackground", "true");
        Tester t = new Tester();
        SwingUtilities.invokeLater(t);
    }

    @SuppressWarnings("serial")
    @Override
    public void run() {
        JFrame frame = new JFrame("Tooltip tester");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 800);
        Canvas c = new Canvas(){
            private Dimension prefSize = new Dimension();
            @Override
            public void paint(Graphics g){
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
            }

            @Override
            public void setPreferredSize(Dimension preferredSize) {
                prefSize = preferredSize;
                super.setPreferredSize(preferredSize);
            }

            @Override
            public Dimension size() {
                return prefSize;
            }
        };
        c.setPreferredSize(new Dimension(400, 400));
        ScrollPane s = new ScrollPane();
        s.add(c);
        frame.add(s);
        frame.setVisible(true);
    }
}

这段代码的行为正是我想要的。然而,重写 size() 方法来做一些文档说它应该做的事情之外的事情并不是解决这个问题的特别优雅的方法。我觉得我一定在这里做错了什么。X11 的 ScrollPane 对等点的一个相当基本的功能是否可能被破坏?

其他一些相关说明:
- 出于我的目的,使用 java.awt.Canvas 是不可协商的。在我的实际应用程序中,我使用 Java AWT Native Interface 非常快速地绘制了一些东西。
-虽然我阅读了有关 Java 7 和 Java 6 更高版本中轻/重兼容性的新改进的文档,但我并没有真正看到任何一种情况的改进,所以我决定坚持使用 awt.ScrollPane 而不是 swing.JScrollPane。无论哪种方式,ScrollPane 都应该在我上面展示的简单案例中正常工作。

4

1 回答 1

1

没有SSCCE很难帮助你,对于未来的读者

然而,实际上,在调整大小操作发生时,两个滚动条似乎都会闪烁,甚至可能会持续到操作完成后的下一次重绘

  • 使用过的 LCD/LED 面板导致那些闪烁(包括 MsExcell,例如,顺便说一句,多次讨论),

  • 对于带有 JScrollPane 的 Swing JFrame,同样的闪烁

  • 不在 CRT 或等离子显示器上显示

  • 如果您在 PC 上播放全高清视频,那么每个好的多媒体播放器都等到调整大小结束,然后将可用空间填充到其容器中


  • 您必须添加 ComponentListener,将 Swing Timer 放在那里,延迟很小(KMPlayer 显示 350-500 毫秒),直到调整大小继续调用 Timer#restart,

  • Canvas 是 CAD / CAM、OpenGL(CL) 的好解决方法,好的 Java 视频播放器基于 AWT

  • 您必须避免将 Swing Container 与 AWT 内容混合,让一切都基于 AWT(未装饰的容器)

于 2012-06-26T18:44:04.253 回答