Java 当其他组件具有焦点时,如何使用键盘滚动JPanel?

Java 当其他组件具有焦点时,如何使用键盘滚动JPanel?,java,swing,keyboard,jscrollpane,focusable,Java,Swing,Keyboard,Jscrollpane,Focusable,我一直在寻找一个解决这个问题的方法,我认为这是Java Swing中非常常见的问题,但找不到具体的答案 我有一个SwingJPanel,上面有一个可滚动的JPanel,显示文档的图像 下面是更多Swing组件,例如另一个面板中的JTable和一些文本框、JButton控件等。(同一JWindow中有更多面板) 当用户编辑下面框中的数据等时,这些当然会获得应有的关注。现在,当用户想要滚动文档中的某些特定数据时,他/她需要先设置焦点(使用鼠标/选项卡),然后滚动 因此,用户希望使用上/下箭头键盘,而

我一直在寻找一个解决这个问题的方法,我认为这是Java Swing中非常常见的问题,但找不到具体的答案

我有一个Swing
JPanel
,上面有一个可滚动的
JPanel
,显示文档的图像

下面是更多Swing组件,例如另一个面板中的
JTable
和一些文本框、
JButton
控件等。(同一
JWindow
中有更多面板)

当用户编辑下面框中的数据等时,这些当然会获得应有的关注。现在,当用户想要滚动文档中的某些特定数据时,他/她需要先设置焦点(使用鼠标/选项卡),然后滚动

因此,用户希望使用上/下箭头键盘,而不离开他正在使用的其他组件的焦点

我曾尝试设置键盘处理程序,但如果不将焦点移至顶部,则无法使其正常工作


没有一种方法可以滚动一个可滚动的Swing组件,而该组件(以及另一个)没有焦点吗?

如果该组件是滚动窗格中的文本字段,那么如果(至少是第一个)文本字段有焦点,向下翻页似乎可以工作。这是运行此类代码并多次向下翻页的结果

如果在聚焦滚动窗格外的组件时需要此行为,请查看

import java.awt.*;
导入javax.swing.*;
导入javax.swing.border.EmptyBorder;
公共类键盘滚动{
私有JComponent ui=null;
键盘滚动(){
initUI();
}
public void initUI(){
如果(ui!=null){
返回;
}
ui=新的JPanel(新的BorderLayout(4,4));
ui.setboorder(新的空订单(4,4,4,4));
JPanel textPanel=新的JPanel(新的网格布局(0,1));
对于(int ii=1;ii<101;ii++){
添加(新的JTextField(“Field”+ii,30));
}
JScrollPane scrollPane=新的JScrollPane(文本面板,
JScrollPane.VERTICAL\u滚动条\u始终,
JScrollPane.HORIZONTAL\u SCROLLBAR\u NEVER);
添加(滚动窗格);
维度d=textPanel.getPreferredSize();
scrollPane.getViewport().setPreferredSize(
新维度((int)d.getWidth(),100));
}
公共JComponent getUI(){
返回用户界面;
}
公共静态void main(字符串[]args){
Runnable r=新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}捕获(异常使用默认值){
}
KeyboardScroll o=新的KeyboardScroll();
JFrame f=新JFrame(“使用“向下翻页”);
f、 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f、 setLocationByPlatform(真);
f、 setContentPane(o.getUI());
f、 包装();
f、 setMinimumSize(f.getSize());
f、 setVisible(真);
}
};
SwingUtilities.invokeLater(r);
}
}

如果组件是滚动窗格中的文本字段,则如果(至少是第一个)文本字段是焦点,则向下翻页似乎可以工作。这是运行此类代码并多次向下翻页的结果

如果在聚焦滚动窗格外的组件时需要此行为,请查看

import java.awt.*;
导入javax.swing.*;
导入javax.swing.border.EmptyBorder;
公共类键盘滚动{
私有JComponent ui=null;
键盘滚动(){
initUI();
}
public void initUI(){
如果(ui!=null){
返回;
}
ui=新的JPanel(新的BorderLayout(4,4));
ui.setboorder(新的空订单(4,4,4,4));
JPanel textPanel=新的JPanel(新的网格布局(0,1));
对于(int ii=1;ii<101;ii++){
添加(新的JTextField(“Field”+ii,30));
}
JScrollPane scrollPane=新的JScrollPane(文本面板,
JScrollPane.VERTICAL\u滚动条\u始终,
JScrollPane.HORIZONTAL\u SCROLLBAR\u NEVER);
添加(滚动窗格);
维度d=textPanel.getPreferredSize();
scrollPane.getViewport().setPreferredSize(
新维度((int)d.getWidth(),100));
}
公共JComponent getUI(){
返回用户界面;
}
公共静态void main(字符串[]args){
Runnable r=新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}捕获(异常使用默认值){
}
KeyboardScroll o=新的KeyboardScroll();
JFrame f=新JFrame(“使用“向下翻页”);
f、 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f、 setLocationByPlatform(真);
f、 setContentPane(o.getUI());
f、 包装();
f、 setMinimumSize(f.getSize());
f、 setVisible(真);
}
};
SwingUtilities.invokeLater(r);
}
}
有没有一种方法可以滚动一个可滚动的Swing组件,而这个组件(还有另一个)没有焦点

那么一般的解决办法就是使用

但是,问题是每个组件都可以为up/down事件本身实现键绑定,在这种情况下,将调用该组件的相关
操作

本教程演示如何从组件中删除键绑定

一个JTable和一些文本框

因此,这些是实现向上/向下键绑定的组件的示例

按钮控件

是没有默认向上/向下键绑定的组件的示例

<
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class KeyboardScroll {

    private JComponent ui = null;

    KeyboardScroll() {
        initUI();
    }

    public void initUI() {
        if (ui != null) {
            return;
        }

        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        JPanel textPanel = new JPanel(new GridLayout(0, 1));
        for (int ii = 1; ii < 101; ii++) {
            textPanel.add(new JTextField("Field " + ii, 30));
        }
        JScrollPane scrollPane = new JScrollPane(textPanel,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        ui.add(scrollPane);
        Dimension d = textPanel.getPreferredSize();
        scrollPane.getViewport().setPreferredSize(
                new Dimension((int)d.getWidth(),100));
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(
                            UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                KeyboardScroll o = new KeyboardScroll();

                JFrame f = new JFrame("Use 'Page Down'");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        setLayout( new BorderLayout() );

        JPanel top = new JPanel();
        top.add( new JTextField(10) );
        top.add( new JButton("Button") );
        add(top, BorderLayout.PAGE_START);

        JLabel label = new JLabel( new ImageIcon("mong.jpg") );
        JScrollPane scrollPane = new JScrollPane( label );
        add(scrollPane, BorderLayout.CENTER);

        JScrollBar scrollBar = scrollPane.getVerticalScrollBar();

        InputMap im = getInputMap(JScrollBar.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        ActionMap am = getActionMap();
        im.put(KeyStroke.getKeyStroke("pressed UP"), "up");
        am.put("up", new AbstractAction()
        {
            public void actionPerformed(ActionEvent e)
            {
                scrollBar.setValue(scrollBar.getValue() - scrollBar.getUnitIncrement(-1));
            }
        });

        im.put(KeyStroke.getKeyStroke("pressed DOWN"), "down");
        am.put("down", new AbstractAction()
        {
            public void actionPerformed(ActionEvent e)
            {
                scrollBar.setValue(scrollBar.getValue() + scrollBar.getUnitIncrement(1));
            }
        });

    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
    }
}