【问题标题】:Scrollable JPanel in a CardLayout?CardLayout中的可滚动JPanel?
【发布时间】:2014-05-12 18:24:51
【问题描述】:

我一直在寻找一种将垂直滚动条添加到JPanel 的方法,该滚动条又添加到CardLayout 面板中。我查看了所有与实现可滚动JPanel 相关的帖子,但我不知道如何使用这个特定的CardLayout 来实现它。 Oracle 也没有给出我可以使用的示例。

也许我没有为JWindow 或我使用的任何其他组件使用正确的配置。

我已将我的程序的精简版本放在我想为其实现垂直滚动条的下方。

我的问题是如何在代码底部实现JPanelScrollable类,使其可以滚动?

import javax.swing.*;

import java.awt.*;

import java.net.URL ;


public class Program2 extends JFrame
{
    public Program2()
    {
        super("Flash CC");
        Container2 container = new Container2();
        setSize(700, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setFocusable( true ) ;
        add(container);

        setVisible(true) ; 
    }


    public static void main(String[] args)
    {
        Program2 prog = new Program2();
    }
}

class Container2 extends JPanel
{
    private CardLayout          cardLayout   = new CardLayout() ;
    private JPanel1             jPanelFirst  = new JPanel1() ;
    private JPanel2             jPanelSecond = new JPanel2() ;
    private JPanelScrollable    jPanelThird  = new JPanelScrollable() ;

    //Constructor
    Container2()
    {
        this.setLayout( cardLayout )   ;
        this.setFocusable( true ) ;

        JScrollPane scrollFrame = new JScrollPane(jPanelThird);

        this.add( jPanelFirst,  "first card" )  ;
        this.add( jPanelSecond, "second card" ) ;
        this.add( scrollFrame , "third card" ) ;

        cardLayout.show( this, "third card" ) ;
    }
}

class JPanel1 extends JPanel
{

}

class JPanel2 extends JPanel
{

}

class JPanelScrollable extends JPanel
{
    // here many, many, many elemnts will go 
    // and a vertical scroll barr is needed to   view'm all.
    JPanelScrollable()
    {
        this.setOpaque( true ) ;
        this.setLayout( null ) ;
        for(int i=0; i<30; i++)
        {
            JButton b = new JButton("Button" + i) ;
            b.setBounds(0, (i * 100), 100, 50) ;
            this.add(b) ;
        }

    }
}

【问题讨论】:

    标签: java swing user-interface layout cardlayout


    【解决方案1】:

    将面板添加到 JScrollPane

    JScrollPane scrollPane = new JScrollPane(jPanelThird);
    

    将滚动窗格添加到 CardLayout

    this.add(scrollPane, "third card");
    

    详情请见How to use scroll panes

    更新了工作示例

    import java.awt.BorderLayout;
    import java.awt.CardLayout;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class TestCardLayout {
    
        public static void main(String[] args) {
            new TestCardLayout();
        }
    
        private int index = 0;
    
        public TestCardLayout() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    final CardLayout cl = new CardLayout();
                    final JPanel cardPane = new JPanel(cl);
                    cardPane.add(new JLabel("Hello"), "1");
                    cardPane.add(new JScrollPane(createForm()), "2");
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(cardPane);
                    frame.setSize(200, 200);
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
    
                    JButton next = new JButton("Next");
                    next.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            index++;
                            if (index > 1) {
                                index = 0;
                            }
                            if (index == 0) {
                                cl.show(cardPane, "1");
                            } else { 
                                cl.show(cardPane, "2");
                            }
                        }
                    });
                    frame.add(next, BorderLayout.SOUTH);
                }
    
            });
        }
    
        public JPanel createForm() {
            JPanel form = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            for (int index = 0; index < 100; index++) {
                form.add(new JTextField(10), gbc);
            }
            return form;
        }
    }
    

    【讨论】:

    • 谢谢我正在尝试这个选项,我之前也看到过这个链接没有用。
    • 对我来说很好用,记住,直到你将组件设置为大于可视空间的大小,滚动条才会显示
    • 感谢您的宝贵时间,很遗憾我仍然无法修复它。我已经更新了代码以显示我在做什么,但没有成功。如果您能仔细查看并告诉我其中是否有错误,我将不胜感激。谢谢。
    • 我还实现了一些按钮,以防你想运行它。
    • @twimB 你不应该使用this.setLayout( null ) ;,JScrollPane 取决于视图组件的首选大小来确定组件是否超出可视区域
    【解决方案2】:

    Container.add(...) 方法接受任何组件。 CardLayout 不限于面板。

    将面板添加到 JScrollPane 并将滚动窗格添加到卡片布局。

    【讨论】:

    • @twimB, I have also implemented some buttons in case you'd like to run it - 不要使用空布局。只有当您添加到滚动窗格的组件的首选大小大于滚动窗格的大小时,滚动条才会出现。当您使用空布局时,面板的首选大小为 0。
    【解决方案3】:

    如果您使用的是 eclipse,请考虑使用WindowBuilder。它是免费的,您可以通过拖放和更改某些属性来做您需要的事情。

    【讨论】:

      猜你喜欢
      • 2012-10-21
      • 2010-11-26
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多