Есть ли способ добавить KeyListener в JDialog / JOptionPane?

#java #swing #keylistener

#java #swing #keylistener

Вопрос:

Я пытался создать игру для школьного проекта и хотел добавить несколько пасхальных яиц, но для этого мне нужно определить ввод ключа. Я некоторое время искал, как это сделать, и не мог найти никаких способов, которые работают.

Используемая мной настройка заключается в создании JOptionPane и создании его с помощью JDialog для создания заголовка и добавления значка в окно.

Вот мой код на данный момент:

 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 в диалоговом окне, но он не работает. Я пробовал другие базовые примеры, и они работают, я просто понятия не имею, что не так с моим.

Комментарии:

1. 1) Создание класса со всеми статическими методами — плохой дизайн. 2) Когда модальный диалог виден, код блокируется до тех пор, пока диалог не будет закрыт, что означает, что ваш addKeyListener() оператор не выполняется. 3) не используйте «==» для сравнения строк. Вместо этого используйте equals(...) метод. 4) Не используйте KeyListener. Вместо этого вы должны использовать Key Bindings . Прочитайте руководство по Swing для основы Swing. Существует раздел «Привязки клавиш». Кроме того, любой из примеров покажет вам, как лучше структурировать ваш код, чтобы вы не использовали статические методы.

Ответ №1:

Вы захотите избежать KeyListener . Когда у вас на экране появляется другой фокусируемый компонент, он не будет работать.

Вместо этого вы захотите посмотреть, как использовать привязки клавиш.

choice == "Yes" это не то, как вы сравниваете String s в Java, вы захотите использовать "Yes".equals(choice) вместо этого.

Я бы также предложил взглянуть на то, как использовать CardLayout в качестве другого средства для изменения пользовательского интерфейса 😉

 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);
    }
}