Java 如何将键绑定连接到JSplitPane分配器的上下箭头?

Java 如何将键绑定连接到JSplitPane分配器的上下箭头?,java,swing,key-bindings,jsplitpane,Java,Swing,Key Bindings,Jsplitpane,我有一个JSplitPane,它的oneTouchExpandable设置为true JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.setDividerSize(10); splitPane.setOneTouchExpandable(true); 问题是我不知道如何将键绑定附加到JSplitPane的分隔符上的向上和向下箭头。对于向上箭头,我需要Ctrl+

我有一个JSplitPane,它的oneTouchExpandable设置为true

JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.setDividerSize(10);
        splitPane.setOneTouchExpandable(true);
问题是我不知道如何将键绑定附加到JSplitPane的分隔符上的向上和向下箭头。对于向上箭头,我需要Ctrl+U,对于向下箭头,我需要Ctrl+D


谢谢

OneTouchExpandable所示的箭头按钮的实现是UI标签,需要额外的工作来绑定它们。您可以轻松地使用
JSplitPane
本身上的键绑定,使用
setDividerLocation(int)
控制
JSplitPane
分隔器位置。在
Ctrl+U
时增加,在
Ctrl+D
时减少。例如:

    Action incrDividerLoc = new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
        JSplitPane srcSplitPan = (JSplitPane) e.getSource();
        (srcSplitPan).setDividerLocation(srcSplitPan.getDividerLocation()+10);
     }
   };

  Action decrDividerLoc = new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
        JSplitPane srcSplitPan = (JSplitPane) e.getSource();
        (srcSplitPan).setDividerLocation(srcSplitPan.getDividerLocation()-10);
    }
   };

    jSplitPane1.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_U, KeyEvent.CTRL_DOWN_MASK),
                                "increaseDivider");
    jSplitPane1.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.CTRL_DOWN_MASK),
                                "decreaseDivider");
    jSplitPane1.getActionMap().put("increaseDivider", incrDividerLoc);
    jSplitPane1.getActionMap().put("decreaseDivider", decrDividerLoc);

注意:方法传递给
setDividerLocation(int)
的小于0的值意味着应将分隔符重置为一个值,该值尝试遵守左/顶部组件的首选大小。通知侦听器后,最后一个分隔器位置将通过
setLastDividerLocation

更新,
onetoucheExpandable
显示的箭头按钮是UI标签,将需要额外的工作来绑定它们。您可以轻松地使用
JSplitPane
本身上的键绑定,使用
setDividerLocation(int)
控制
JSplitPane
分隔器位置。在
Ctrl+U
时增加,在
Ctrl+D
时减少。例如:

    Action incrDividerLoc = new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
        JSplitPane srcSplitPan = (JSplitPane) e.getSource();
        (srcSplitPan).setDividerLocation(srcSplitPan.getDividerLocation()+10);
     }
   };

  Action decrDividerLoc = new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
        JSplitPane srcSplitPan = (JSplitPane) e.getSource();
        (srcSplitPan).setDividerLocation(srcSplitPan.getDividerLocation()-10);
    }
   };

    jSplitPane1.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_U, KeyEvent.CTRL_DOWN_MASK),
                                "increaseDivider");
    jSplitPane1.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.CTRL_DOWN_MASK),
                                "decreaseDivider");
    jSplitPane1.getActionMap().put("increaseDivider", incrDividerLoc);
    jSplitPane1.getActionMap().put("decreaseDivider", decrDividerLoc);
注意:方法传递给
setDividerLocation(int)
的小于0的值意味着应将分隔符重置为一个值,该值尝试遵守左/顶部组件的首选大小。通知侦听器后,通过
setLastDividerLocation
更新最后一个分隔器位置

问题是我不知道如何将键绑定附加到JSplitPane的分隔符上的向上和向下箭头

