【问题标题】:Java Swing JScrollPane Containing more Panes not Scrolling?Java Swing JScrollPane 包含更多不滚动的窗格?
【发布时间】:2015-09-01 06:00:08
【问题描述】:

对不起,如果这是一个愚蠢的问题,我对 Java swing UI 很陌生。 我正在尝试开发一个程序来获取我的 Steam 成就,并且我有它的基本代码,但现在我想为它创建一个 UI。

下面的代码是 UiHandler 类,还有很多其他的,但是它们与这个问题无关。这个类基本上只给出了两个对话框,询问用户和应用程序 ID,然后应该给出一个包含所有成就和值的滚动框。相反,列表会在没有任何滚动选项的情况下离开屏幕。

问题是我的 scrollPanel(在 mainPanel 内)似乎没有滚动(它的侧面没有滚动条,滚轮什么也不做)。我希望 scrollPanel 的内容(它是面板,具有存储在地图中的所有成就的列表)会滚动。

这是我第一次使用滚动面板,所以我真的不知道我在做什么......

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.WindowEvent;
import java.util.Iterator;
import java.util.Map;

import javax.swing.*;

@SuppressWarnings("serial")
public class UserInterface extends JFrame {

public UserInterface() {
    initUI();
}

@SuppressWarnings("unchecked")
private void initUI() {

    UserInteractionHandler uiHandler = new UserInteractionHandler();

    setTitle("Steam Stats");
    setSize(500, 400);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    JPanel panel = new JPanel(new GridLayout(0, 1));

    JLabel header = new JLabel("Steam Stats", SwingConstants.CENTER);
    header.setFont(new Font("trebuchet ms", Font.BOLD, 20));
    panel.add(header);


    String userId = JOptionPane.showInputDialog("Steam ID 64");
    String appId = JOptionPane.showInputDialog("App Id of Game");

    Map<String, Integer> allAchievements = uiHandler.getAllAchievements(appId, userId);

    @SuppressWarnings("rawtypes")
    Iterator it = allAchievements.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<String, Integer> pair = (Map.Entry<String, Integer>) it.next();

        JLabel key = new JLabel(pair.getKey());
        JLabel value = new JLabel(pair.getValue().toString());
        panel.add(key);
        panel.add(value);

        it.remove();
    }

    JScrollPane scrollPanel = new JScrollPane(panel);

    JPanel mainPanel = new JPanel(new GridLayout(0, 1));
    mainPanel.add(scrollPanel);

    getContentPane().add(mainPanel, BorderLayout.NORTH);



}

public static void runUi() {

    EventQueue.invokeLater(new Runnable() {
        public void run() {
            UserInterface ui = new UserInterface();
            ui.setVisible(true);
        }
    });
}
}

这是生成的窗口的屏幕截图: http://puu.sh/jVsto/4a4bcbdf6e.png

感谢您的帮助。 垫子

【问题讨论】:

    标签: java swing scroll jscrollpane


    【解决方案1】:

    您的问题是您正在添加 JScrollPane BorderLayout.NORTH,并且正在设置 GUI 的大小。这会将 GUI 限制在一定的大小,但不会限制 BorderLayout.NORTH 组件的大小,因此它将与显示 JScrollPane 视口的全部内容所需的一样大,无论是在小 GUI 中。

    可能的解决方案:

    • 如果您将 JScrollPane 添加到 BorderLayout.CENTER 位置,它实际上会起作用。
    • 如果可能,您会希望避免设置任何内容的大小。
    • 您可以限制 JScrollPane 视口的 preferredSize
    • 我最喜欢的解决方案:在 JScrollPane 中使用 JList 来显示数据,并通过 setVisibleRowCount(...) 指定列表的可见行数。

    例如:

    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.event.WindowEvent;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class UserInterface extends JFrame {
    
        public UserInterface() {
            initUI();
        }
    
        @SuppressWarnings("unchecked")
        private void initUI() {
    
            UserInteractionHandler uiHandler = new UserInteractionHandler();
    
            setTitle("Steam Stats");
            // !! setSize(500, 400);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    
            JPanel panel = new JPanel(new GridLayout(0, 1));
    
            JLabel header = new JLabel("Steam Stats", SwingConstants.CENTER);
            header.setFont(new Font("trebuchet ms", Font.BOLD, 20));
            panel.add(header);
    
            String userId = JOptionPane.showInputDialog("Steam ID 64");
            String appId = JOptionPane.showInputDialog("App Id of Game");
    
            Map<String, Integer> allAchievements = uiHandler.getAllAchievements(
                    appId, userId);
    
            DefaultListModel<MyPair> listModel = new DefaultListModel<>();
            JList<MyPair> pairList = new JList<>(listModel);
            pairList.setCellRenderer(new MyPairRenderer());
            pairList.setVisibleRowCount(20);
    
            @SuppressWarnings("rawtypes")
            Iterator it = allAchievements.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, Integer> pair = (Map.Entry<String, Integer>) it
                        .next();
    
                MyPair myPair = new MyPair(pair.getKey(), pair.getValue());
                listModel.addElement(myPair);
    
                it.remove();
            }
    
            //!! JScrollPane scrollPanel = new JScrollPane(panel);
            JScrollPane scrollPanel = new JScrollPane(pairList);
    
            JPanel mainPanel = new JPanel(new BorderLayout());
            mainPanel.add(header, BorderLayout.PAGE_START);
            mainPanel.add(scrollPanel);
    
            getContentPane().add(mainPanel, BorderLayout.PAGE_START);
            pack(); // !!
    
        }
    
        public static void runUi() {
    
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    UserInterface ui = new UserInterface();
                    ui.setVisible(true);
                }
            });
        }
    
        public static void main(String[] args) {
            UserInterface.runUi();
        }
    }
    
    class MyPair {
        private String name;
        private int value;
        public MyPair(String name, int value) {
            this.name = name;
            this.value = value;
        }
    
        public String getName() {
            return name;
        }
    
        public int getValue() {
            return value;
        }
    
    }
    
    class MyPairRenderer implements ListCellRenderer<MyPair> {
        private JPanel panel = new JPanel(new GridLayout(1, 2, 5, 5));
        private JLabel nameLabel = new JLabel();
        private JLabel valueLabel = new JLabel();
    
        public MyPairRenderer() {
            panel.add(nameLabel);
            panel.add(valueLabel);
        }
    
        @Override
        public Component getListCellRendererComponent(JList<? extends MyPair> list,
                MyPair value, int index, boolean isSelected, boolean cellHasFocus) {
            if (value != null) {
                nameLabel.setText(value.getName());
                valueLabel.setText("" + value.getValue());
            }
            return panel;
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 1970-01-01
      • 2018-02-03
      相关资源
      最近更新 更多