JLabel отображает обратный отсчет, Java
У меня есть "статус" JLabel в одном классе (с именем Welcome) и таймер в другом (с именем Timer). Прямо сейчас, первый отображает слово "статус", а второй должен делать обратный отсчет. Я бы так хотел, но не знаю, как отобразить 10, 9, 8, 7 ... 0 (и перейти к следующему окну). Мои попытки пока:
// class Welcome
setLayout(new BorderLayout());
JPanel area = new JPanel();
JLabel status = new JLabel("status");
area.setBackground(Color.darkGray);
Font font2 = new Font("SansSerif", Font.BOLD, 25);
status.setFont(font2);
status.setForeground(Color.green);
area.add(status, BorderLayout.EAST); // can I put it in the bottom-right corner?
this.add(area);
и таймер:
public class Timer implements Runnable {
// public void runThread() {
// new Thread(this).start();
// }
public void setText(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setText(text); // link to status here I guess
}
});
}
public void run() {
for (int i = 10; i > 0; i--) {
// set the label
final String text = "(" + i + ") seconds left";
setText(text);
// // sleep for 1 second
// try {
// Thread.currentThread();
// Thread.sleep(1000);
// } catch (Exception ex) {
// }
}
// go to the next window
UsedBefore window2 = new UsedBefore();
window2.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// runThread();
}
} // end class
4 ответа
Я согласен, что вам следует рассмотреть возможность использования таймера "Java" в соответствии с Anh Pham, но на самом деле доступно несколько классов Timer, и для ваших целей таймер Swing, а не java.util.Timer, как предложено Anh, подойдет для ваших целей. Лучший.
Что касается вашей проблемы, то на самом деле это не более чем простая проблема ссылок. Дайте классу с меткой публичный метод, скажем setCountDownLabelText(String text)
и затем вызовите этот метод из класса, который содержит таймер. Вам нужно иметь ссылку на класс GUI с таймером JLabel в другом классе.
Например:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Welcome extends JPanel {
private static final String INTRO = "intro";
private static final String USED_BEFORE = "used before";
private CardLayout cardLayout = new CardLayout();
private JLabel countDownLabel = new JLabel("", SwingConstants.CENTER);
public Welcome() {
JPanel introSouthPanel = new JPanel();
introSouthPanel.add(new JLabel("Status:"));
introSouthPanel.add(countDownLabel);
JPanel introPanel = new JPanel();
introPanel.setPreferredSize(new Dimension(400, 300));
introPanel.setLayout(new BorderLayout());
introPanel.add(new JLabel("WELCOME", SwingConstants.CENTER), BorderLayout.CENTER);
introPanel.add(introSouthPanel, BorderLayout.SOUTH);
JPanel usedBeforePanel = new JPanel(new BorderLayout());
usedBeforePanel.setBackground(Color.pink);
usedBeforePanel.add(new JLabel("Used Before", SwingConstants.CENTER));
setLayout(cardLayout);
add(introPanel, INTRO);
add(usedBeforePanel, USED_BEFORE);
new HurdlerTimer(this).start();
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Welcome");
frame.getContentPane().add(new Welcome());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
public void setCountDownLabelText(String text) {
countDownLabel.setText(text);
}
public void showNextPanel() {
cardLayout.next(this);
}
}
class HurdlerTimer {
private static final int TIMER_PERIOD = 1000;
protected static final int MAX_COUNT = 10;
private Welcome welcome; // holds a reference to the Welcome class
private int count;
public HurdlerTimer(Welcome welcome) {
this.welcome = welcome; // initializes the reference to the Welcome class.
String text = "(" + (MAX_COUNT - count) + ") seconds left";
welcome.setCountDownLabelText(text);
}
public void start() {
new Timer(TIMER_PERIOD, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (count < MAX_COUNT) {
count++;
String text = "(" + (MAX_COUNT - count) + ") seconds left";
welcome.setCountDownLabelText(text); // uses the reference to Welcome
} else {
((Timer) e.getSource()).stop();
welcome.showNextPanel();
}
}
}).start();
}
}
Поскольку вы используете Swing, вы должны использовать javax.swing.Timer, а не java.util.Timer. Вы можете установить таймер на срабатывание с интервалом в 1 секунду (1000 мс), и ваш слушатель сделает обновление. Поскольку обновления Swing должны происходить в потоке рассылки событий, ваш слушатель является идеальным местом для status.setText
,
В Java уже есть класс Timer: http://www.exampledepot.com/egs/java.util/ScheduleRepeat.html
Почему бы не поместить метод setText в класс приветствия и просто сделать "status.setText(text)"?
И вы можете попробовать BorderLayout.SOUTH или.PAGE END или.LINE END, чтобы получить таймер в правом нижнем углу