highlighting the word in java

两盒软妹~` 提交于 2019-12-01 11:59:31
David Kroukamp

I dont think you understand me.

Using my newest example I made this one (note this is updated code from example in last question. Now uses Swing Timers only):

private int[] timings = {2000, 4000, 0, 3000, 2000};//word timings
private String[] words = {"Hel", "lo", " ", "wor", "ld"};//each indiviaul word

private String sentence = "Hello world";//entire string for writing to JSCrollPane

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;

public class KaraokeTest {

    private int[] timings = {2000, 4000, 0, 3000, 2000};//word timings
    private String[] words = {"Hel", "lo", " ", "wor", "ld"};//each indiviaul word
    private String sentence = "Hello world";//entire string for writing to JSCrollPane
    private DefaultHighlighter.DefaultHighlightPainter highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
    private int count = 0;
    private boolean fisrTime = true;
    private JFrame frame;
    private JTextPane jtp;
    private JButton startButton;
    private AtomicBoolean done = new AtomicBoolean(false);

    public KaraokeTest() {
        initComponents();
    }

    private void initComponents() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);

        jtp = new JTextPane();

        jtp.setText(sentence);
        jtp.setEditable(false);

        startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                startKaraoke();
            }
        });

        frame.add(jtp, BorderLayout.CENTER);
        frame.add(startButton, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
    }

    private void startKaraoke() {
        if (fisrTime) {
            startButton.setEnabled(false);
            fisrTime = false;
        }

        createAndStartTimer(timings[count], count);

        Timer t = new Timer(1, new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (done.get()) {
                    count++;
                    if (count == timings.length) {
                        JOptionPane.showMessageDialog(frame, "Done");
                        startButton.setEnabled(true);
                        count = 0;
                        fisrTime = true;
                        done.getAndSet(false);
                        ((Timer) ae.getSource()).stop();
                    } else {
                        ((Timer) ae.getSource()).stop();
                        startKaraoke();
                    }
                }
            }
        });
        done.getAndSet(false);//to synchronize when the remove highlight timer is done so a clash between adding highlights before the timer is done doesnt occur
        t.start();
    }

    private void createAndStartTimer(int delay, final int count) {
        int sp = 0;
        for (int i = 0; i < count; i++) {
            sp += words[i].length();
        }
        try {
            jtp.getHighlighter().addHighlight(sp, sp + words[count].length(), highlightPainter);
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }

        Timer t = new Timer(delay, new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                jtp.getHighlighter().removeAllHighlights();
                done.getAndSet(true);//so that out other timer knows we are done completly and can add new higlights
            }
        });
        t.setRepeats(false);
        t.start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new KaraokeTest();
            }
        });
    }
}

You can achieve this with one Timer as well by simply adjusting the delay for the Timer. Just took the code from @DavidKroukamp and removed one of the Timer instances

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicBoolean;

public class KaraokeTest {

  private int[] timings = {2000, 4000, 0, 3000, 2000};//word timings
  private String[] words = {"Hel", "lo", " ", "wor", "ld"};//each indiviaul word
  private String sentence = "Hello world";//entire string for writing to JSCrollPane
  private DefaultHighlighter.DefaultHighlightPainter highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
  private boolean fisrTime = true;
  private JFrame frame;
  private JTextPane jtp;
  private JButton startButton;
  private AtomicBoolean done = new AtomicBoolean(false);

  public KaraokeTest() {
    initComponents();
  }

  private void initComponents() {
    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);

    jtp = new JTextPane();

    jtp.setText(sentence);
    jtp.setEditable(false);

    startButton = new JButton("Start");
    startButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent ae) {
        startKaraoke();
      }
    });

    frame.add(jtp, BorderLayout.CENTER);
    frame.add(startButton, BorderLayout.SOUTH);

    frame.pack();
    frame.setVisible(true);
  }

  private void startKaraoke() {
    if (fisrTime) {
      startButton.setEnabled(false);
      fisrTime = false;
    }

    Timer t = new Timer( timings[0], new ActionListener() {
      private int currentIndex = 0;
      @Override
      public void actionPerformed( ActionEvent e ) {
        clearHighlights();
        highlightWord( currentIndex );
        currentIndex++;
        if ( currentIndex < timings.length ){
          ( ( Timer ) e.getSource() ).setDelay( timings[currentIndex] );
          ( ( Timer ) e.getSource() ).restart();
        } else {
          ( ( Timer ) e.getSource() ).stop();
        }
      }
    } );
    t.setRepeats( true );

    t.start();
  }

  private void highlightWord( int index ){
    int sp = 0;
    for (int i = 0; i < index; i++) {
      sp += words[i].length();
    }
    try {
      jtp.getHighlighter().addHighlight(sp, sp + words[index].length(), highlightPainter);
    } catch (BadLocationException ex) {
      ex.printStackTrace();
    }
  }
  private void clearHighlights(){
    jtp.getHighlighter().removeAllHighlights();
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        new KaraokeTest();
      }
    });
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!