【问题标题】:How to get horizontal scroll bars in JScrollPane如何在 JScrollPane 中获取水平滚动条
【发布时间】:2012-11-06 22:48:16
【问题描述】:

我有一个似乎无法解决的面板布局问题。我有以下代码:

public class Test extends ApplicationFrame {
    public Test(String title) {
        super(title);

        JPanel jpanel = new JPanel();
        jpanel.setPreferredSize(new Dimension(100 * 2, 300));
        jpanel.setBackground(new Color(0xFF0000));

        JScrollPane scrollPane = new JScrollPane(jpanel);
        scrollPane.setBackground(new Color(0xFF0000));
        scrollPane.getViewport().setPreferredSize(new Dimension(100 * 2, 300));

        this.add(scrollPane, BorderLayout.WEST);
        this.setPreferredSize(new Dimension(500, 500));
    }

    public static void main(String args[]) {
        Test test = new Test("Layout Test");
        test.pack();
        RefineryUtilities.centerFrameOnScreen(test);
        test.setVisible(true);
    }
}

创建以下布局:

当我拖动窗口的右侧并将其移至红色的JPanelJScrollPane 时,我希望水平滚动条出现在JScrollPane 上。但目前窗口只是缩小而不显示水平滚动条。这可能吗?

我想保留BorderLayout.WEST,因为我的用例是在我没有足够大的图表来填满整个窗口时防止 JFreeChart 拉伸。

【问题讨论】:

  • WEST 组件实际上并没有开始水平“压缩”。在这种情况下,我不认为BorderLayout 是你的朋友
  • @MadProgrammer 您对哪个布局管理器有更好的选择有什么建议吗?
  • 我的直觉是GridBagLayout,但我还不相信它会达到你的目的
  • 我认为那些 setXXSize 仅用于演示:-)
  • @kleopatra nope - 纯属无知 setXXSize 不会被使用。我在各个方面都是 java ui 新手。

标签: java swing jpanel jscrollpane jfreechart


【解决方案1】:

many reasons 不使用setPreferredSize(),但这里的关键是所需的结果取决于封闭组件的首选大小。特别是,

  • ChartPanel 具有由JPanel 指定的默认FlowLayout,但图表忽略了这一点并调整以填充可用空间;您可以覆盖getPreferredSize() 以选择任何所需的初始几何形状。

  • JScrollPane 的滚动条仅在视口大小小于内容大小时出现。 BorderLayout.WESTBorderLayout.EAST 不变,所以滚动条永远不会出现。

调用pack() “导致此Window 调整大小以适合其子组件的首选大小和布局。”在下面的示例中,在pack() 之后人为减小了框架的大小,以使滚动条出现。 GridLayout 使两个面板的大小相等。调整框架大小以查看效果。

附录:如果您希望ChartPanel 具有固定大小,请将其添加到JPanel;默认FlowLayout 使用首选大小。

public class ChartPanelTest {

    private static final int N = 64;
    private static final int SIZE = 400;
    private static final Random random = new Random();

    private static XYDataset createDataset() {

        final TimeSeries series = new TimeSeries("Random Data");
        Day current = new Day();
        for (int i = 0; i < N; i++) {
            series.add(current, random.nextGaussian());
            current = (Day) current.next();
        }
        return new TimeSeriesCollection(series);
    }

    private static JFreeChart createChart(final XYDataset dataset) {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Test", "Day", "Value", dataset, false, false, false);
        return chart;
    }

    public static void main(String[] args) {

        JFrame f = new JFrame();
        f.setLayout(new GridLayout(1, 0));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JFreeChart chart = createChart(createDataset());
        f.add(new JScrollPane(new JPanel() {

            {
                setBackground(Color.red);
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(SIZE, SIZE);
            }
        }));
        f.add(new ChartPanel(chart) {

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(SIZE, SIZE);
            }
        });
        f.pack();
        f.setSize(2 * (SIZE - N), SIZE - N);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

【讨论】:

  • 这看起来就是我想要完成的。仍然需要翻译成真正的应用程序,但演示非常有用。谢谢!这也是为 JFreeChart 准备的。 :D
  • 能够成功集成到实际应用中。再次感谢!
  • 优秀;还可以考虑JSplitPane,显示为here
【解决方案2】:

这是可以做到的。你可以声明三个JPanel。 一个 JPanel 是带有 BorderLayout 的 contentPanel。 设置为您想要滚动条的JPanel 的preferedSize 和maximumSize 创建一个 jscroolpane 及其完成: 伪代码:

JPanel contentPanel = new JPanel(new BorderLayuout());
JPanel jpanel1 = new JPanel(layout--);
JPanel jpanel2 = new JPanel(layout--);
jpanel2.setPreferredSize(..);
jpanel2.setMaximuSize(..);
JScrollPane jsp = new JScroolPane(jpanel2);
contentPanel.add(jpanel1,BorderLayout.WEST);
contentPanel.add(jsp,BorderLayout.CENTER);
this.getContentPane().add(contentPanel);

在我的示例中,滚动条位于中心。 如果你想改变

contentPanel.add(jsp,BorderLayout.WEST);
contentPanel.add(jpanel1,BorderLayout.CENTER);

【讨论】:

  • -1 for setXXSize - 出于这样做的原因,请参阅@trashgod 的答案中的参考
猜你喜欢
  • 2013-12-20
  • 2015-06-19
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多