通常,您会尝试访问按钮的操作。在许多情况下,组件已经定义了一个可以使用的操作。有关JSplitPane的默认绑定列表,请参见。遗憾的是,没有支持一键单击选项的操作

因此,我们需要直接从UI访问按钮:

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

public class SplitPaneDividerAction extends AbstractAction
{
    private boolean leading;

    public SplitPaneDividerAction(boolean leading)
    {
        this.leading = leading;
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        JSplitPane splitPane = (JSplitPane)e.getSource();
        BasicSplitPaneUI ui = (BasicSplitPaneUI)splitPane.getUI();
        BasicSplitPaneDivider divider = ui.getDivider();

        if (leading)
            ((JButton)divider.getComponent(0)).doClick();
        else
            ((JButton)divider.getComponent(1)).doClick();
    }

    private static void createAndShowUI()
    {
        JPanel leading = new JPanel();
        leading.setPreferredSize( new Dimension(200, 100) );
        leading.setBackground( Color.BLUE );
        leading.setFocusable(true);

        JPanel trailing = new JPanel();
        trailing.setPreferredSize( new Dimension(200, 100) );
        trailing.setBackground( Color.RED );
        trailing.setFocusable(true);

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leading, trailing);
        splitPane.setOneTouchExpandable(true);
        splitPane.setDividerLocation(100);

        InputMap im = splitPane.getInputMap(JSplitPane.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        ActionMap am = splitPane.getActionMap();
        im.put(KeyStroke.getKeyStroke("control U"), "leading");
        im.put(KeyStroke.getKeyStroke("control D"), "trailing");
        am.put("leading", new SplitPaneDividerAction(true));
        am.put("trailing", new SplitPaneDividerAction(false));

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( splitPane );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
当然,只有当LAF从BasicSplitPaneUI扩展时,这种方法才会起作用

问题是我不知道如何将键绑定附加到JSplitPane的分隔符上的向上和向下箭头

通常,您会尝试访问按钮的操作。在许多情况下,组件已经定义了一个可以使用的操作。有关JSplitPane的默认绑定列表,请参见。遗憾的是,没有支持一键单击选项的操作

因此,我们需要直接从UI访问按钮:

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

public class SplitPaneDividerAction extends AbstractAction
{
    private boolean leading;

    public SplitPaneDividerAction(boolean leading)
    {
        this.leading = leading;
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        JSplitPane splitPane = (JSplitPane)e.getSource();
        BasicSplitPaneUI ui = (BasicSplitPaneUI)splitPane.getUI();
        BasicSplitPaneDivider divider = ui.getDivider();

        if (leading)
            ((JButton)divider.getComponent(0)).doClick();
        else
            ((JButton)divider.getComponent(1)).doClick();
    }

    private static void createAndShowUI()
    {
        JPanel leading = new JPanel();
        leading.setPreferredSize( new Dimension(200, 100) );
        leading.setBackground( Color.BLUE );
        leading.setFocusable(true);

        JPanel trailing = new JPanel();
        trailing.setPreferredSize( new Dimension(200, 100) );
        trailing.setBackground( Color.RED );
        trailing.setFocusable(true);

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leading, trailing);
        splitPane.setOneTouchExpandable(true);
        splitPane.setDividerLocation(100);

        InputMap im = splitPane.getInputMap(JSplitPane.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        ActionMap am = splitPane.getActionMap();
        im.put(KeyStroke.getKeyStroke("control U"), "leading");
        im.put(KeyStroke.getKeyStroke("control D"), "trailing");
        am.put("leading", new SplitPaneDividerAction(true));
        am.put("trailing", new SplitPaneDividerAction(false));

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( splitPane );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

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

当然,这种方法只有在LAF扩展自BasicSplitPaneUI时才有效。

+1,但是splitpane引用应该来自ActionEvent的getSource()方法。@camickr,但我还是会听你的。:)已编辑+1,但splitpane引用应来自ActionEvent的getSource()方法。@camickr,但我还是会听你说的。:)编辑