简体   繁体   中英

Issues with CardLayout using Keylistener in java

To start with ,i have 2 classes Runtest and Front extended with Jpanel . what i'm trying to do is switch these 2 panel with a keylistener (ENTER key ) , but its just static and not changing , here's the code so far ,

import static com.sun.java.accessibility.util.AWTEventMonitor.addKeyListener;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;


public class Pactest implements ActionListener , KeyListener{

     JFrame frame = new JFrame("Test");
     Runtest test ;
     Front front = new Front();
     CardLayout cardpane = new CardLayout();
     int key ;


   public Pactest() throws IOException, UnsupportedAudioFileException, LineUnavailableException {


        addKeyListener(this);

         this.test = new Runtest();
         frame.setLayout(cardpane);
         frame.setSize(355, 520);
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.add(front);
         frame.add(test);
         frame.setVisible(true);
         frame.setResizable(false);  

         cardpane.show(front, "1");



   }


@Override
public void actionPerformed(ActionEvent ae) {
    if(key == KeyEvent.VK_ENTER){
     cardpane.next(frame); 

     }
}

@Override
public void keyTyped(KeyEvent ke) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of    generated methods, choose Tools | Templates.
}

@Override
public void keyPressed(KeyEvent ke) {
    key = ke.getKeyCode();

}
@Override
public void keyReleased(KeyEvent ke) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
} 


   public static void main(String[] args) throws IOException,              UnsupportedAudioFileException, LineUnavailableException {

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

           new Pactest() ;

      }

  }); 
 }

Your code shouldn't even compile as you're calling addKeyListener(...) in a class that doesn't have this method since it does not extend from Component or JComponent:

public class Pactest implements ActionListener , KeyListener{

     JFrame frame = new JFrame("Test");
     Runtest test ;
     Front front = new Front();
     CardLayout cardpane = new CardLayout();
     int key ;

   public Pactest() throws IOException, UnsupportedAudioFileException, LineUnavailableException {
        addKeyListener(this);

In the future, if you're asking about code with compilation issues, please tell us about these, issues, post all error messages, and indicate which lines are involved with the errors.

Once you fix this, a better solution is to use Key Bindings, since with Key Bindings you can get around most all of the problems KeyListeners have with focus. Please have a look at the Key Bindings Tutorial for more.


More concrete suggestions:

  • Note that if you add the CardLayout to a JFrame, you're actually adding it to the JFrame's contentPane, not the JFrame itself, and this can mess you up down the road.
  • Instead add the CardLayout to a JPanel, and then add "cards" (often other JPanels) to that same JPanel.
  • When calling CardLayout methods, you must pass in the container that uses it, the very same JPanel described above.
  • Then add the CardLayout-using JPanel to your JFrame where desired.
  • Again, use Key Bindings, not a KeyListener, because Key Bindings, if set correctly, can work even if the bound component doesn't have the focus.

HovercraftFullOfEels is correct +1, you should not be using KeyListener for this task, there are just to many issues relating to current focus...

You are also not using CardLayout properly and should take a closer look at How to Use CardLayout for more details.

The overall problem I have with your idea is that is is not obvious to the user...unless they "know" they have to press Enter , how will they know how to move to the next view. Even then, if a component (like a text component or button) is using Enter for it's own needs, this could either prevent your key listener/binding from been notified at best and at worse, trip the use to the next view BEFORE they are ready...

Another choice might be to supply a "Next" button, which is set as the "default" button, which provides the same functionality, but also provides the means with which the user can understand what they are doing...

没有手

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Pactest {

    JFrame frame = new JFrame("Test");
    JLabel test = new JLabel("RunTest");
    JLabel front = new JLabel("Front");
    CardLayout cardpane = new CardLayout();
    int key;

    private JButton next;
    private JPanel cards;

    public Pactest() throws IOException, UnsupportedAudioFileException, LineUnavailableException {

        cards = new JPanel(cardpane);
        cards.add(front, "1");
        cards.add(test, "2");

        frame.add(cards);
        frame.setSize(355, 520);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setResizable(false);

        cardpane.show(cards, "1");

        next = new JButton("Next");
        frame.add(next, BorderLayout.SOUTH);
        next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                cardpane.next(cards);
            }
        });

        frame.getRootPane().setDefaultButton(next);

    }

    public static void main(String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException {

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

                try {
                    new Pactest();
                } catch (IOException | UnsupportedAudioFileException | LineUnavailableException ex) {
                    Logger.getLogger(Pactest.class.getName()).log(Level.SEVERE, null, ex);
                }

            }

        });

    }
}

Take a look at How to Use Root Panes for more details

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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