java JPanel,动态地向它添加组件和JScrollPane

时间:2014-08-19 02:19:07

标签: java swing jpanel jscrollpane

我们一直在试验这个,但没有运气,请注意我可能使用错误的组件...... 我们有JFrame一个JPanel,其中包含一个JScrollPane,其中包含另一个JPanel,名为interiorPanel。 如果JButton有一个动作,可以动态地将组件添加到最里面的面板,然后调用它的revalidate()方法,interiorPanel就像我们需要在JScrollPane内部一样增长,显示如下滚动条:

the desired case

但是,我们希望使用循环添加组件而不是使用按钮。使用这个循环:

for (int i = 1; i < 10; i++) {
    demo.getPanelInterior().add(new JButton("Hello"));
    demo.getPanelInterior().revalidate();
    demo.getPanelInterior().repaint();
}

似乎没有像我们点击按钮那样工作,因为最里面的面板增长,但滚动条没有显示,所以我们以这样的结束:

undesired effect

我们应该怎样做才能从第一张图片中获得结果?这是工作示例代码:

    import java.awt.*;
    import java.awt.event.*;

    import javax.swing.*;


    public class Demo extends JPanel {

        private JPanel exteriorPanel;
        private JPanel interiorPanel;
        private JButton button;
        private JList<String> list;
        private String[] imageNames = { "Bird", "Cat", "Dog", "Rabbit", "Pig", "dukeWaveRed",
        "kathyCosmo", "lainesTongue", "left", "middle", "right", "stickerface"};
        private DefaultListModel<String> model;



        public Demo() {

            //Create the list of images and put it in a scroll pane.

            model = new DefaultListModel<>();
            for (String s : imageNames) {
                model.addElement(s);
            }

            list = new JList<String>(model);
            list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            list.setSelectedIndex(0);

            JScrollPane listScrollPane = new JScrollPane();
            listScrollPane.setViewportView(list);

            button = new JButton("Add element");
            button.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    buttonActionPerformed(e);
                }
            });

        interiorPanel = new JPanel();
        interiorPanel.add(listScrollPane);
        interiorPanel.add(button);
        interiorPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));

        JScrollPane anotherScroll = new JScrollPane();
        anotherScroll.setViewportView(interiorPanel);

        exteriorPanel = new JPanel();
        exteriorPanel.add(anotherScroll);
        exteriorPanel.setPreferredSize(new Dimension(400, 200));

        interiorPanel.setBackground(new Color(255, 0, 0));


    }

    private void buttonActionPerformed(ActionEvent e) {
        model.addElement("Hola");
        interiorPanel.add(new JButton("Hello"));
        interiorPanel.revalidate();
    }

    //Used by SplitPaneDemo2
    public JList getImageList() {
        return list;
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {

        //Create and set up the window.
        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Demo demo = new Demo();
        frame.getContentPane().add(demo.getExteriorPanel());

        //Display the window.
        frame.pack();
        frame.setVisible(true);

        for (int i = 1; i < 10; i++) {
            demo.getPanelInterior().add(new JButton("Hello"));
            demo.getPanelInterior().revalidate();
            demo.getPanelInterior().repaint();
        }


    }

    public JPanel getExteriorPanel() {
        return exteriorPanel;
    }

    public JPanel getPanelInterior() {
        return interiorPanel;
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }


}

提前致谢

1 个答案:

答案 0 :(得分:2)

(主要)问题与exteriorPanel使用FlowLayout有关,这允许它扩展以满足JScrollPane的要求,将尝试使用它的首选大小作为它自己的布局计算的基础...这将产生你所看到的结果。实际上,即使使用&#34;单击按钮&#34;,如果您尝试调整窗口大小,也会发生这种情况......

相反,请尝试更改exteriorPanel的布局管理器,例如......

exteriorPanel = new JPanel(new BorderLayout());

这将强制滚动窗格满足父容器的要求,然后允许视图溢出其边界并显示滚动条......

Using a border layout

您还应该阅读Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?