gpt4 book ai didi

java - 制作帮助菜单

转载 作者:行者123 更新时间:2023-12-01 23:12:22 27 4
gpt4 key购买 nike

我正在向我的程序添加一个帮助菜单,并且我试图找出是否有一种方法可以拦截键盘输入,而无需在 JFrame 上使用 setFocusable 方法。如果我将焦点设置到框架上并按 F1,则没有问题。当他们按下任何其他组件时,问题就会出现。框架不再处于焦点状态,因此 F1 键不再显示菜单。这是我的做法

package helpmenu;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class HelpMenu extends JFrame
{
public HelpMenu()
{
setSize(300, 300);
setTitle("Help Menu");
}


/**
* Sets a KeyListener to
* the passed in JFrame.
* @param mainFrame
*/
public void callMenu( JFrame mainFrame )
{
mainFrame.addKeyListener( new functionListener() ); //Set keylistener to the main frame.
mainFrame.setFocusable(true); //Put the main frame into focus.
}

/**
* Inner KeyListener
* class for the mainFrame
* @author Shaun
*/
class functionListener implements KeyListener
{
@Override
public void keyPressed(KeyEvent e)
{
//Check if the F1 key was pressed
if ( e.getKeyCode() == KeyEvent.VK_F1 ) {
setVisible(true);
}
}

@Override
public void keyReleased(KeyEvent e) {}

@Override
public void keyTyped(KeyEvent e) {}
}
}

最佳答案

不要将 KeyListener 用于此类事情。正如您所注意到的,原因之一是它要求组件处于焦点位置。相反,use a Key Binding使用 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 输入 map 。

此外,有些相关,请参阅 "The Use of Multiple JFrames, Good/Bad Practice?"您的帮助菜单可能应该是一个 JDialog。

这是使用键绑定(bind)的示例:

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

class HelpDialogEx {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new HelpDialogEx();
}
});
}

final JFrame frame = new JFrame("Press F1 for help");
final JPanel cpane = new JPanel(new GridLayout(4, 5, 10, 10));

final HelpDialog help = new HelpDialog(frame);

final AbstractAction helpToggle = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
help.setVisible(!help.isVisible());
}
};

HelpDialogEx() {
for(int i = 0; i < 20; i++) {
cpane.add(new JButton("Nil"));
}

cpane.setPreferredSize(new Dimension(640, 480));
frame.setContentPane(cpane);

addHelpToggle(frame.getRootPane());
addHelpToggle(help.getRootPane());

frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

void addHelpToggle(JComponent comp) {
KeyStroke f1Key = KeyStroke.getKeyStroke(
KeyEvent.VK_F1, 0, true
);
String cmd = "helpToggle";

for(InputMap im : new InputMap[] {
comp.getInputMap(JComponent.WHEN_FOCUSED),
comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
}) {
im.put(f1Key, cmd);
}

comp.getActionMap().put(cmd, helpToggle);
}

static class HelpDialog
extends JDialog {
HelpDialog(Window parent) {
super(parent, "\"Help\"", Dialog.ModalityType.MODELESS);

JTextArea doc = new JTextArea(getUnhelpfulText());
doc.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
doc.setEditable(false);
doc.setLineWrap(true);

JScrollPane scroll = new JScrollPane(doc);
scroll.getViewport().setPreferredSize(new Dimension(480, 360));

setContentPane(scroll);

pack();
setLocationRelativeTo(null);
}

static String getUnhelpfulText() {
StringBuilder sb = new StringBuilder();

addRandomParagraph(sb);
for(int i = 0; i < 3; i++) {
sb.append("\n\n");
addRandomParagraph(sb);
}

return sb.toString();
}

static void addRandomParagraph(StringBuilder sb) {
sb.append(" ");
addRandomSentence(sb);
for(int i = 0; i < 10; i++) {
sb.append(' ');
addRandomSentence(sb);
}
}

static void addRandomSentence(StringBuilder sb) {
sb.append((char)(Math.random() * 26 + 'A'));

for(int i = (int)(Math.random() * 10 + 1); i > 0; i--) {
for(int len = (int)(Math.random() * 10 + 1); len > 0; len--) {
sb.append((char)(Math.random() * 26 + 'a'));
}

sb.append(' ');
}

sb.setCharAt(sb.length() - 1, '.');
}
}
}

我发现虽然教程说 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 应该涵盖组件本身聚焦的时间,但事实并非如此。

关于java - 制作帮助菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21685029/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com