添加一个JPanel数组时,JScrollPane不显示滚动条

时间:2016-03-05 18:48:44

标签: java swing

我在JScrollPane中添加了一个JPanel数组。 JPanels数组被添加到JScrollPane,但滚动条不会显示。

public class MyFrame extends JFrame {

    private JPanel contentPane;
    private JPanel panel_1;
    private JScrollPane scrollPane;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MyFrame frame = new MyFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public MyFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 288, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        panel_1 = new JPanel();
        panel_1.setBounds(10, 114, 434, 136);
        panel_1.setLayout(null);

        scrollPane = new JScrollPane(panel_1);
        scrollPane.setBounds(52, 57, 164, 126);
        scrollPane.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Histogram", TitledBorder.LEADING, TitledBorder.TOP, null, Color.BLUE));
        scrollPane.setLayout(new ScrollPaneLayout());
        contentPane.add(scrollPane);

        buildBar();
    }

    JPanel[] barPanel;
    private void buildBar(){
        int x=0,y=22,w=100,h=80,s=10,n=3;   
        barPanel = new JPanel[n];
        for(int i=0; i<n; i++){
            barPanel[i] = new JPanel();
            barPanel[i].setBounds(x, y, w, h);
            barPanel[i].setBackground(new Color(255,0,0));
            panel_1.add(barPanel[i]);
            panel_1.revalidate();
            panel_1.repaint();
            x = x + w + s;
        }
    }
}

我一直在努力工作几个小时。也许有一些我错过了。

2 个答案:

答案 0 :(得分:2)

你用这两条线射击自己:

    panel_1.setBounds(10, 114, 434, 136);
    panel_1.setLayout(null);

这两个都会破坏JScrollPane使用和显示滚动条的能力。你需要做的是:不要使用setBounds,而是让组件使用他们的preferredSize,并避免使用null布局,因为这不会改变容器的preferredSize。

另一个理所当然地避免空布局的原因。

如,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.*;

public class MyPanel2 extends JPanel {
    private static final int PREF_W = 388;
    private static final int PREF_H = PREF_W;
    public static final int INNER_PREF_W = 434;
    public static final int INNER_PREF_H = 126;
    private static final int HISTO_PANEL_COUNT = 6;
    private static final Dimension VP_SZ = new Dimension(164, 126);
    private JPanel holderPanel = new JPanel(new GridLayout(0, 1));

    public MyPanel2() {
        int w = INNER_PREF_W;
        int h = INNER_PREF_H;
        for (int i = 0; i < HISTO_PANEL_COUNT; i++) {
            holderPanel.add(new InnerPanel(w, h));
        }

        JScrollPane scrollPane = new JScrollPane(holderPanel);
        scrollPane.getViewport().setPreferredSize(VP_SZ);

        setLayout(new GridBagLayout());
        add(scrollPane);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private class InnerPanel extends JPanel {
        private int w;
        private int h;

        public InnerPanel(int w, int h) {
            this.w = w;
            this.h = h;
            setBorder(BorderFactory.createLineBorder(Color.BLUE));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int x = 0, y = 22, w = 100, h = 80, s = 10, n = 3;
            g.setColor(Color.RED);
            for (int i = 0; i < n; i++) {
                g.fillRect(x, y, w, h);
                x = x + w + s;
            }
        }

        @Override
        public Dimension getPreferredSize() {
            if (isPreferredSizeSet()) {
                return super.getPreferredSize();
            }
            return new Dimension(w, h);
        }
    }

    private static void createAndShowGui() {
        MyPanel2 mainPanel = new MyPanel2();

        JFrame frame = new JFrame("MyPanel2");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            createAndShowGui();
        });
    }
}

答案 1 :(得分:2)

JScrollPane依赖于容器的preferredSize来确定滚动条的宽度。如果使用布局,则在将组件添加到面板时将为您确定preferredSize。

但是,当你使用:

contentPane.setLayout(null);

您正在阻止preferredSize根据添加的组件进行更改。

尝试使用适用于您的情况的布局。

如果您确定不想使用布局,为了查看滚动条,您可以为 手动添加的每个组件设置容器的preferredSize 调整preferredSize。这样,滚动条仍将使用新添加的组件进行扩展。