0

我目前陷入关于 JScrollPane 和子组件的两难境地。本质上,我需要严格控制 JScrollPane 中子组件的大小调整,以便它锁定到 JScrollPane 的大小(以便不出现滚动条)或保持固定到预定义的大小(并让 JScrollPane 在适当时显示滚动条) . 此控件必须能够动态切换(特别是通过来自另一个 JFrame 窗口的切换框)。JScrollPane 被定向锁定到父 JFrame 窗口(完全填充它并通过 BorderLayout 锁定到其调整大小)。

目前我使用 Canvas 对象作为 JScrollPane 的子组件,因为它具有三重缓冲功能 (createBufferStrategy(3);)。我在很多地方都看到 Canvas 和 JScrollPane 不能很好地融合在一起,因此我们非常感谢能够解决上述问题并放弃使用 Canvas 的答案。

我的组件布局如下:

JFrame(自定义类)-> JScrollPane-> Canvas

不确定这是否有帮助,但画布渲染代码如下:

//This is a method from a nested class inside the JFrame class.
public void run() {
    long MaxFrameTime;
    long Time;
            //This is the Canvas Object
    RXDisplayCanvas.createBufferStrategy(3);
    BufferStrategy BS = RXDisplayCanvas.getBufferStrategy();
    Graphics2D G2D;

    while(isVisible()){
        MaxFrameTime = Math.round(1000000000.0 / FPSLimit);
        Time = System.nanoTime();

        //Render Frame from a source from another thread via a AtomicReference<BufferedImage> named 'Ref'
        BufferedImage Frame = Ref.get();
        if(Frame != null){
            G2D = (Graphics2D)BS.getDrawGraphics();

            int X0 = 0;
            int Y0 = 0;
            int W = RXDisplayCanvas.getWidth();
            int H = RXDisplayCanvas.getHeight();
            double Width = Frame.getWidth();
            double Height = Frame.getHeight();
            double ImgW = Width;
            double ImgH = Height;

            if(ImgW > W){
                ImgW = W;
                ImgH = ImgW / (Width / Height);
            }

            if(ImgH > H){
                ImgH = H;
                ImgW = ImgH * (Width / Height);
            }

            int CenterX = (int)Math.round((W / 2.0) - (ImgW / 2.0)) + X0;
            int CenterY = (int)Math.round((H / 2.0) - (ImgH / 2.0)) + Y0;
            G2D.setBackground(Color.BLACK);
            G2D.clearRect(0, 0, W, H);
            G2D.drawImage(Frame, CenterX, CenterY, (int)Math.round(ImgW), (int)Math.round(ImgH), null);

            //Additional Drawing Stuff Here


            G2D.dispose();

            if(!BS.contentsLost()){
                BS.show();
            }
        }

        Time = System.nanoTime() - Time;
        if(Time < MaxFrameTime){
            try{
                Thread.sleep(Math.round((MaxFrameTime - Time)/1000000.0));
            }catch(InterruptedException N){}
        }
    }
}

我当前对我的问题的实现效果不是很好(不与父 JScrollPane '重新锁定';'FixedDim' 是先前设置的维度对象):

/**
 * Sets whether to lock the size of the canvas object to a predefined dimension.
 * @param b If true, the canvas becomes non-resizable and scrollbars will appear when appropriate. 
 * If false, the canvas will resize with the enclosing scrollpane.
 */
public void setLockResize(boolean b){
    CurrentlyLocked = b;
    if(b){
        RXDisplayCanvas.setMinimumSize(FixedDim);
        RXDisplayCanvas.setMaximumSize(FixedDim);
        RXDisplayCanvas.setPreferredSize(FixedDim);
    }else{
        RXDisplayCanvas.setMinimumSize(Min);
        RXDisplayCanvas.setMaximumSize(Max);
        RXDisplayCanvas.setPreferredSize(FixedDim);
    }
}
4

1 回答 1

1

并废弃 Canvas 的使用

Swing 默认情况下是双缓冲的。尝试只使用 JPanel。

我需要严格控制 JScrollPane 中子组件的大小调整,以便它锁定到 JScrollPane 的大小(这样不会出现滚动条)或保持固定到预定义的大小(并让 JScrollPane 在适当的时候显示滚动条)

您也许可以使用Scrollable Panel。对于 ScrollableSizeHint,您可能能够在 NONE 和 FIT 之间切换。

于 2013-06-21T00:37:19.217 回答