【问题标题】:JLabel scrolling textJLabel 滚动文本
【发布时间】:2026-02-11 23:35:01
【问题描述】:

我需要通过获取每个字母并将其从一个 jlabel 移动到下一个来制作一段沿页面滚动的文本。到目前为止,这是我的代码。它需要延迟,因为它太快了,但是当字符串完成时它似乎崩溃了。任何帮助将不胜感激?。

package Lab4;

import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

public class Scroll extends JFrame implements ActionListener {
final int scrollNumber = 10;
JTextField inputTextField = new JTextField(10);
JLabel[] output = new JLabel[scrollNumber];
JLabel text = new JLabel("Enter text and press Return",
        SwingConstants.CENTER);

public Scroll() {

    setLayout(new GridLayout(2, 1));
    JPanel row1 = new JPanel(new GridLayout(1, 10));

    output[0] = new JLabel();
    output[1] = new JLabel();
    output[2] = new JLabel();
    output[3] = new JLabel();
    output[4] = new JLabel();
    output[5] = new JLabel();
    output[6] = new JLabel();
    output[7] = new JLabel();
    output[8] = new JLabel();
    output[9] = new JLabel();

    row1.add(output[9]);
    row1.add(output[8]);
    row1.add(output[7]);
    row1.add(output[6]);
    row1.add(output[5]);
    row1.add(output[4]);
    row1.add(output[3]);
    row1.add(output[2]);
    row1.add(output[1]);
    row1.add(output[0]);

    add(row1);
    JPanel row2 = new JPanel(new GridLayout(1, 2));
    row2.add(text);
    row2.add(inputTextField);
    add(row2);

    inputTextField.addActionListener(this);

}

public void shift() {

    output[9].setText(output[8].getText());
    output[8].setText(output[7].getText());
    output[7].setText(output[6].getText());
    output[6].setText(output[5].getText());
    output[5].setText(output[4].getText());
    output[4].setText(output[3].getText());
    output[3].setText(output[2].getText());
    output[2].setText(output[1].getText());
    output[1].setText(output[0].getText());

}

public void run(String input) {
    int length = input.length();
    int i = 0;

    while (true) {

        if (output[0] != null) {
            output[0].setText(input.substring(i, i + 1));

        } else {
            output[0].setText("");
        }
        i = i + 1;
        System.out.println("0" + output[0].getText());
        System.out.println("1" + output[1].getText());
        System.out.println("2" + output[2].getText());
        System.out.println("3" + output[3].getText());
        System.out.println("4" + output[4].getText());
        System.out.println("5" + output[5].getText());
        System.out.println("6" + output[6].getText());
        System.out.println("7" + output[7].getText());
        System.out.println("8" + output[8].getText());
        System.out.println("9" + output[9].getText());
        shift();

    }
}

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == inputTextField) {

        String j = inputTextField.getText();
        run("abcdef");
        System.out.println(j);
    }

}

}

【问题讨论】:

    标签: java jframe jpanel jlabel


    【解决方案1】:

    首先。是的,您的应用程序崩溃了。从技术上讲,它是您在 run 方法中调用 input.substring(i, i + 1) 时得到的 IndexOutOfBoundsException。您在无限循环中增加i 而没有限制。因此它会比您的字符串长度更高,结果substring 然后抛出该异常。
    所以第一个修复是增加索引时的限制。

    [...]
    i = i + 1;
    if(i > length - 1)
        i = 0;
    

    下一个修复应该是延迟。但这并不像听起来那么容易。您应该开始学习Threads 如何在 Java 中工作,因为您需要开始学习。那是因为你永远不应该让你的主线程进入睡眠状态,否则你的 GUI 会变得不负责任。所以我会给你一个简单的解决方案,并提醒你学习线程是如何工作的。
    因此,删除您的 run 方法并更改您的 actionPerformed 方法,如下所示:

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == inputTextField) {
    
            String j = inputTextField.getText();
            // run("abcdef");
            new Thread(new Runnable(){
                @Override
                public void run() {
                    int length = j.length();
                    int i = 0;
                    while (true) {
                        if (output[0] != null) {
                            output[0].setText(j.substring(i, i + 1));
                        } else {
                            output[0].setText("");
                        }
                        i = i + 1;
                        if(i > length - 1)
                            i = 0;                                              
                        try {
                            Thread.sleep(500); // your delay in ms
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }                       
                        shift();                        
                    }               
                }           
            }).start();
        }
    }
    

    【讨论】:

    • 感谢您的帮助,但最后一个问题,我如何让它只运行一次?
    • 您需要为while 循环添加一个条件,以便在完成时结束。比如:int runs = 0; while (runs++ < ((length - 1) + output.length)) { [...] }.