当前位置: 首页 > 知识库问答 >
问题:

更改JFrame的面板“禁用”插入的新面板的输入地图

经国安
2023-03-14

问题描述:我有一个JFrame,在这个JFrame中有一个带按钮的JPanel,当我按下按钮时,一个动作监听器会用一个新的JPanel来更改当前的JPanel,其中包含另外两个JPanel,这两个JPanel都有一个inputMap,当用户按下“up”键时,这两个JPanel都会生成一些东西。问题是:当我用新的JPanel更改JPanel时,“up”键不会起任何作用。

下面是代码:是一个SSCCE,所以您只需复制和粘贴即可查看它的功能。

这个修改后的代码来自我有时“解决”的另一个问题。如何让两个JPanels监听同一个事件?(代码在我选择的答案中)。

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class TwoPanelsTest extends JFrame {

private static MyPanel one = new MyPanel("One");
private static MyPanel two = new MyPanel("Two");
private static List<MyPanel> list = Arrays.asList(one, two);
private PanelsController panelsController;

public TwoPanelsTest() {
    super("TwoPanelsTest");
    panelsController= new PanelsController(this);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setSize(400,400);
    this.setLocationRelativeTo(null);
    this.setVisible(true);
}

private static class MyPanel extends JPanel {

    private String string = " will be updated though its action.";
    private Action action = new UpdateAction(this);
    private String name;
    private JLabel label;

    public MyPanel(String name) {
        this.name = name;
        this.label = new JLabel(name + string, JLabel.CENTER);
        this.setLayout(new GridLayout());
        this.setFocusable(true);
        this.add(label);
    }

    public Action getAction() {
        return action;
    }

    private void update() {
        label.setText(name + ": " + System.nanoTime());
    }

    private static class UpdateAction extends AbstractAction {

        private MyPanel panel;

        public UpdateAction(MyPanel panel) {
            this.panel = panel;
        }

        @Override
        public void actionPerformed(ActionEvent ae) {
            panel.update();
        }
    }
}//MyPanel

private static class ButtonPanel extends JPanel{
    private JButton button ;
    private PanelsController panelsController;

    public ButtonPanel(PanelsController panelsController){
        this.panelsController=panelsController;

        button = new JButton("Button");
        button.setActionCommand("buttonPressed");
        button.addActionListener(this.panelsController);
        this.setFocusable(true);
        add(button);
    }
}//ButtonPanel

private static class PanelsController implements ActionListener {

    private TwoPanelsTest twoPanelsTest;

    public PanelsController(TwoPanelsTest twoPanelsTest){
        this.twoPanelsTest=twoPanelsTest;
        this.twoPanelsTest.getContentPane().add(new ButtonPanel(this));
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        if (ae.getActionCommand().equals("buttonPressed")){
            twoPanelsTest.getContentPane().removeAll();
            twoPanelsTest.getContentPane().invalidate();

            JPanel panel = new JPanel(new GridLayout(0, 1, 10, 10));
            panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            panel.add(one);
            panel.add(two);
            panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
            .put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
            panel.getActionMap().put("up", new AbstractAction() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    for (MyPanel panel : list) {
                        panel.getAction().actionPerformed(e);
                    }
                }
            });
            twoPanelsTest.getContentPane().add(panel);
            twoPanelsTest.validate();
            twoPanelsTest.repaint();
        }
    }//ActionPerformed

}//PanelsController

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

        @Override
        public void run() {
            TwoPanelsTest t = new TwoPanelsTest();
        }
    });
}
}

共有1个答案

彭宜人
2023-03-14

好吧,这很简单-如果你有两个面板,里面没有任何组件,并且想让它们听热键使用:

panel.getInputMap ( JComponent.WHEN_IN_FOCUSED_WINDOW )
     .put ( KeyStroke.getKeyStroke ( KeyEvent.VK_UP, 0 ), "up" );

JComponent。当在聚焦窗口中而不是JComponent中时。当\u聚焦\u组件的\u祖先\u时。

否则,您需要在面板内聚焦某些内容,以便它能够捕捉关键事件。

顺便说一下,还有另一种方法可以监听Java应用程序窗口中的全局热键:

Toolkit.getDefaultToolkit ().addAWTEventListener ( new AWTEventListener ()
{
    public void eventDispatched ( AWTEvent event )
    {
        // All application key events will be passed here
    }
}, AWTEvent.KEY_EVENT_MASK );
 类似资料:
  • 问题内容: 我有2个JPanels和1个JFrame,当我单击一个按钮时,我试图在面板之间切换。我不想使用CardLayout,因为我想要不同的面板,并且对于CardLayouts我只能为两个面板使用相同的按钮。我的代码是: } 问题答案: 这是一个帮助您的小例子: 最新编辑 显示您的选择,内部

  • 我只想插入一个图表(由类创建)到另一个类的面板中(此处为TabFrame)。我正在使用NetBeans。所以,我创建了一个类,如您所见: 下一步是将Graphique类创建的图表集成到另一个名为此处的类中的面板(由于netbeans的GUI界面已经声明)中: 为什么这不起作用?

  • 在我的程序中,我有一个基于向导的布局。由CardLayout实现。因此,有一组类扩展了JPanel。我想在每个面板上都有按钮来导航到其他面板。例如,当程序显示第一面板时,我想有一个按钮来显示第二面板。 我试图在main cardlayout panel holder中创建一个方法,以便任何其他类都可以通过该方法更改显示面板,但它不起作用,并且出现了stackoverflow错误。 这是我的课程 基

  • 我正在尝试构建一个基于按钮的动态应用程序,这些按钮从创建的面板内部切换JFrame的主面板(这是我的应用程序的顶部内容)。 这个问题更多的是设计问题,而不是开发问题。我不确定我的设计,但我会试着解释一下。 我有一个JFrame代表我的应用程序,其中包含一个JTabbedPane(和多个Tabs)。每个选项卡都包含一个默认的JPanel,在那个JPanel中,我调用一个正在呈现我的视图的控制器(我正

  • 我在PrimeFaces面板更新中遇到问题。 我有一个主面板,其中包含两个输出面板。每个输出面板可能包含一个按钮,即交换面板。交换面板按钮用于将输出面板从一个交换到另一个。 如果我更新渲染面板的按钮操作,我需要提供主面板ID,它可以正常工作。但是对于树结构层次结构,如果我打算给出两个输出面板ID,它不会渲染面板。当我把日志确认这一点时,按钮操作只调用了一次。 我将附上以下代码示例: renderi

  • 问题内容: 我正在使用一个使用Swing的旧版应用程序,我正在努力弄清用户单击按钮时屏幕的变化情况。我无法弄清楚的原因之一是因为这是我第一次使用Swing。我读了一本书,掌握了基础知识,但仍然很挣扎。 基本上,我正在查看的屏幕具有一个JSplitPane,其左侧具有多个快捷按钮,而右侧具有一个空白窗格。当我单击该按钮时,根据所按下的按钮,右侧窗格中会显示一个不同的屏幕。 遍历代码,我期望在某处会有