Java使用Timer实现操作间延迟 模拟老虎机效果问题求助
问题分析
- 核心逻辑错误:Swing Timer 每次触发仅会执行一次你绑定的回调方法,你在单次回调中一次性执行了
Slot1()到Slot4()四个方法,所有界面文本修改操作会被Swing合并为一次重绘,你只能看到Slot4()执行后的最终结果,看不到中间的切换过程,自然没有滚动效果。 - 无效冗余逻辑:
NUMBER变量在Timer回调和每个Slot方法中都被重复自增,但你没有用它控制当前显示的帧状态,属于完全无用的逻辑。
修正方案
调整Timer回调逻辑,每次触发仅更新一次界面状态,用计数器控制当前显示的滚动帧,即可实现每500ms切换一次内容的滚动效果。如果需要更贴近真实老虎机的体验,可以后续添加滚动速度逐渐降低、逐个标签停止滚动的逻辑。
完整可运行代码
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Window implements ActionListener { Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); JFrame MAIN = new JFrame("Test"); String[] Names = { "Name1", "Name2", "Name3", "Name4" }; JButton B_Start = new JButton(); // 用来记录当前滚动的步数 int rollStep = 0; Timer timer; JLabel Name1 = new JLabel(Names[0]); JLabel Name2 = new JLabel(Names[1]); JLabel Name3 = new JLabel(Names[2]); JLabel Name4 = new JLabel(Names[3]); public static void main(String[] args) { new Window().window(); } public void window() { MAIN.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); MAIN.setLayout(null); MAIN.setResizable(false); MAIN.setSize( 665, 519); MAIN.setForeground(Color.BLACK); MAIN.getContentPane().setBackground(Color.decode("#008080")); int x = (int) ((dimension.getWidth() - MAIN.getWidth()) / 2); int y = (int) ((dimension.getHeight() - MAIN.getHeight()) / 2 - 100); MAIN.setLocation(x,y); MAIN.setVisible(true); B_Start.setBounds(250, 110, 300, 300); Name1.setBounds(100,125,200,40); Name2.setBounds(100,200,200,40); Name3.setBounds(100,275,200,40); Name4.setBounds(100,350,200,40); Name1.setFont(new Font("SnowCaps", Font.BOLD, 30)); Name2.setFont(new Font("SnowCaps", Font.BOLD, 30)); Name3.setFont(new Font("SnowCaps", Font.BOLD, 30)); Name4.setFont(new Font("SnowCaps", Font.BOLD, 30)); MAIN.add(B_Start); MAIN.add(Name1); MAIN.add(Name2); MAIN.add(Name3); MAIN.add(Name4); B_Start.addActionListener(this); timer = new Timer(500, new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ rollStep++; // 每次Timer触发仅更新一次界面 updateSlot(); // 如果需要滚动指定次数后自动停止,可以在这里加判断,比如rollStep到20就调用timer.stop() } }); } public void updateSlot(){ // 根据当前步数模4的结果切换显示内容 int offset = rollStep % 4; Name1.setText(Names[(0 + offset) %4]); Name2.setText(Names[(1 + offset) %4]); Name3.setText(Names[(2 + offset) %4]); Name4.setText(Names[(3 + offset) %4]); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == B_Start) { if(!timer.isRunning()) timer.start(); else timer.stop(); } } }
内容的提问来源于stack exchange,提问作者CodeMasterOver9000
相关产品推荐
相关产品推荐

