我正在使用 CardLayout 来显示一系列问题。对于每个问题,标签上都会显示一个计时器。我通过了主课的问题和每个问题的时间限制。
//Reference - SynforgeTutorials
public class Quiz extends JFrame{
JPanel p=new JPanel();
CardLayout cards=new CardLayout();
int numQs;
int cardnumber;
CL1 questions[];
public static void main(String[] args) {
String[] messages = {"What is area of a circle?","When does spring start?","When is the next leap year?","How many days in a week?","What causes seasons?"};
int[] mins = {1,2,0,1,1};
int[] secs = {30,0,30,0,0};
new Quiz(messages,mins,secs);
}
public Quiz(String messages[],int mins[],int secs[]){
questions = new CL1[messages.length];
for(int i=0;i<questions.length;i++)
{
questions[i] = new CL1(messages[i],mins[i],secs[i],this);
}
p.setLayout(cards);
numQs=questions.length;
for(int i=0;i<numQs;i++){
p.add(questions[i],"q"+i);
}
cardnumber = 0;
cards.show(p,"q"+ cardnumber);
add(p);
setVisible(true);
}
public void OK(){
if(cardnumber==(numQs-1)){
this.dispose();
}
else{
cardnumber = cardnumber + 1;
cards.show(p,"q"+ cardnumber);
}
}
}
这是构造卡片的类。它有 3 个面板 - 顶部面板显示问题,中间面板在标签上显示分钟和秒以及暂停和恢复按钮,底部面板显示确定按钮。单击“确定”按钮后,将显示下一张卡片。
public class CL1 extends JPanel implements ActionListener {
int correctAns;
Quiz quiz;
int selected;
boolean used;
private Timer myTimer1;
public long initialTimeInSecs;
public long elapsedTime;
public long convertToSecs;
public String minutes;
public String seconds;
public String clockTimeString;
public static final int ONE_SEC = 1000;
Font myClockFont = new Font("Serif", Font.PLAIN, 20);
//Message
JPanel qPanel=new JPanel();
//Timer
JPanel tPanel=new JPanel();
JLabel timeLbl = new JLabel("New label");
JButton btnPause=new JButton("Pause");
JButton btnResume=new JButton("Resume");
//bottom
JPanel botPanel=new JPanel();
JButton OK=new JButton("OK");
public CL1(String q, int userMinutes, int userSeconds, Quiz quiz){
this.quiz=quiz;
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
//Message
qPanel.add(new JLabel(q));
add(qPanel);
//Timer
convertToSecs = (userMinutes * 60) + userSeconds;
initialTimeInSecs = convertToSecs;
elapsedTime = initialTimeInSecs;
seconds = Integer.toString((int)(elapsedTime % 60));
minutes = Integer.toString((int)((elapsedTime % 3600) / 60));
if (seconds.length() < 2)
seconds = "0" + seconds;
if (minutes.length() < 2)
minutes = "0" + minutes;
clockTimeString = (minutes+":"+seconds).toString();
timeLbl.setText(clockTimeString);
timeLbl.setFont(myClockFont);
timeLbl.setBorder(raisedbevel);
myTimer1 = new Timer(ONE_SEC,new ActionListener() {
public void actionPerformed(ActionEvent evt) {
initialTimeInSecs = initialTimeInSecs - 1;
elapsedTime = initialTimeInSecs;
String seconds = Integer.toString((int)(elapsedTime % 60));
String minutes = Integer.toString((int)((elapsedTime % 3600) / 60));
if (seconds.length() < 2)
seconds = "0" + seconds;
if (minutes.length() < 2)
minutes = "0" + minutes;
clockTimeString = (minutes+":"+seconds).toString();
timeLbl.setText(clockTimeString);
if(clockTimeString.equals("00:00"))
{
myTimer1.stop();
}
}
});
myTimer1.start();
btnPause.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
PauseBtnActionPerformed(evt);
}
});
btnResume.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
ResumeBtnActionPerformed(evt);
}
});
tPanel.add(timeLbl);
tPanel.add(btnPause);
tPanel.add(btnResume);
add(tPanel);
//bottom
OK.addActionListener(this);
botPanel.add(OK);
add(botPanel);
}
public void actionPerformed(ActionEvent e){
Object src=e.getSource();
//OK button
if(src.equals(OK)){
quiz.OK();}
}
public void PauseBtnActionPerformed(java.awt.event.ActionEvent evt)
{
myTimer1.stop();
}
public void ResumeBtnActionPerformed(java.awt.event.ActionEvent evt)
{
myTimer1.start();
}
}
计时器似乎不会随着每张新卡而刷新。每张卡都是并行开始的,这样当我从一张卡转到下一张卡时,新卡会显示第一张卡上已经过去的时间。
例如,对于问题 1,时间限制为 1.30 对于问题 2,时间限制为 2.00 对于问题 3,时间限制为 3.00
对话框首先显示第一个标签,并从 1.30 开始向下滴答。假设我在该标签上停留了 10 秒,然后按“确定”。
然后显示第二个标签,并且计时器开始从 1.50 开始计时(2.00-0.10,而不是 2.00)。假设我在这个问题上停留 25 秒,然后按“确定”。
然后显示第三个标签,计时器开始从 2.25 开始计时(3.00-(0.10+0.25),而不是 3.00)。
我想做两件事:
- 我希望每张卡片的计时器仅在显示该卡片时启动。
- 我希望卡在时间限制达到 00:00 后自动更改为下一张卡。
任何建议都会有帮助。提前致谢!
最佳答案
I want the timer for each card to start only when that card is shown.
您可以使用HierarchyListener
来监听每张卡片可见性的变化:
@Override
public void hierarchyChanged(HierarchyEvent e)
{
JComponent component = (JComponent)e.getSource();
if ((HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags()) != 0
&& component.isShowing())
{
// start the Timer
}
}
因此,您需要将 HierarchyListener
添加到添加到 CardLayout
的每个面板。
I want the card to automatically change to the next card
CardLayout
支持“下一张卡”功能,因此您只需在计时器达到 0 时调用相应的方法即可。
关于java - 卡片布局 : How to get an event to start only when a particular card is displayed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29479134/