【问题标题】:Effective way to delay in JavaJava中延迟的有效方法
【发布时间】:2017-05-28 04:08:30
【问题描述】:

我需要创建一个简单的延迟(3-5 秒),以便在处理之前可以读取窗口。

我在网上找到了一百万个示例,但它们似乎都给了我同样的问题。我的代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel;

public class GrantedPane extends JPanel {

private static final long serialVersionUID = 1L;

public GrantedPane() {

    JFrame frame = new JFrame();
    frame.setUndecorated(true);
    frame.setSize(400, 150);
    frame.setContentPane(this);
    frame.setLocationRelativeTo(null);
    frame.setSize(400, 80);

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    setBorder(new CompoundBorder(BorderFactory.createLineBorder(Color.WHITE), new EmptyBorder(20, 20, 20, 20)));

    JLabel grantTitle = new JLabel(" Key Accepted ");
    grantTitle.setForeground(Color.YELLOW);
    grantTitle.setFont(new Font("Enter The Grid", Font.PLAIN, 32));
    grantTitle.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(grantTitle);
    frame.setVisible(true);
            delay(3);
            frame.dispose();
}

@Override
protected void paintComponent(Graphics g) {
    int w = getWidth(), h = getHeight();
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    GradientPaint gp = new GradientPaint(0, 0, Color.BLACK, 0, h, Color.GRAY);
    g2d.setPaint(gp);
    g2d.fillRect(0, 0, w, h);
}

    void delay (int sec){   
    try {
        TimeUnit.SECONDS.sleep(sec);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

所以这个问题(以及我尝试过的所有其他类型的技术,包括绝望行为中的嵌套 FOR 循环......)是窗口永远不会出现。

我假设这是因为在frame.setVisible() 生效之前就发生了睡眠。我试过wait() 也有同样的效果。

有人可以帮我解决这个问题吗?

编辑--

这是我实例化它的方式(在另一个类中)。在此之前的屏幕变为绿色,然后启动“已接受”窗口。该程序有 8 个类,否则我会把整个事情都扔掉。请注意,我在实例化时收到“未使用”警告,但我不知道为什么。

    void validCode() {
        color1 = Color.GREEN;
        color2 = Color.GREEN;
        repaint();
        GrantedPane granted = new GrantedPane();
    }

【问题讨论】:

  • 你试过sleep()吗?
  • @user3226170 你试过用 sleep() 的线程吗?
  • 假设使用Thread sleep() 是理想的。这个post 很好参考。
  • 在尝试提出更多问题之前,请阅读How do I ask a good question?
  • “所以这个问题(以及我尝试过的所有其他类型的技术,包括绝望的嵌套 FOR 循环......)的问题是窗口永远不会出现。” - 这是因为您似乎尝试过的每个解决方案都在阻止 EDT。请参阅Concurrency in Swing 了解更多详细信息,How to use Swing Timers 了解典型解决方案

标签: java swing


【解决方案1】:

您是否在任何地方实例化了该类?添加了一个主要方法并更新了导入。它工作正常。

import java.util.concurrent.TimeUnit;
import java.awt.*;

import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class GrantedPane extends JPanel {

private static final long serialVersionUID = 1L;

public GrantedPane() {

    JFrame frame = new JFrame();
    frame.setUndecorated(true);
    frame.setSize(400, 150);
    frame.setContentPane(this);
    frame.setLocationRelativeTo(null);
    frame.setSize(400, 80);

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    setBorder(new CompoundBorder(BorderFactory.createLineBorder(Color.WHITE), new EmptyBorder(20, 20, 20, 20)));

    JLabel grantTitle = new JLabel(" Key Accepted ");
    grantTitle.setForeground(Color.YELLOW);
    grantTitle.setFont(new Font("Enter The Grid", Font.PLAIN, 32));
    grantTitle.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(grantTitle);
    frame.setVisible(true);
    delay(3);
    frame.dispose();
}

@Override
protected void paintComponent(Graphics g) {
    int w = getWidth(), h = getHeight();
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    GradientPaint gp = new GradientPaint(0, 0, Color.BLACK, 0, h, Color.GRAY);
    g2d.setPaint(gp);
    g2d.fillRect(0, 0, w, h);
}

    void delay (int sec){

    try {
        TimeUnit.SECONDS.sleep(sec+2);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

    public static void main(String args[]){
        GrantedPane d = new GrantedPane();
    }
}

【讨论】:

  • 是的,在我添加 delay() 之前,它可以完美运行,然后我就会遇到问题。
  • 你能分享一下你在哪里实例化了这个类吗?我分享的代码也完美运行,延迟(我尝试改变延迟并得到正确的结果)
  • @user3226170 您得到了未使用的警告,因为您在创建后没有在任何地方使用“授权”实例。您到达函数的末尾。
  • 因为GrantedPane 没有在EDT 的上下文中被调用,所以你没有阻止整个UI,Swing Timer 通常是一个更安全的解决方案
【解决方案2】:

这里没有答案:从用户体验方面来看,您的想法没有意义。当然,从技术角度来看,它提供了一些学习以使其发挥作用。但除此之外,你用这种方法浪费你的时间。

例如,放置一个模态选项对话框,而不是自动显示和删除框架。只需要求用户在完成阅读后单击一个按钮。

您知道,这就是超时的问题:您永远无法为所有您的用户正确设置超时!如果延迟足够长,以至于 99% 的用户可以阅读消息,那么可能有 50% 的用户会抱怨你的 UI 让他们等待的时间过长。 (那 1% 的人分心,从未注意到自动关闭窗口)。

您最不想要的就是:感觉您的应用程序正在减慢他们的速度的用户。有众所周知的最佳实践来向用户呈现消息。自动显示和删除它们不在最佳实践列表中。

【讨论】:

  • 赞成:我也非常不喜欢程序响应时间的延迟,无论是有意还是无意。
  • 赞成:有时不回答是最好的,n'est pas?
  • 有时。我也考虑过事件调度线程的问题,但我决定阻止操作员深入挖掘他拼命试图打开的那个洞。
【解决方案3】:

所以这个问题(以及我尝试过的所有其他类型的技术,包括绝望行为中的嵌套 FOR 循环......)是窗口永远不会出现。

这是因为您似乎尝试过的每个解决方案都在阻止 EDT。有关更多详细信息,请参阅 Concurrency in SwingHow to use Swing Timers 以了解在 Swing 中对用户安全的典型解决方案(不会阻止 EDT,可用于安全更新 UI)

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class GrantedPane extends JPanel {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new GrantedPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(3000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        frame.dispose();
                    }
                });
                timer.start();
            }
        });
    }

    private static final long serialVersionUID = 1L;

    public GrantedPane() {

        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        setBorder(new CompoundBorder(BorderFactory.createLineBorder(Color.WHITE), new EmptyBorder(20, 20, 20, 20)));

        JLabel grantTitle = new JLabel(" Key Accepted ");
        grantTitle.setForeground(Color.YELLOW);
        grantTitle.setFont(new Font("Enter The Grid", Font.PLAIN, 32));
        grantTitle.setAlignmentX(Component.CENTER_ALIGNMENT);

        add(grantTitle);
    }

    @Override
    protected void paintComponent(Graphics g) {
        int w = getWidth(), h = getHeight();
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        GradientPaint gp = new GradientPaint(0, 0, Color.BLACK, 0, h, Color.GRAY);
        g2d.setPaint(gp);
        g2d.fillRect(0, 0, w, h);
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 2015-04-23
    相关资源
    最近更新 更多