【问题标题】:Methods in JLabelsJLabels 中的方法
【发布时间】:2017-05-03 05:12:20
【问题描述】:

我需要一种简单的方法来制作可以在 JLabel 中使用的方法。我想做一个 .write(some text);每当我调用 jLabel.write(some text);它一个字母一个字母地写出一些文本。我可以使用控制台轻松地做到这一点,但我现在知道如何在 JLabel 中做到这一点。

示例代码:

public void write(String a) {
    char letter;
    String word = "";
    for(int i = 0; i < a.length(); i++) {
        letter = a.charAt(i);
        this.setText(word + letter);
        word = word + letter;
        try {
            Thread.sleep(100);
        } catch(Exception e) {
        }
    }
}

...

text.write("Hello");

由于显而易见的原因,这不起作用。但是有什么办法吗?

【问题讨论】:

标签: java swing methods jlabel


【解决方案1】:

这是你想要得到的标签的完整示例:

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

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class JPrintLabel extends JLabel {

    private Dimension storedSize;

    private Timer printTimer;

    public void write(final String text) {
        // stop old timer if required
        if (printTimer != null) {
            printTimer.stop();
        }
        // compute size
        if (!isPreferredSizeSet()) {
            setText(text);
            storedSize = getPreferredSize();
            setText("");
        }
        printTimer = new Timer(200, new ActionListener() {
            int counter;
            @Override
            public void actionPerformed(ActionEvent e) {
                if (counter >= text.length()) {
                    printTimer.stop();
                    printTimer = null;
                } else {
                    setText(text.substring(0, ++counter));
                }
            }
        });
        printTimer.start();
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || storedSize == null) {
            return super.getPreferredSize();
        } else {
            return storedSize;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frm = new JFrame("Test print");
                JPrintLabel pl = new JPrintLabel();
                frm.add(pl);
                pl.write("Here is the text, we want to print!");
                frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frm.pack();
                frm.setLocationRelativeTo(null);
                frm.setVisible(true);
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    为此,我们需要 4 个步骤:

    • 1) 创建一个扩展 JLabel 的新类,
    • 2) 添加一个计时器和一个方法来写文本
    • 3) 创建自定义 JLabel 的实例,然后
    • 4) 使用你的 write 方法

    第 1 步和第 2 步的新类和方法:

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JLabel;
    import javax.swing.Timer;
    
    public class MyCustomJLabel extends JLabel{
        private String text = "";
    
        public void write(String textToWrite) {
            int delay = 1000; //milliseconds
            ActionListener taskPerformer = new ActionListener(){
                int characterCount = 0;
                public void actionPerformed(ActionEvent evt){
                    if (characterCount == textToWrite.length())
                    {
                        ((Timer)evt.getSource()).stop();
                    }
                    getThisLabel().setText(textToWrite.substring(0, characterCount));
                    characterCount++;
                }
            };
            new Timer(delay, taskPerformer).start();
        }
    
        private MyCustomJLabel getThisLabel(){
            return this;
        }
    }
    

    您的主要方法中的新方法执行第 3 步:

    MyCustomJLabel myLabel = new MyCustomJLabel():
    myForm.add(myLabel);
    

    第4步,你可以使用myLabel.write来做你的方法:

    myLabel.write("my text to print 1 letter at a time");
    

    感谢 Sergiy Medvynskyy 的评论,代码已更正。

    【讨论】:

    • 您的代码错误:您将在大约 3 秒内一次性打印出所有文本。没有一个字母一个字母的模式。此外,您应该覆盖 getPreferredSize() 方法以提供正确的文本大小。
    • @SergiyMedvynskyy 是的,我已经纠正了我的答案以延迟正确打印,但会让getPreferredSize() 使用默认行为,因为 OP 可能应该使用布局管理器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    相关资源
    最近更新 更多