卡布局最初会切换面板,为什么程序启动后不会切换?

时间:2016-08-01 19:15:53

标签: java swing jpanel cardlayout

所以我遇到了一种奇怪的错误。我正在使用卡片布局在GUI中的帮助面板和用户面板之间切换。在最初启动程序时,卡布局按预期工作,并且只要用户按下“H”就会切换,但如果单击任何按钮或键入文本字段,则无法再切换卡面板。我查看了oracle文档,但一无所获。有谁知道可能导致这个问题的原因?

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 javax.swing.JPanel;
import javax.swing.Timer;

public class MainPanel extends JPanel implements KeyListener{

    CardLayout cl = new CardLayout();
    userPanel up = new userPanel();
    HelpPanel hp = new HelpPanel();
    private boolean showUserPanel = true;

    private Timer mainTimer = new Timer(500, new ActionListener(){
        public void actionPerformed(ActionEvent event){
            up.setTipPercent();
        }
    });
//---------------------------------------------------------------------
//Constructor
    public MainPanel(){
        setLayout(cl);
        add(up, "userPanel");
        add(hp, "HelpPanel");
        cl.show(this, "userPanel");
        addKeyListener(this);
        setFocusable(true);
        mainTimer.start();
    }
//---------------------------------------------------------------------
//Key Listener Methods
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if(keyCode == e.VK_H && showUserPanel == true){
            cl.show(this, "HelpPanel");
            mainTimer.stop();
            showUserPanel = false;
        }else if(keyCode == e.VK_H && showUserPanel == false){
            cl.show(this, "userPanel");
            showUserPanel = true;
            mainTimer.start();
        }
    }

    @Override
    public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub

    }


}

这是userPanel

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;

//---------------------------------------------------------------------
public class userPanel extends JPanel{
    //Fields
    private JButton calc;
    private JRadioButton fiveP, tenP, fiftP, twenP;
    private ButtonGroup buttonGroup;
    private double tipAmount = 0.0;
    private JTextField tipArea;
    private JTextArea totalArea;

//---------------------------------------------------------------------         
//Constructor
    public userPanel(){
        setBackground(Color.BLACK);
        tipArea = new JTextField("Enter bill amount");
        totalArea = new JTextArea("");
        setupButtons();
        tipArea.setPreferredSize(new Dimension(300,40));
        totalArea.setPreferredSize(new Dimension(300,40));
    }
//---------------------------------------------------------------------
//Setup JComponents
    public void setupButtons(){
        calc = new JButton("Calculate the Tip");
        calc.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
                calculateTheTip(tipAmount);
            }
        });
        buttonGroup = new ButtonGroup();

        fiveP = new JRadioButton("Five Percent");
        tenP = new JRadioButton("Ten Percent");
        fiftP = new JRadioButton("Fifteen Percent");
        twenP = new JRadioButton("Twenty Percent");

        buttonGroup.add(fiveP);
        buttonGroup.add(tenP);
        buttonGroup.add(fiftP);
        buttonGroup.add(twenP);

        add(fiveP);
        add(tenP);
        add(fiftP);
        add(twenP);

        add(tipArea);
        add(totalArea);

        add(calc);
    }
//---------------------------------------------------------------------
//Calculate the total and display it to the user
public void calculateTheTip(double total){
    String theTotal = tipArea.getText();
    //Take user input and make sure it is a number
    try{
        double billAmount = Double.parseDouble(theTotal);
        total = billAmount*total;
        double totalAmt = billAmount + billAmount*tipAmount;
        totalArea.setText("Tip: "+total+ " \nTotal: " + totalAmt);
    }catch(NumberFormatException E){
        totalArea.setText("Please Enter only the amount without a $ or text!");
    }
    return;
}
//---------------------------------------------------------------------
//Chose which tipPercent to use     
    public void setTipPercent(){
        if(fiveP.isSelected()){
            tipAmount = .05;
        }else if(tenP.isSelected()){
            tipAmount = .1;
        }else if(fiftP.isSelected()){
            tipAmount = .15;
        }else{
            tipAmount = .2;
        }
    }
}

这是Help Panel

import java.awt.*;
import javax.swing.JPanel;

public class HelpPanel extends JPanel{
    public HelpPanel(){
        setBackground(Color.BLACK);
    }
}

2 个答案:

答案 0 :(得分:2)

按下按钮等会使焦点远离MainPanelKeyEvent被发送到具有焦点而不是MainPanel的对象。

我建议将KeyListener创建为单独的对象并将其添加到其他组件中。

答案 1 :(得分:1)

您的程序无法知道点击H是否意味着按下了更换卡的按键,或者您是否使用JTextField进行了写作。

对于您的问题,使用键绑定,它是最好的解决方案,因为它将焦点更改为您想要关注的组件。请阅读docs