在显示滚动条之前将内容缩小到minSize

时间:2015-03-13 11:35:43

标签: java swing jscrollpane

我想要实现的是,在内容缩小到最小尺寸后,JScrollPane会显示滚动条。滚动条显示后,面板应具有最小尺寸。 我可以实现的最接近的事情是在jpanel上实现Scrollable并覆盖getScrollableTracksViewportHeight和getScrollableTracksViewportWidth方法。

public class EditPanel extends JPanel implements Scrollable {

    @Override
    public Dimension getPreferredScrollableViewportSize() {
        return super.getPreferredSize();
    }

    @Override
    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
        return 16;
    }

    @Override
    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
        return 16;
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return this.getMinimumSize().width < this.getWidth();
    }

    @Override
    public boolean getScrollableTracksViewportHeight() {
        return this.getMinimumSize().height < this.getHeight();
    }
}

然而,当内容缩小到最小尺寸以下时,这会导致滚动条闪烁。

如果没有滚动条闪烁,我怎么能实现这一目标? 这是我用来测试这个的代码:

public class Main {
    public static void main(String[] args) {
        JFrame f = new JFrame();
        JScrollPane sp = new JScrollPane();
        EditPanel p = new EditPanel();
        p.setMinimumSize(new Dimension(200, 200));
        p.setPreferredSize(new Dimension(500, 500));
        p.setBackground(Color.white);

        sp.setViewportView(p);
        f.setContentPane(sp);

        f.pack();
        f.setVisible(true);
    }
}

1 个答案:

答案 0 :(得分:1)

您希望根据视口的大小进行比较,而不是面板:

@Override
public boolean getScrollableTracksViewportWidth() {
    //return this.getMinimumSize().width < this.getWidth();
    return this.getMinimumSize().width < getParent().getWidth();
}

@Override
public boolean getScrollableTracksViewportHeight() {
    //return this.getMinimumSize().height < this.getHeight();
    return this.getMinimumSize().height < getParent().getHeight();
}

编辑:

  

当滚动条显示时,EditPanels大小将是首选大小而不是最小大小。

滚动条基于视口中组件的首选大小。因此,您还需要动态管理首选大小。也许是这样的:

@Override
public Dimension getPreferredSize()
{
    Dimension preferredSize = super.getPreferredSize();
    Component parent = getParent();

    if (parent == null)
        return preferredSize;

    Dimension parentSize = parent.getSize();
    Dimension minimumSize = getMinimumSize();

    int width = Math.min(preferredSize.width, parentSize.width);
    width = Math.max(width, minimumSize.width);

    int height = Math.min(preferredSize.height, parentSize.height);
    height = Math.max(height, minimumSize.height);

    return new Dimension(width, height);
}