Make a typewriter effect in a jlabel

Tags: , , ,



This is my JPanel which I’m adding in a JFrame, but the code that write letter per letter but when executed freezes and sometime later, the text appears, the text is not writing with that effect, but I think it should be working, why?

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package vista;

import java.awt.Image;
import javax.swing.ImageIcon;
import static paladins.nut.and.crush.panelver.PaladinsNutAndCrushPanelVer.mainPanel;

public class sceneKonami extends javax.swing.JPanel {

    String ruta = "src/backgrounds/soniabelmont.png";
    String ruta1 = "src/backgrounds/legends.png";
    ImageIcon fondo = new ImageIcon(new ImageIcon(ruta).getImage().getScaledInstance(1280, 720, Image.SCALE_DEFAULT));
    ImageIcon fondo1 = new ImageIcon(new ImageIcon(ruta1).getImage().getScaledInstance(730, 250, Image.SCALE_DEFAULT));
   
    public sceneKonami() {
        initComponents();
        loader();

        

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        texter = new javax.swing.JLabel();
        castlevania = new javax.swing.JLabel();
        background = new javax.swing.JLabel();

        setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        add(jButton1, new org.netbeans.lib.awtextra.AbsoluteConstraints(240, 370, -1, -1));
        add(texter, new org.netbeans.lib.awtextra.AbsoluteConstraints(184, 77, 1050, 510));
        add(castlevania, new org.netbeans.lib.awtextra.AbsoluteConstraints(50, 30, 730, 250));
        add(background, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 1280, 720));
    }// </editor-fold>                        

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
      String message = "Sonia Belmont is waiting, nShe will appear soon. nIn a great adventure";
      slowPrint(message);
                                
    }                                        

    public static void slowPrint(String message) {
        
        char[] chars = message.toCharArray();
        for (int i = 0; i < chars.length; i++) {

            texter.setText(texter.getText() + String.valueOf(message.charAt(i)));
            mainPanel.repaint();
            mainPanel.revalidate();
            System.out.println(message.charAt(i));

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // Variables declaration - do not modify                     
    private javax.swing.JLabel background;
    private javax.swing.JLabel castlevania;
    private javax.swing.JButton jButton1;
    private static javax.swing.JLabel texter;
    // End of variables declaration                   

    private void loader() {
        background.setIcon(fondo);
        castlevania.setIcon(fondo1);
    }
}

when the program run and i press the buttom to run the type writter eefect, the program got freeze and sometime later the text appears

Answer

The following is mre (1) of what you are trying to achieve, using a swing Timer:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;

public class SwingMain {

    SwingMain() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.add(new SceneKonami());
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new SwingMain();
    }
}

class SceneKonami extends javax.swing.JPanel {

    private int index = 0;
    private javax.swing.Timer timer;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel texter;

    public SceneKonami() {
        initComponents();
    }

    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        texter = new javax.swing.JLabel();
        setLayout(new BorderLayout(5,5));
        jButton1.setText("Type Message");
        jButton1.addActionListener(evt -> jButton1ActionPerformed(evt));
        add(jButton1, BorderLayout.SOUTH);
        add(texter, BorderLayout.NORTH);
        setPreferredSize(new Dimension(400,150));
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        String message = "Sonia Belmont is waiting, nShe will appear soon. nIn a great adventure";
        slowPrint(message);
    }

    public void slowPrint(String message) {

        if(timer != null && timer.isRunning()) return;
        index   = 0;
        texter.setText("");

        timer = new javax.swing.Timer(100,new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                texter.setText(texter.getText() + String.valueOf(message.charAt(index)));
                index++;
                if (index >= message.length()) {
                    timer.stop();
                }
            }
        });
        timer.start();
    }
}

(1) Always consider posting an MRE when asking and answering.


Source: stackoverflow