为什么keylistener没有对CardLayout的面板做出反应,因为代码中的其他监听器成功了?

时间:2015-03-31 07:51:09

标签: java swing jpanel keylistener cardlayout

我写了一个keylistener,它会从屏幕保护程序JPanel切换回主屏幕,并将其添加到屏幕保护程序JPanel创建方法,但它不会在按键时触发,也不会发生任何事情。

任何人都知道发生了什么事?

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import static javax.swing.SwingUtilities.invokeLater;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class layoutdemo {
    JPanel cards; // panel that uses CardLayout
    CardLayout clo;
    final static String WELCOMEPANEL = "Card with welcome message";
    final static String SCREENSAVERPANEL = "Card with screensaver";
    final static String ENTERPINPANEL = "Card with PIN input"; // not implemented yet
    final static String[] FILEARRAY = new String[]      {"/cardlayouttest/newpackage/btc-zg.jpg","/cardlayouttest/newpackage/pic2.jpeg"};
    static layoutdemo ldm = null;
    private static int INDEX = 0;
    private JLabel screenImage;
    private Timer changeTimer;
    public void addComponenttoPane(Container pane){ //method for adding CardLayout and components to JFrame
    cards = new JPanel(new CardLayout());
    cards.add(welcomePanel(),WELCOMEPANEL);
    cards.add(screensaverPanel(),SCREENSAVERPANEL);
    pane.add(cards,BorderLayout.CENTER);
}
public JPanel welcomePanel(){ //method for creating the "Welcome" panel
    JPanel welcomePanel;
    welcomePanel = new JPanel();
    JLabel welcomeLabel = new JLabel("Dobrodošli na depozitni bankomat!",SwingConstants.CENTER);
    JLabel instructionLabel = new JLabel("Molim vas ubacite karticu u utor sa desne strane",SwingConstants.CENTER);
    instructionLabel.setFont(new Font(instructionLabel.getFont().getFontName(),Font.PLAIN,28));
    welcomeLabel.setFont(new Font(instructionLabel.getFont().getFontName(),Font.PLAIN,28));
    welcomePanel.setLayout(new GridLayout(0,1));
    welcomePanel.add(welcomeLabel);
    welcomePanel.add(instructionLabel);

    return welcomePanel;
}
public JPanel screensaverPanel(){ // method for creating the "Screensaver" panel
    JPanel screensaverPanel;
    screensaverPanel = new JPanel();
    screenImage = new JLabel();
    screenImage.setIcon(new ImageIcon(getClass().getResource("/cardlayouttest/newpackage/btc-zg.jpg")));
    screensaverPanel.add(screenImage);
    screensaverPanel.addKeyListener(stopScreensaver());
    screensaverPanel.setFocusable(true);
    return screensaverPanel;
}
private static layoutdemo createAndShowGUI(){ // method for creating and showing the GUI
    JFrame frame1 = new JFrame("layoutdemowithswitch");
    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    layoutdemo ldm = new layoutdemo();
    ldm.addComponenttoPane(frame1);
    frame1.pack();
    frame1.setVisible(true);
    frame1.getGraphicsConfiguration().getDevice().setFullScreenWindow(frame1);
    ldm.clo = (CardLayout) ldm.cards.getLayout();
    ldm.clo.show(ldm.cards, WELCOMEPANEL);
    return ldm;
}
public ActionListener timeoutPanelListener(Timer timer){ //listener for main screen timeout - returns to ads
    ActionListener timeout = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            CardLayout cl = (CardLayout) cards.getLayout();
            cl.show(cards, SCREENSAVERPANEL);
            timer.stop();
            changeTimer = new Timer(5000,changeImageListener(screenImage));
            changeTimer.start();

        }
    };
    return timeout;
}
    public ActionListener changeImageListener(JLabel image){ //listener for changing images in Screensaver
    ActionListener change = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            image.setIcon(new ImageIcon(getClass().getResource(FILEARRAY[INDEX])));
            INDEX++;
            if (INDEX >= FILEARRAY.length) INDEX = 0;

        }
    };
    return change;
}
public KeyListener stopScreensaver(){
    KeyListener key = new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
            CardLayout cl = (CardLayout) cards.getLayout();
            cl.show(cards, WELCOMEPANEL);
            Timer timer2 = new Timer(10000,null);
            ActionListener timeout = ldm.timeoutPanelListener(timer2);
            timer2.addActionListener(timeout);
            timer2.start();
            System.out.println("key typed");
        }

        @Override
        public void keyPressed(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {
            CardLayout cl = (CardLayout) cards.getLayout();
            cl.show(cards, WELCOMEPANEL);
            Timer timer2 = new Timer(10000,null);
            timer2.start();
            ActionListener timeout = ldm.timeoutPanelListener(timer2);
        }
    };
    return key;
    }

   public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, UnsupportedLookAndFeelException{
   UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
   invokeLater(new Runnable(){
       @Override
       public void run(){
           ldm = createAndShowGUI();      
           Timer timer = new Timer(5000,null);
           ActionListener timeout = ldm.timeoutPanelListener(timer);
           timer.addActionListener(timeout);
           timer.start();       
       }
   });
   }
}

1 个答案:

答案 0 :(得分:0)

使用CardLayout切换卡时,焦点未放在面板上。由于面板没有焦点,因此无法接收KeyEvents。

首先,您需要使面板具有可聚焦性。

其次,您需要在面板可见时给予焦点。查看Card Layout Focus。这是一个扩展CardLayout的类,当它变得可见时给予面板焦点。

相关问题