有没有办法将 keyListener 添加到 JDialog / JOptionPane?

Is there a way to add a keyListener to JDialog / JOptionPane?

我一直在尝试为学校项目制作游戏并想添加一些彩蛋,但为此我需要检测按键输入。我一直在寻找如何做到这一点,但找不到任何可行的方法。

我正在使用的设置是制作 JOptionPane 并使用 JDialog 创建它以制作标题并将图标添加到 window。

到目前为止,这是我的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyAdapter;

public class ObamaSimulator {

    public static void main(String[] args) {
        JLabel label; // text in JOptionPane
        
        label = new JLabel("<html><center><b style = 'font-size: 40px; color: red;'>WELCOME</b><p style = 'width: 175px;'><br> To Obama Simulator. In this game you are obama, there isn't really much else to say <br>(The story will tell you more)<br>[press OK to continue or X to quit]", SwingConstants.CENTER);
        String choice = JText("Yes", null, label, "Welcome!"); // Runs JText with option 1, option 2, label, and title, and outputs with the option they chose
        
        if(choice == "Yes"){
            game();
        }else{
            System.out.println("Baboon closed the window :(");
            
            label = new JLabel("<html><center><p style = 'width: 175px;'>Game Closed", SwingConstants.CENTER);
            JText("OK", null, label, null);
            
            System.exit(0); // Used to end the program, IDK why it dosn't end by it's self
        }
        
    }
    
    
    
    public static String JText(String op1, String op2, JLabel label, String title){
        Object[] options; // Options in JOptionPane
        
        JFrame frm = new JFrame(); // Frame used to make JOptionPane have icon
        frm.setIconImage(new ImageIcon("Obama (1).gif").getImage()); // Sets icon of JOptionPane window
        
        if(op1 == null){ // Checks if an option is missing
            options = new Object[] {op2};
        }else if(op2 == null){
            options = new Object[] {op1};
        }else{
            options = new Object[] {op1, op2};
        }
        
        if(title == null){ // Checks if title is missing
            title = "Obama Simulator";
        }

        JOptionPane jp = new JOptionPane(label , JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE,null, options, options[0]); // Creates basic JOptionPane
        JDialog dialog = jp.createDialog(frm, title); // Finishes by adding icon and title
        
        dialog.setSize(350, 300); // Sets size
        dialog.setLocationRelativeTo(null); // Centers the Window
        dialog.setResizable(true); // Needed to make icon
        
        dialog.addKeyListener(new KeyListener(){  
  
            @Override
            public void keyTyped(KeyEvent e) {
                // Nothing
            }
    
            @Override
            public void keyPressed(KeyEvent e) {
                // Nothing 
            }
    
            @Override
            public void keyReleased(KeyEvent e) {
                
                    if (e.getKeyCode() == KeyEvent.VK_UP){
                      System.out.println("up");
                    }
                    
                }
            });
  
        dialog.setVisible(true); // Sets JOptionPane visible
                


        String choice = (String) jp.getValue(); // Sets Choice to variable

        return choice; // Sends choice back to meathod
    }
    
    
    
    
    public static void game(){
        JLabel label;
        String choice;
        
        System.out.println("Baboon picked yes");
        
        label = new JLabel("<html><center><p style = 'width: 175px; font-size: 10px;'>You are Obama, having a lovely day in Minecraft, feeding your dog. You need more quarts and Redstone blocks to build a lighthouse by the sea. While running to your portal room you find an untamed wolf, do you want to tame it?", SwingConstants.CENTER);
        choice = JText("Tame", "Dont tame", label, null);
        
        if(choice == "Tame"){
            System.out.println("Baboon picked tame");
            
            label = new JLabel("<html><center><p style = 'width: 175px; font-size: 10px;'>You shove a bone deep into the mouth of the wolf. You tame it but it makes you feel horrible, maybe it will make you feel better if you dye the collar?", SwingConstants.CENTER);
            choice = JText("Dye", "Dont dye", label, null);
            
            if(choice == "Dye"){
                System.out.println("Baboon Dyed");
            }
            
        }
        
    //  System.exit(0);
    }
}

