Displaying contents of String array in Swing compo

2019-01-15 22:02发布

I have an array of strings which I'm trying to display (one by one) as a slideshow in a Java Swing component. I am also trying to add a delay time between the iterations.

I attempted to do this by using a JTextArea, with an action listener added to it. Here is the code I have right now:

private class myActionListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        // A BUNCH OF TEXT PROCESSING

        //NOTE: myInfo.getContents() returns an ArrayList<myType>.
        Iterator<myType> iterator = myInfo.getContents().iterator();

        int i = 0;
        while (iterator.hasNext()) {
            myTextArea.setText(iterator.next().toString());
            // to add time betweeen iterations i wanted to use the thread
            // delay method.
        }
    }
}

My code is not working because JTextArea doesn't have an action listener.

UPDATE NOTE: Many replies stated that I should use an ActionListener for the JTextArea; However, Eclipse is not showing me that JTextArea has a method called addActionListener.

I'm kind of stuck here, which Java Swing component do you think would be the most suitable in this scenario?

The text in my array may be long, so a one lined label would not be a good choice.

What other alternatives or approaches do I have?

Thank you very much, any help and suggestions are appreciated.

2条回答
再贱就再见
2楼-- · 2019-01-15 22:32

Use your ActionListener in combination with a javax.Swing.Timer. The ActionListener assigned to the Timer will be called on regular intervals with the specified delay.

See the timer tutorial for more information

查看更多
\"骚年 ilove
3楼-- · 2019-01-15 22:45

This is basic example is based on the suggestion posted by @Robin

public class TestDisplayString {

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

    public TestDisplayString() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        private JTextArea textArea;
        private List<String> content;
        private Iterator<String> iterator;

        public TestPane() {
            readText();
            setLayout(new BorderLayout());
            textArea = new JTextArea(10, 40);
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
            add(new JScrollPane(textArea));
            iterator = content.iterator();

            Timer timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (iterator.hasNext()) {
                        textArea.setText(iterator.next());
                    } else {
                        ((Timer)e.getSource()).stop();
                    }
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

        protected void readText() {
            content = new ArrayList<>(25);
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/Text.txt")));
                String text = null;
                while ((text = reader.readLine()) != null) {
                    if (text.trim().length() > 0) {
                        content.add(text);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    reader.close();
                } catch (Exception e) {
                }
            }
        }

    }

}

This is the contents of the "Text.txt" file.

How to Use Swing Timers

A Swing timer (an instance of javax.swing.Timer) fires one or more action events after a specified delay. Don't confuse Swing timers with the general-purpose timer facility that was added to the java.util package in release 1.3. This page describes only Swing timers.

In general, we recommend using Swing timers rather than general-purpose timers for GUI-related tasks because Swing timers all share the same, pre-existing timer thread and the GUI-related task automatically executes on the event-dispatch thread. However, you might use a general-purpose timer if you don't plan on touching the GUI from the timer, or need to perform lengthy processing.

You can use Swing timers in two ways:

To perform a task once, after a delay.
For example, the tool tip manager uses Swing timers to determine when to show a tool tip and when to hide it.
To perform a task repeatedly.
For example, you might perform animation or update a component that displays progress toward a goal.

Swing timers are very easy to use. When you create the timer, you specify an action listener to be notified when the timer "goes off". The actionPerformed method in this listener should contain the code for whatever task you need to be performed. When you create the timer, you also specify the number of milliseconds between timer firings. If you want the timer to go off only once, you can invoke setRepeats(false) on the timer. To start the timer, call its start method. To suspend it, call stop.

Note that the Swing timer's task is performed in the event dispatch thread. This means that the task can safely manipulate components, but it also means that the task should execute quickly. If the task might take a while to execute, then consider using a SwingWorker instead of or in addition to the timer. See Concurrency in Swing for instructions about using the SwingWorker class and information on using Swing components in multi-threaded programs.

Let's look at an example of using a timer to periodically update a component. The TumbleItem applet uses a timer to update its display at regular intervals. (To see this applet running, go to How to Make Applets. This applet begins by creating and starting a timer:

timer = new Timer(speed, this); timer.setInitialDelay(pause); timer.start();

The speed and pause variables represent applet parameters; as configured on the other page, these are 100 and 1900 respectively, so that the first timer event will occur in approximately 1.9 seconds, and recur every 0.1 seconds. By specifying this as the second argument to the Timer constructor, TumbleItem specifies that it is the action listener for timer events.

After starting the timer, TumbleItem begins loading a series of images in a background thread. Meanwhile, the timer events begin to occur, causing the actionPerformed method to execute:

public void actionPerformed(ActionEvent e) { //If still loading, can't animate. if (!worker.isDone()) { return; }

loopslot++;

if (loopslot >= nimgs) {
    loopslot = 0;
    off += offset;

    if (off < 0) {
        off = width - maxWidth;
    } else if (off + maxWidth > width) {
        off = 0;
    }
}

animator.repaint();

if (loopslot == nimgs - 1) {
    timer.restart();
} }

Until the images are loaded, worker.isDone returns false, so timer events are effectively ignored. The first part of the event handling code simply sets values that are employed in the animation control's paintComponent method: loopslot (the index of the next graphic in the animation) and off (the horizontal offset of the next graphic).

Eventually, loopslot will reach the end of the image array and start over. When this happens, the code at the end of actionPerformed restarts the timer. Doing this causes a short delay before the animation sequence begins again.

查看更多
登录 后发表回答