我可以使用添加到 JToolBar 的 JButton 来上下滚动 JPanel 吗?

Can I use JButtons added to a JToolBar to scroll up and down a JPanel?

我可以使用添加到 JToolBar 的 JButton 来滚动 JPanel 吗? 当我生成大量缩略图时,它们并不都适合 JPanel。我想使用 up/down 箭头 JButton 来滚动。这可以做到吗?如果可以,怎么做?

注意:我想在没有 JScrollPane 的情况下执行此操作,因为我想要自定义箭头图标,而不是标准滚动条。

这是一个 SSCCE:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class PicSlider2 {
    private JButton thumbs;
    private JButton[] thumbnails;
    private JLabel picViewer;
    private JPanel thumbPanel;
    private JToolBar toolBar;

public PicSlider2() {
    final JFrame frame = new JFrame("Picture Slider");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(800, 600));
    frame.setResizable(false);
    frame.setLayout(new BorderLayout());

    picViewer = new JLabel();
    picViewer.setText("Image here");
    picViewer.setHorizontalAlignment(JLabel.CENTER);
    picViewer.setVerticalAlignment(JLabel.BOTTOM);
    picViewer.setBorder(new LineBorder(Color.BLACK, 2));

    JMenuBar frameMenuBar = new JMenuBar();
    frame.setJMenuBar(frameMenuBar);
    JMenu file = new JMenu("File");
    frameMenuBar.add(file);

    JMenuBar picViewerMenu = new JMenuBar();
    picViewerMenu.setLayout(new FlowLayout(FlowLayout.LEFT));
    thumbs = new JButton("THUMBNAILS");//an icon in actual program
    thumbs.setPreferredSize(new Dimension(150,45));
    thumbs.setToolTipText("Thumbnails");
    thumbs.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                picViewer.setVisible(false);
                thumbPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20,20));                
                thumbPanel.setBorder(BorderFactory.createEmptyBorder(50,100,50,30));

                thumbnails = new JButton[30];//example size, chosen so all buttons won't fit on one page
                for (int i = 0; i < 30; i++) {
                    thumbnails[i] = new JButton(Integer.toString(i));
                    thumbnails[i].setPreferredSize(new Dimension(100, 100));                  
                    thumbnails[i].addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent evt) {                           
                                System.out.println("thumbnail clicked - opens full-size view of pic in the JLabel picViewer");                                  
                            }
                        }); 
                    thumbPanel.add(thumbnails[i]);
                    thumbPanel.setVisible(true); 
                }
                toolBar = new JToolBar(null, JToolBar.VERTICAL);
                toolBar.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 30));
                JButton up = new JButton("Up Arrow");
                up.setPreferredSize(new Dimension(80,60));
                up.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent evt) {  
                            System.out.println("Up Arrow Stub - NEEDS TO SCROLL UP PAGE, as needed");
                        }
                    } );
                JButton down = new JButton("Down Arrow");
                down.setPreferredSize(new Dimension(80,60));
                down.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent evt) {  
                            System.out.println("Down Arrow Stub - NEEDS TO SCROLL DOWN PAGE, as needed");
                        }
                    } );
                toolBar.add(Box.createGlue());
                toolBar.add(up);
                toolBar.add(Box.createVerticalStrut(40));
                toolBar.add(down);
                toolBar.add(Box.createGlue());
                frame.getContentPane().add(thumbPanel, BorderLayout.CENTER);
                frame.getContentPane().add(toolBar, BorderLayout.LINE_END);
            }
        });
    picViewerMenu.add(thumbs);
    frame.getContentPane().add(picViewerMenu, BorderLayout.SOUTH);
    frame.add(picViewer, BorderLayout.CENTER);
    frame.setLocation(300, 50);
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                PicSlider2 ps = new PicSlider2();
            }
        });
}

}

