繁体   English   中英

JFrame中的KeyEvent由于可运行而无法正常工作

[英]KeyEvent in JFrame won't work due to runnable

我是Java的新手,所以我真的希望这个问题确实是由可运行的程序引起的,该可运行的程序阻塞了我认为的关键事件监听器。 我有Roll类,它调用另一个类TimerImageSwapper ,该类在构建器中创建了一个runnable。 稍后在Roll上通过类main()方法调用TimerImageSwapper#run()

TimerImageSwapper的目的是通过显示随机面并将其降落到某个值来模拟多维数据集滚动。 该方法的主方法在被调用时将接收调用方JFrame类作为输入,以便结果显示在初始JFrame

确定数字后,我希望用户能够通过按空格键使屏幕变暗。 多数民众赞成在那部分不起作用。

PS我假设这是一个线程问题,因为它在调试模式下运行得很好。

Roll类如下所示:

package nofis;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.KeyEvent;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Roll extends javax.swing.JFrame {

    private final long id;
    private final String filename;
    private int clicks = 0;

    public Roll(long id) {
        this.setUndecorated(true);
        this.setExtendedState(Roll.MAXIMIZED_BOTH);
        this.filename = "c:\\results\\test.csv";
        initComponents();
        this.id = id;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(204, 204, 255));
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });

        jButton1.setText("text!");
        jButton1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jButton1KeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jButton1KeyReleased(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(162, 162, 162)
                        .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 429, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(399, 399, 399)
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(271, 271, 271)
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 221, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(93, 93, 93)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(52, 52, 52))
        );

        pack();
    }// </editor-fold>                        

    private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
        if (evt.getKeyCode() == KeyEvent.VK_SPACE) {
            if (clicks == 0) {
                clicks++;
                try {
                    rollDice();
                } catch (IOException ex) {
                    Logger.getLogger(Roll.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {
                while (!is.done) {
                    try {
                        this.wait(100);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Roll.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }

                for (Component c : this.getRootPane().getComponents()) {
                    c.setVisible(false);
                }

                this.setBackground(Color.black);
                revalidate();
//
                repaint();

            }
        }    }                               

    private void jButton1KeyReleased(java.awt.event.KeyEvent evt) {                                     
        // TODO add your handling code here:
    }                                    

    private void jButton1KeyPressed(java.awt.event.KeyEvent evt) {                                    
        if (evt.getKeyCode() == KeyEvent.VK_SPACE) {
            try {
                if (clicks == 0) {
                    clicks++;
                    try {
                        rollDice();
                    } catch (IOException ex) {
                        Logger.getLogger(Roll.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return;
                } else {
                    while (!is.done) {
                        this.wait(100);
                    }

//here i am going through all form elemets and make them disappear. 
                for (Component c : this.getRootPane().getComponents()) {
                    c.setVisible(false);
                }
                this.setBackground(Color.black);
                revalidate();
                repaint();
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(Roll.class.getName()).log(Level.SEVERE, null, ex);
            }


        }    }                                   

    private void rollDice() throws IOException {
        jButton1.setVisible(false);
        is = new TimerImageSwapper(jLabel1, jLabel2);
        Random rand = new Random();
        int res = 1 + rand.nextInt(6);
        is.main(this, res);

        revalidate();
        repaint();

        {

        }
    }

    private static void updateCsvFile(String sFileName, Long id, Integer result, Date time) throws IOException {

        try (FileWriter writer = new FileWriter(sFileName, true)) {
            writer.append(id.toString());
            writer.append(',');
            writer.append(result.toString());
            writer.append(',');
            writer.append(time.toString());
            writer.append('\n');
            writer.flush();
        } catch (Exception e) {
        }

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;

                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Roll.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Roll.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Roll.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Roll.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
    }
    private javax.swing.JLabel jlabel1;
    TimerImageSwapper is;
    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    // End of variables declaration                   

}

TimerImageSwapper看起来像这样:

package nofis;

import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.*;

public class TimerImageSwapper {

    public static final String[] IMAGES = {
        "dice1.png",
        "dice2.png",
        "dice3.png",
        "dice4.png",
        "dice5.png",
        "dice6.png"
    };

    private static final int TIMER_DELAY = 100;

    private ImageIcon[] icons = new ImageIcon[IMAGES.length];
    private final JLabel mainLabel;// = new JLabel();

    private int iconIndex = 0;
    private int max = 30;
    private int count = 0;
    public int res = 1;
    Timer timer = null;
    JLabel result =null;
    public boolean done = false;
    public TimerImageSwapper(JLabel mainLabel,JLabel jLabel2) throws IOException {
        for (int i = 0; i < icons.length; i++) {
            BufferedImage image = ImageIO.read(new File(IMAGES[i]));
            icons[i] = new ImageIcon(image);
        }
        this.mainLabel = mainLabel;
        this.result=jLabel2;


        mainLabel.setIcon(icons[iconIndex]);

        timer = new Timer(TIMER_DELAY, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                Random rand = new Random();
                if (count >= max) {
                    timer.stop();
                    done=true;

                    res = iconIndex;
                    mainLabel.setIcon(icons[res-1]);
                    result.setFont(new java.awt.Font("Arial", Font.BOLD, 20));
                    result.setText("text: " + Integer.toString(res));

                    return;
                }
                count++;
                iconIndex=rand.nextInt(6)+1;
                mainLabel.setIcon(icons[iconIndex-1]);
            }
        });
        timer.start();
    }


    public Component getMainComponent() {
        return mainLabel;
    }

    private void createAndShowGui() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(this.getMainComponent());
        frame.setVisible(true);

    }
    JFrame frame;

    public void main(JFrame frame, int result) {
        this.frame = frame;
        res=result;

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                createAndShowGui();
            }
        });
    }
}

我知道我有很多执行不当的代码,不胜感激。

谢谢。

  • 我们不建议将KeyListener用作一般规则,这是有原因的,我们建议使用键绑定API
  • 另外,您不应该在按钮上使用KeyListener ,如果用户用鼠标单击按钮时会发生这种情况? 相反,您应该使用ActionListener 请参阅如何使用按钮,复选框和单选按钮以及如何编写动作侦听器
  • while (!is.done) {由于Swing是单线程的,将导致您出现问题,因此您永远都不应做任何会阻塞事件调度线程的事情,这将防止UI更新或响应新事件。 有关更多详细信息,请参阅Swing中的并发 在您的情况下,我考虑使用Observer Pattern ,您的Timer会触发一个通知,您的Roll类将对此进行响应

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM