简体   繁体   English

JScrollPane不添加组件

[英]JScrollPane doesn't add components

I extend JScrollPane and add several components to it. 我扩展了JScrollPane并向其中添加了几个组件。 When I add scroll pane to JFrame no components are displayed. 当我将滚动窗格添加到JFrame时,不显示任何组件。 In case when my class extends, for example, JPanel and then I add it to a standalone JScrollPane, everything works fine. 如果我的类扩展了(例如,JPanel),然后将其添加到独立的JScrollPane中,则一切正常。 I cannot understand this behaviour. 我无法理解这种行为。 Could anyone explain me, why it happens? 谁能解释我,为什么会发生?

Here are both variants (the one that works and the one that doesn't): 这是两种变体(一种有效,一种无效):

This variant doesn't work: 此变体不起作用:

public class MainScrollPanel extends JScrollPane {

    private JPanel verticalPanel;

    public MainScrollPanel() throws IOException, ParseException {
        initGUI();
        readData();
    }

    private void initGUI() {
        verticalPanel = new JPanel();
        verticalPanel.setLayout(new BoxLayout(verticalPanel, BoxLayout.Y_AXIS));

        add(verticalPanel);
        setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    }

    private void readData() throws IOException, ParseException {
        //read data
        //...
        for(NewData message : messages) {
            verticalPanel.add(new JLabel(message.getMessage()));
        }
    }
}

public class MainGUI extends JFrame {
    private MainScrollPanel mainPanel;

    public MainGUI() throws IOException, ParseException {
        super("Scroll app");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        mainPanel = new MainScrollPanel();
        getContentPane().add(mainPanel);

        setSize(200, 200);
        setVisible(true);
    }

    public static void main(String[] args) throws IOException, ParseException {
        new MainGUI();
    }
}

This one works fine: 这个很好用:

public class MainScrollPanel extends JPanel {

    public MainScrollPanel() throws IOException, ParseException {
        initGUI();
        readData();
    }

    private void initGUI() {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    }

    private void readData() throws IOException, ParseException {
        //The same as in previous example
    }
}

public class MainGUI extends JFrame {
    private MainScrollPanel mainPanel;

    public MainGUI() throws IOException, ParseException {
        //...
        JScrollPane scrollPane = new JScrollPane(mainPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        getContentPane().add(scrollPane);
        //...
    }
}

You probably don't need or want to extend JScrollPane, but regardless, you almost never add components directly to a JScrollPane but rather to its Viewport. 您可能不需要或不想扩展JScrollPane,但是无论如何,您几乎永远不会直接向JScrollPane而是向其视口添加组件。 Else you lose the Viewport and its functionality. 否则,您将失去视口及其功能。

This can be done via the JScrollPane method: setViewportView(Component comp) The other way is to pass the component into the JScrollPane's constructor (or here its super constructor) as this will automatically pass the component to the viewport. 这可以通过JScrollPane方法完成: setViewportView(Component comp)另一种方法是将组件传递到JScrollPane的构造函数(或这里的其超级构造函数)中,因为这将自动将组件传递到视口。 It's a little syntactic sugar is all. 这只是一点语法糖。

eg, 例如,

private void initGUI() {
    verticalPanel = new JPanel();
    verticalPanel.setLayout(new BoxLayout(verticalPanel, BoxLayout.Y_AXIS));

    setViewportView(verticalPanel); // ********** changed *******

    setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM