1

我有一个字符串数组,我试图在 Java Swing 组件中将其显示为幻灯片(一个一个)。我还试图在迭代之间添加延迟时间。

我试图通过使用 JTextArea 来做到这一点,并添加了一个动作侦听器。这是我现在拥有的代码:

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.
        }
    }
}

我的代码不起作用,因为 JTextArea 没有动作侦听器。

更新 说明:许多回复说我应该为 JTextArea 使用 ActionListener;但是,Eclipse 并没有告诉我 JTextArea 有一个名为 addActionListener 的方法。

我有点卡在这里,您认为哪个 Java Swing 组件最适合这种情况?

我的数组中的文本可能很长,因此单行标签不是一个好的选择。

我还有哪些其他选择或方法?

非常感谢,任何帮助和建议都非常感谢。

4

2 回答 2

5

这是基于@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) {
                }
            }
        }

    }

}

这是“Text.txt”文件的内容。

如何使用摆动计时器

Swing 计时器(javax.swing.Timer 的一个实例)在指定的延迟后触发一个或多个动作事件。不要将 Swing 计时器与 1.3 版中添加到 java.util 包中的通用计时器工具混淆。本页仅描述 Swing 计时器。

一般来说,我们建议使用 Swing 计时器而不是通用计时器来处理与 GUI 相关的任务,因为 Swing 计时器都共享相同的、预先存在的计时器线程,并且与 GUI 相关的任务会自动在事件调度线程上执行。但是,如果您不打算从计时器触摸 GUI,或者需要执行冗长的处理,则可以使用通用计时器。

您可以通过两种方式使用 Swing 计时器:

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.

摆动计时器非常易于使用。创建计时器时,您指定一个动作侦听器,以便在计时器“关闭”时得到通知。此侦听器中的 actionPerformed 方法应包含您需要执行的任何任务的代码。创建计时器时,您还可以指定计时器触发之间的毫秒数。如果您希望计时器只关闭一次,您可以在计时器上调用 setRepeats(false)。要启动计时器,请调用它的 start 方法。要暂停它,请调用 stop。

请注意,Swing 计时器的任务是在事件调度线程中执行的。这意味着任务可以安全地操作组件,但也意味着任务应该快速执行。如果任务可能需要一段时间才能执行,则考虑使用 SwingWorker 代替计时器或在计时器之外使用。有关使用 SwingWorker 类的说明以及在多线程程序中使用 Swing 组件的信息,请参阅 Swing 中的并发。

让我们看一个使用计时器定期更新组件的示例。TumbleItem 小程序使用计时器定期更新其显示。(要查看此小程序运行,请转到如何制作小程序。此小程序首先创建并启动一个计时器:

计时器=新计时器(速度,这个);timer.setInitialDelay(暂停); 计时器.start();

speed和pause变量代表小程序参数;如另一页所配置,分别为 100 和 1900,因此第一个计时器事件将在大约 1.9 秒内发生,并且每 0.1 秒重复一次。通过将 this 指定为 Timer 构造函数的第二个参数,TumbleItem 指定它是计时器事件的操作侦听器。

启动计时器后,TumbleItem 开始在后台线程中加载一系列图像。同时,定时器事件开始发生,导致 actionPerformed 方法执行:

public void actionPerformed(ActionEvent e) { //如果还在加载,不能动画。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();
} }

在加载图像之前,worker.isDone 返回 false,因此实际上忽略了计时器事件。事件处理代码的第一部分简单地设置动画控件的paintComponent 方法中使用的值:loopslot(动画中下一个图形的索引)和off(下一个图形的水平偏移量)。

最终,loopslot 将到达图像数组的末尾并重新开始。发生这种情况时,actionPerformed 末尾的代码会重新启动计时器。这样做会导致动画序列再次开始之前的短暂延迟。

于 2012-11-25T08:02:16.410 回答
4

将 yourActionListenerjavax.Swing.Timer. ActionListener分配给 的将Timer定期以指定的延迟时间调用。

有关更多信息,请参阅计时器教程

于 2012-11-25T07:03:09.807 回答