我尝试在对话框中使用 keyListener,但它不起作用。我已经尝试了其他基本示例并且它们有效,我只是不知道我的问题是什么。

您将要避免 KeyListener。当屏幕上有另一个可聚焦组件时,它不会起作用。

相反,您需要查看 How to Use Key Bindings

choice == "Yes" 不是您在 Java 中比较 String 的方式,您需要使用 "Yes".equals(choice)

我还建议看看 How to Use CardLayout 作为翻转 UI 的另一种方法 ;)

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;

public class ObamaSimulator {

    public static void main(String[] args) {
        JLabel label; // text in JOptionPane

        label = new JLabel("<html><center><b style = 'font-size: 40px; color: red;'>WELCOME</b><p style = 'width: 175px;'><br> To Obama Simulator. In this game you are obama, there isn't really much else to say <br>(The story will tell you more)<br>[press OK to continue or X to quit]", SwingConstants.CENTER);
        String choice = JText("Yes", null, label, "Welcome!"); // Runs JText with option 1, option 2, label, and title, and outputs with the option they chose

        if ("Yes".equals(choice)) {
            game();
        } else {
            System.out.println("Baboon closed the window :(");

            label = new JLabel("<html><center><p style = 'width: 175px;'>Game Closed", SwingConstants.CENTER);
            JText("OK", null, label, null);

            System.exit(0); // Used to end the program, IDK why it dosn't end by it's self
        }

    }

    public static String JText(String op1, String op2, JLabel label, String title) {
        Object[] options; // Options in JOptionPane

        JFrame frm = new JFrame(); // Frame used to make JOptionPane have icon
        frm.setIconImage(new ImageIcon("Obama (1).gif").getImage()); // Sets icon of JOptionPane window

        if (op1 == null) { // Checks if an option is missing
            options = new Object[]{op2};
        } else if (op2 == null) {
            options = new Object[]{op1};
        } else {
            options = new Object[]{op1, op2};
        }

        if (title == null) { // Checks if title is missing
            title = "Obama Simulator";
        }

        JOptionPane jp = new JOptionPane(label, JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]); // Creates basic JOptionPane
        JDialog dialog = jp.createDialog(frm, title); // Finishes by adding icon and title

        dialog.pack();//setSize(350, 300); // Sets size
        dialog.setLocationRelativeTo(null); // Centers the Window
        dialog.setResizable(true); // Needed to make icon

        InputMap im = jp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap am = jp.getActionMap();

        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
        am.put("up", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Up");
            }
        });
        //
        //dialog.addKeyListener(new KeyListener() {
        //
        //    @Override
        //    public void keyTyped(KeyEvent e) {
        //        // Nothing
        //    }
        //
        //    @Override
        //    public void keyPressed(KeyEvent e) {
        //        // Nothing 
        //    }
        //
        //    @Override
        //    public void keyReleased(KeyEvent e) {
        //
        //        if (e.getKeyCode() == KeyEvent.VK_UP) {
        //            System.out.println("up");
        //        }
        //
        //    }
        //});

        dialog.setVisible(true); // Sets JOptionPane visible

        String choice = (String) jp.getValue(); // Sets Choice to variable

        return choice; // Sends choice back to meathod
    }

    public static void game() {
        JLabel label;
        String choice;

        System.out.println("Baboon picked yes");

        label = new JLabel("<html><center><p style = 'width: 175px; font-size: 10px;'>You are Obama, having a lovely day in Minecraft, feeding your dog. You need more quarts and Redstone blocks to build a lighthouse by the sea. While running to your portal room you find an untamed wolf, do you want to tame it?", SwingConstants.CENTER);
        choice = JText("Tame", "Dont tame", label, null);

        if ("Tame".equals(choice)) {
            System.out.println("Baboon picked tame");

            label = new JLabel("<html><center><p style = 'width: 175px; font-size: 10px;'>You shove a bone deep into the mouth of the wolf. You tame it but it makes you feel horrible, maybe it will make you feel better if you dye the collar?", SwingConstants.CENTER);
            choice = JText("Dye", "Dont dye", label, null);

            if ("Dye".equals(choice)) {
                System.out.println("Baboon Dyed");
            }

        }

        //  System.exit(0);
    }
}