0

In my code, the user can add new buttons to the main JPanel using the menu. The JPanel utilizes the FlowLayout form so that depending on the size of the window, the number or buttons on each row changed to accommodate the best view... well, that was the case until I introduces JScrollPane. Now I have two issues:

  1. The # of buttons on each row will stop changing as soon as the window is re-sized by the user to the preferred size or lower. *Didn't have this issue before, even with preferred size being set.

  2. I can only scroll to see the buttons that are within the preferred size range of JPanel. Anything that gets placed outside is not view-able and doesn't increase the size of JScrollPane's range.

Here's the code:

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();
            }
        });
    }
}

I've tried numerous things and I've been digging through the Javadoc.... I've read lots of things and tutorials, but still can't get my scrolling/re-sizing to work.

4

1 回答 1

2

当您设置组件的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();
         }
      });
   }
}
于 2013-05-12T00:35:44.217 回答