JScrollPane无法正常工作,视口正在堆叠面板

时间:2017-01-13 01:20:37

标签: java swing user-interface jscrollpane viewport

这是运行程序的类。

import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class runClass {

public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setSize(1366, 768);
    frame.setVisible(true);

    JPanel backgroundPanel = new JPanel();
    backgroundPanel.setBounds(0, 0, 1366, 768);
    backgroundPanel.setBackground(Color.PINK);
    frame.getContentPane().add(backgroundPanel);

    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(0,1,10,10));

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBounds(228, 5, 453, 426);
    scrollPane.setViewportView(panel);
    scrollPane.setVisible(true);
    backgroundPanel.setLayout(null);
    backgroundPanel.add(scrollPane);

    for (int x = 0; x < 15; x++){
        panel.add(new ExerciseList(new Exercise("hello")));
    }

    panel.revalidate();
    panel.repaint();

}
}

这是要添加到容器中的面板。

import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Font;

public class ExerciseList extends JPanel{

    private Exercise exercise;

    public ExerciseList(Exercise e){

        this.exercise = e;

        setLayout(null);
        setVisible(true);
        setBackground(Color.LIGHT_GRAY);

        JLabel lblName = new JLabel(exercise.getName());
        lblName.setFont(new Font("Tahoma", Font.PLAIN, 18));
        lblName.setBounds(229, 11, 209, 22);
        add(lblName);

    }
}

这是用于检索ExerciseList信息的练习类。

public class Exercise {

    private String name;

    public Exercise(String name) {
        super();
        this.name = name;

    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

这是我正在获取的ExerciseList堆叠的图像。

As you can see, the ExerciseList panels are overlapping, rather than the JScrollPane allowing me to scroll

任何帮助表示赞赏!感谢

1 个答案:

答案 0 :(得分:3)

问题在于:您正在使用null布局,这是JScrollPanes无法处理的布局,作为一般规则应该避免使用。摆脱这个:

// setLayout(null);

你的问题就消失了。为什么这是个问题?容器的布局管理器及其组件都有助于确定容器及其组件的首选大小。如果使用null布局,则不会发生这种情况,因此视口的视图(JScrollPane持有的JPanel)将不会像添加更多组件时那样扩展。

虽然null布局和setBounds()似乎是Swing新手,比如创建复杂GUI的最简单和最好的方法,但是你创建的Swing GUI越多,使用它们时会遇到更严重的困难。当GUI调整大小时,它们不会调整组件的大小,它们是增强或维护的皇室女巫,当它们被放置在滚动窗格中时它们完全失败,当它们在所有平台上观看时或者与原始平台不同的屏幕分辨率时它们看起来很糟糕

了解布局管理器。

然后使用它们。

例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

@SuppressWarnings("serial")
public class ExerciseDemo extends JPanel {
    private static final int PREF_W = 500;
    private static final int PREF_H = 450;
    protected static final int MAX_COUNTER = 30;
    private JPanel exerciseHolder = new JPanel(new GridLayout(0, 1));

    public ExerciseDemo() {
        JPanel wrapperPanel = new JPanel(new BorderLayout());
        wrapperPanel.add(exerciseHolder, BorderLayout.PAGE_START);
        JScrollPane scrollPane = new JScrollPane(wrapperPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        setLayout(new BorderLayout());
        add(scrollPane);

        new Timer(300, new ActionListener() {
            int counter = 0;

            @Override
            public void actionPerformed(ActionEvent e) {
                counter++;
                exerciseHolder.add(new ExerciseList2(new Exercise("John Smith " + counter)));
                exerciseHolder.revalidate();
                exerciseHolder.repaint();
                if (counter > MAX_COUNTER) {
                    ((Timer) e.getSource()).stop();
                }
            }
        }).start();

    }

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

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

        JFrame frame = new JFrame("ExerciseDemo");
        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());
    }
}

@SuppressWarnings("serial")
class ExerciseList2 extends JPanel {
    private static final Font NAME_FONT = new Font("Tahoma", Font.PLAIN, 18);
    private Exercise exercise;

    public ExerciseList2(Exercise exercise) {
        this.exercise = exercise;

        JLabel lblName = new JLabel(exercise.getName());
        lblName.setFont(NAME_FONT);

        setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        setLayout(new BorderLayout(15, 0));
        add(new JCheckBox("Check Box"), BorderLayout.LINE_START);
        add(lblName, BorderLayout.CENTER);
        add(new JButton("Button"), BorderLayout.LINE_END);
    }    

    public Exercise getExercise() {
        return exercise;
    }

}