【问题标题】:How to create a dynamically-sized JScrollPane w/ JPanel as the client?如何使用 JPanel 作为客户端创建动态大小的 JScrollPane?
【发布时间】:2013-05-11 23:58:06
【问题描述】:

在我的代码中,用户可以使用菜单向主 JPanel 添加新按钮。 JPanel 使用 FlowLayout 表单,因此根据窗口的大小,每行上的数字或按钮会发生变化以适应最佳视图......嗯,在我介绍 JScrollPane 之前就是这种情况。现在我有两个问题:

  1. 一旦用户将窗口大小重新调整为首选大小或更低,每行上的按钮数将停止更改。 *以前没有这个问题,即使设置了首选尺寸。

  2. 我只能滚动查看 JPanel 首选大小范围内的按钮。任何放置在外面的东西都是不可见的,也不会增加 JScrollPane 范围的大小。

代码如下:

package testit;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.border.LineBorder;

class TestIt extends JFrame implements ActionListener {
    //Main window frame, content panel and scroll pane
    private JFrame main_frame;
    private JPanel main_panel;
    private JScrollPane main_scroll;

    //Screen size
    private Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();

    public TestIt() {
        //Set up the main frame
        main_frame = new JFrame("Test Program");
        main_frame.setLayout(new BorderLayout());
        main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main_frame.setIconImage(
                new ImageIcon("src/testit/resources/img/app_icon.gif").getImage());

        //Set up the content panel and add it to the scroll pane
        main_panel = new JPanel();
        main_panel.setLayout(new FlowLayout());
        main_panel.setPreferredSize(
                new Dimension(screen.width/10 * 6, screen.height/10 * 6));
        main_scroll = new JScrollPane(main_panel);

        //Add the menu bar and the scroll pane to the main frame
        main_frame.add(main_scroll, BorderLayout.CENTER);       
        main_frame.setJMenuBar(createMenuBar());

        //Display the main GUI
        main_frame.pack();
        main_frame.setLocationRelativeTo(null);
        main_frame.setVisible(true);

    }

    private JMenuBar createMenuBar() {
        //Create the top menu bar
        JMenuBar top_menu_bar = new JMenuBar();

        //Create the menu
        JMenu main_menu = new JMenu ("Menu");
        main_menu.setMnemonic(KeyEvent.VK_M);
        top_menu_bar.add(main_menu);

        //Create the menu items and add them to the menu
        JMenuItem menu_item;

        menu_item = new JMenuItem("Add New");
        menu_item.setMnemonic(KeyEvent.VK_N);
        menu_item.setAccelerator(
                KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.ALT_MASK));
        menu_item.setActionCommand("new");
        menu_item.addActionListener(this);
        main_menu.add(menu_item);

        menu_item = new JMenuItem("Save");
        menu_item.setMnemonic(KeyEvent.VK_S);
        menu_item.setAccelerator(
                KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.ALT_MASK));
        menu_item.setActionCommand("save");
        menu_item.addActionListener(this);
        main_menu.add(menu_item);

        menu_item = new JMenuItem("Exit");
        menu_item.setMnemonic(KeyEvent.VK_X);
        menu_item.setAccelerator(
                KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK));
        menu_item.setActionCommand("exit");
        menu_item.addActionListener(this);
        main_menu.add(menu_item);

        //Return the assembled menu bar
        return top_menu_bar;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (e.getActionCommand()) {
            case "new":
                createThumb();
                break;
            case "save":
                break;
            default:
                quit();
                break;
        }
    }

    private void createThumb() {
        //Width and height for the thumbnail button
        final int H = 170;
        final int W = 150;

        //Set up the thumbnail button
        ImageIcon image = new ImageIcon("src/testit/resources/img/test.gif");       
        JButton thumb = new JButton(image);
        thumb.setMargin(new Insets(0, 0, 0, 0));
        thumb.setBorder(new LineBorder(Color.BLACK));
        thumb.setBackground(Color.BLACK);
        thumb.setPreferredSize(new Dimension(W, H));
        thumb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                openNewFrame();
            }
        });
        main_panel.add(thumb);
        main_panel.validate();
    }

    private void openNewFrame() {
        JFrame new_window = new JFrame();
        new_window.setPreferredSize(new Dimension(400, 800));
        new_window.pack();
        new_window.setLocationRelativeTo(null);
        new_window.setVisible(true);
    }

    private void quit() {
        System.exit(0);
    }

    //Create an instance of the program
    private static void runIt() {
        TestIt program = new TestIt();
    }

    public static void main(String [] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                runIt();
            }
        });
    }
}

我尝试了很多东西,并且一直在研究 Javadoc.... 我已经阅读了很多东西和教程,但仍然无法让我的滚动/调整大小起作用。

【问题讨论】:

    标签: java swing scroll jscrollpane


    【解决方案1】:

    当您设置组件的preferredSize 时,您会固定它的大小,因此它不会在JScrollPane 中展开。一个解决方案是不这样做,不固定容纳 JButton 的容器的大小。

    例如,

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class TestIt2 extends JPanel {
       private static final Dimension THUMB_SIZE = new Dimension(170, 150);
       private Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
       private JPanel thumbPanel = new JPanel(new GridLayout(0, 6, 5, 5));
    
       public TestIt2() {
          JPanel holderPanel = new JPanel(new BorderLayout());
          holderPanel.add(thumbPanel, BorderLayout.NORTH);
          holderPanel.add(Box.createGlue(), BorderLayout.CENTER);
    
          setLayout(new BorderLayout());
          add(new JScrollPane(holderPanel), BorderLayout.CENTER);
       }
    
       public JMenuBar createMenuBar() {
          JMenuBar top_menu_bar = new JMenuBar();
          JMenu main_menu = new JMenu("Menu");
          main_menu.setMnemonic(KeyEvent.VK_M);
          top_menu_bar.add(main_menu);
          JMenuItem menu_item;
    
          menu_item = new JMenuItem("Add New");
          menu_item.setMnemonic(KeyEvent.VK_N);
          menu_item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
                ActionEvent.ALT_MASK));
          menu_item.setActionCommand("new");
          menu_item.addActionListener(new ActionListener() {
    
             @Override
             public void actionPerformed(ActionEvent arg0) {
                createThumb();
             }
          });
          main_menu.add(menu_item);
    
    
          return top_menu_bar;
       }
    
       protected void createThumb() {
          JButton thumb = new JButton("Thumb");
          thumb.setPreferredSize(THUMB_SIZE);
          thumbPanel.add(thumb);
          revalidate();
          repaint();
       }
    
       @Override
       public Dimension getPreferredSize() {
          return new Dimension(screen.width / 10 * 6,
                screen.height / 10 * 6);
       }
    
       private static void createAndShowGui() {
          TestIt2 mainPanel = new TestIt2();
    
          JFrame frame = new JFrame("TestIt2");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.setJMenuBar(mainPanel.createMenuBar());
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    【讨论】:

    • 我喜欢!然而,一个问题是当我增加窗口的宽度时,它会增加按钮的宽度。这是由于 GridLayout 与 FlowLayout 的性质造成的吗?有什么方法可以防止 GridLayout 拉伸拇指?我想将 resizable 设置为 false 或强制设置最大宽度可以做到这一点......但我想知道是否还有其他方法?
    猜你喜欢
    • 2020-08-16
    • 2011-11-10
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 2014-09-19
    • 1970-01-01
    相关资源
    最近更新 更多