java - JScrollPane 不起作用,视口(viewport)正在堆叠面板

标签 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

感谢任何帮助!谢谢

最佳答案

问题是:您正在使用 null 布局,这是 JScrollPanes 无法处理的布局,一般情况下应该避免这种布局。摆脱这个:

// setLayout(null);

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

虽然 null 布局和 setBounds() 对于 Swing 新手来说似乎是创建复杂 GUI 的最简单、最好的方法,但您创建的 Swing GUI 越多,使用它们时遇到的困难就越严重。当 GUI 调整大小时,它们不会调整组件的大小,它们是增强或维护的皇家女巫,当放置在滚动 Pane 中时它们完全失败,当在与原始平台或屏幕分辨率不同的所有平台或屏幕分辨率上查看时,它们看起来非常糟糕.

了解布局管理器。

然后使用它们。

例如:

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;
    }

}

关于java - JScrollPane 不起作用,视口(viewport)正在堆叠面板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41625945/

相关文章:

ios - 不确定如何模仿所需的 UI 功能

java - 使用 Scanner 填充对象的 ArrayList

java - java中treemap数据结构除了排序和排序之外的优点

java - 我应该缓冲 InputStream 还是 InputStreamReader?

user-interface - 将文档构建到软件中

javascript - Kendo UI-数据显示问题

java - 有没有办法将字母形式的数字字符串数组转换为数字形式?

java - JPanel闪烁

java - 扩展 JPanel 在添加到另一个 JPanel 时显示很小

java - 使用另一个类的 ArrayList 填充 JComboBox