【问题标题】:My JScrollPane won't scroll vertically over my JPanel我的 JScrollPane 不会在我的 JPanel 上垂直滚动
【发布时间】:2017-03-29 23:58:48
【问题描述】:

我有一个代码,其中有很多“嵌套”布局。 Border、Flow 和在我的主程序中我有一个 GridBag。我将面板动态添加到一个面板,并调整其大小,以便垂直添加每个元素,但不会向上或向下滚动。我在网上看了看,发现了类似的东西,但这只允许我水平滚动,而不是像我想要的那样垂直滚动。这是我写的测试代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Main {

    public Main() {
        JFrame frame = new JFrame("Blah");

        Font font = new Font("Sans-Serif", Font.BOLD, 30);

        JPanel memoryPanel = new JPanel();
        memoryPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        //memoryPanel.setPreferredSize(new Dimension(80 * 4, 55 * 9));

        JScrollPane s = new JScrollPane(memoryPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9));

        for (int i = 0; i <= 10; i++) {

            JPanel nextPanel = new JPanel();
            nextPanel.setLayout(new BorderLayout());
            nextPanel.setBackground(Color.CYAN);
            nextPanel.setForeground(Color.BLACK);

            JPanel labelPanel = new JPanel();
            labelPanel.setLayout(new BorderLayout());

            JPanel buttonPanel = new JPanel();
            buttonPanel.setLayout(new FlowLayout(FlowLayout.TRAILING, 0, 0));

            JLabel label = new JLabel();
            label.setText("" + i);
            label.setPreferredSize(new Dimension(80 * 4, 55));
            label.setHorizontalAlignment(JLabel.RIGHT);
            label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));

            JButton button1 = new JButton("A");
            JButton button2 = new JButton("B");
            JButton button3 = new JButton("C");

            label.setFont(font);
            labelPanel.add(label);

            buttonPanel.add(button1);
            buttonPanel.add(button2);
            buttonPanel.add(button3);

            nextPanel.add(labelPanel, BorderLayout.PAGE_START);
            nextPanel.add(buttonPanel, BorderLayout.PAGE_END);

            memoryPanel.add(nextPanel, 0);
            memoryPanel.revalidate();
            memoryPanel.repaint();
        }
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(s);
        frame.setResizable(false);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Main();
    }
}

使用该注释行,它显示水平滚动条。没有评论,它不显示任何内容。不确定我是否使用错误的布局,但我已经尝试修复它几个小时。我添加的行是s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9));,这使所有内容都水平而不是垂直。不知道如何解决这个问题。有什么建议吗?

【问题讨论】:

  • s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9)); 是错误的尝试和改变。 viewport 显示“视图”的一部分,它的大小实际上应该是 JScrollPane 的大小(减去滚动条)
  • 我也会摆脱 frame.setResizable(false);memoryPanel.setPreferredSize(new Dimension(80 * 4, 55 * 9)); 并让窗口真正将其自身包装在内容周围

标签: java swing jpanel scrollbar jscrollpane


【解决方案1】:

首先摆脱s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9));。您不想更改视口的大小,它是您内容的容器,并充当显示组件可见部分的“窗口”。

接下来,去掉 frame.setResizable(false);,这将允许 pack 实际打包内容周围的窗口。因为您使用的是FlowLayout,这往往会使窗口与屏幕一样宽。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class Main {

    public Main() {
        JFrame frame = new JFrame("Blah");

        Font font = new Font("Sans-Serif", Font.BOLD, 30);

        JPanel memoryPanel = new JPanel();
        memoryPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        //memoryPanel.setPreferredSize(new Dimension(80 * 4, 55 * 9));

        JScrollPane s = new JScrollPane(memoryPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        //        s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9));

        for (int i = 0; i <= 10; i++) {

            JPanel nextPanel = new JPanel();
            nextPanel.setLayout(new BorderLayout());
            nextPanel.setBackground(Color.CYAN);
            nextPanel.setForeground(Color.BLACK);

            JPanel labelPanel = new JPanel();
            labelPanel.setLayout(new BorderLayout());

            JPanel buttonPanel = new JPanel();
            buttonPanel.setLayout(new FlowLayout(FlowLayout.TRAILING, 0, 0));

            JLabel label = new JLabel();
            label.setText("" + i);
            label.setPreferredSize(new Dimension(80 * 4, 55));
            label.setHorizontalAlignment(JLabel.RIGHT);
            label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));

            JButton button1 = new JButton("A");
            JButton button2 = new JButton("B");
            JButton button3 = new JButton("C");

            label.setFont(font);
            labelPanel.add(label);

            buttonPanel.add(button1);
            buttonPanel.add(button2);
            buttonPanel.add(button3);

            nextPanel.add(labelPanel, BorderLayout.PAGE_START);
            nextPanel.add(buttonPanel, BorderLayout.PAGE_END);

            memoryPanel.add(nextPanel, 0);
            memoryPanel.revalidate();
            memoryPanel.repaint();
        }
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(s);
        //        frame.setResizable(false);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Main();
            }
        });
    }
}

如果你想影响可滚动视图区域的大小,那么你需要创建一个实现Scrollable接口的自定义类,并根据你的需要返回适当的值

【讨论】:

  • frame.setResizablepack()的功能无关;它只是确定最终用户是否可以调整窗口大小。
  • @VGR 真的,那么为什么窗口的大小超出了我的屏幕大小,并且在设置时不显示滚动条,而在设置时不显示滚动条,调整为我的屏幕宽度并显示滚动条......巧合;) - 就个人而言,我避免setResizable,它会导致更多问题然后解决
  • @VGR 使用setResizable(false) 帧大小为3524x110,没有它,帧大小为1920x110 - 所以我想说,setResizable 会影响pack 的工作方式
  • 我看到了同样的事情。不是 setResizable 影响 pack() 本身,而是窗口管理器对可调整大小的窗口的处理方式不同。
  • @VGR 简短回答,不要使用setResizable ;) - 代码很痛苦:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 2012-11-08
  • 2016-09-03
相关资源
最近更新 更多