我找到了一种通过对 JPanel 上的项目重新排序来实现所需结果的方法。 JFrame 需要在构造函数之外声明。我添加了一个用于跟踪滚动位置的索引变量和一个用于重新加载重新排序的缩略图的 reloadThumbs() 方法。 这是更改后的完整代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class PicSlider2 {
    private JButton thumbs;
    private JButton[] thumbnails;
    private JLabel picViewer;
    private JPanel thumbPanel;
    private JToolBar toolBar;
    private int scrollIndex;
    private final JFrame frame;
public PicSlider2() {
    scrollIndex = 0;
    frame = new JFrame("Picture Slider");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(800, 600));
    frame.setResizable(false);
    frame.setLayout(new BorderLayout());

    picViewer = new JLabel();
    picViewer.setText("Image here");
    picViewer.setHorizontalAlignment(JLabel.CENTER);
    picViewer.setVerticalAlignment(JLabel.BOTTOM);
    picViewer.setBorder(new LineBorder(Color.BLACK, 2));

    JMenuBar frameMenuBar = new JMenuBar();
    frame.setJMenuBar(frameMenuBar);
    JMenu file = new JMenu("File");
    frameMenuBar.add(file);

    JMenuBar picViewerMenu = new JMenuBar();
    picViewerMenu.setLayout(new FlowLayout(FlowLayout.LEFT));
    thumbs = new JButton("THUMBNAILS");//an icon in actual program
    thumbs.setPreferredSize(new Dimension(150,45));
    thumbs.setToolTipText("Thumbnails");
    thumbs.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                picViewer.setVisible(false);
                thumbPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20,20));                
                thumbPanel.setBorder(BorderFactory.createEmptyBorder(50,100,50,30));

                thumbnails = new JButton[30];//example size, chosen so all buttons won't fit on one page
                for (int i = 0; i < 30; i++) {
                    thumbnails[i] = new JButton(Integer.toString(i));
                    thumbnails[i].setPreferredSize(new Dimension(100, 100));                  
                    thumbnails[i].addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent evt) {                           
                                System.out.println("thumbnail clicked - opens full-size view of pic in the JLabel picViewer");                                  
                            }
                        }); 
                    thumbPanel.add(thumbnails[i]);
                    thumbPanel.setVisible(true); 
                }
                toolBar = new JToolBar(null, JToolBar.VERTICAL);
                toolBar.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 30));
                JButton up = new JButton("Up Arrow");
                up.setPreferredSize(new Dimension(80,60));
                up.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent evt) {  
                            System.out.println("Up Arrow Stub - NEEDS TO SCROLL UP PAGE, as needed");
                            if(scrollIndex > 3) scrollIndex -= 4;
                            else scrollIndex = 0;
                            reloadThumbs();
                        }
                    } );
                JButton down = new JButton("Down Arrow");
                down.setPreferredSize(new Dimension(80,60));
                down.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent evt) {  
                            System.out.println("Down Arrow Stub - NEEDS TO SCROLL DOWN PAGE, as needed");
                            if(scrollIndex < 27) scrollIndex += 4;
                            else scrollIndex = 30;
                            reloadThumbs();
                        }
                    } );
                toolBar.add(Box.createGlue());
                toolBar.add(up);
                toolBar.add(Box.createVerticalStrut(40));
                toolBar.add(down);
                toolBar.add(Box.createGlue());
                frame.getContentPane().add(thumbPanel, BorderLayout.CENTER);
                frame.getContentPane().add(toolBar, BorderLayout.LINE_END);
            }
        });
        picViewerMenu.add(thumbs);
        frame.getContentPane().add(picViewerMenu, BorderLayout.SOUTH);
        frame.add(picViewer, BorderLayout.CENTER);
        frame.setLocation(300, 50);
        frame.pack();
        frame.setVisible(true);
    }

    private void reloadThumbs(){
        thumbPanel.removeAll();
        for(int i = scrollIndex; i < 30; ++i){
            thumbPanel.add(thumbnails[i]);
        }
        for(int i = 0; i < scrollIndex; ++i){
            thumbPanel.add(thumbnails[i]);
        }
        thumbPanel.revalidate();            
        frame.revalidate();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    PicSlider2 ps = new PicSlider2();
                }
            });
    }
}

I am trying to do this without a JScrollPane because I want the custom arrow icons

您可以使用 JScrollPane 并使用默认滚动条 Action 来创建自定义按钮 Icon:

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;

public class ScrollPaneSSCCE extends JPanel
{
    public ScrollPaneSSCCE()
    {
        setLayout( new BorderLayout() );
        JTable table = new JTable(50, 5);
        JScrollPane scrollPane = new JScrollPane( table );
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
        add(scrollPane);
        JScrollBar vertical = scrollPane.getVerticalScrollBar();

        JPanel east = new JPanel( new BorderLayout() );
        add(east, BorderLayout.EAST);

        JButton north = new JButton(  new ActionMapAction("UP", vertical, "negativeUnitIncrement") );
        east.add(north, BorderLayout.NORTH);

        JButton south = new JButton( new ActionMapAction("DOWN", vertical, "positiveUnitIncrement") );
        east.add(south, BorderLayout.SOUTH);
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("ScrollPaneSSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ScrollPaneSSCCE());
        frame.setSize(200, 300);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

您将需要 Action Map Action class,它只是一个简单的包装器 class,它从指定组件的 ActionMap 获取默认值 Action .

您需要为面板设置滚动增量。由于您的图片大小为 100,您可能需要使用:

vertical.setUnitIncrement( 100 );