启动画面进度条不绘图

我正试图在我的启动画面上创建自己的进度条。 创建我的启动画面很简单:

java -splash:EaseMailMain.jpg Main.class(来自Eclipse)

我的main方法的第一行称为:

new Thread(new Splash()).start(); 

这是泼水类:

  public class Splash implements Runnable { public volatile static int percent = 0; @Override public void run() { System.out.println("Start"); final SplashScreen splash = SplashScreen.getSplashScreen(); if (splash == null) { System.out.println("SplashScreen.getSplashScreen() returned null"); return; } Graphics2D g = splash.createGraphics(); if (g == null) { System.out.println("g is null"); return; } int height = splash.getSize().height; int width = splash.getSize().width; //g.drawOval(0, 0, 100, 100); g.setColor(Color.white); g.drawRect(0, height-50, width, 50); g.setColor(Color.BLACK); while(percent <= 100) { System.out.println((width*percent)/100); g.drawRect(0, height-50, (int)((width*percent)/100), 50); percent += 1; try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 

我没有得到任何错误,但我确实在它下面有一个小盒子:

下面有一个矩形的图像。

如果我将drawRects更改为(0,0,宽度,高度),则没有任何区别。

我试过在swingEDT上调用:

 SwingUtilities.invokeAndWait((new Splash())); 

但没有任何反应。

有谁能看到这个问题? 或者知道如何修复它?

从其他线程更新GUI时,应使用SwingUtilities.invokeLaterSwingUtilities.invokeAndWait

请参阅Swing中的并发章节,其中解释了这背后的原因。

教程中的SplashScreen示例在Swing线程中执行Thread.sleep 。 如果在SplashScreen显示时不需要任何其他GUI刷新,这也很好。 但是,您的加载代码应该在不同的线程中发生。

我建议在你的类中添加一个setPercent setter,它创建一个Runnable来通过SwingUtilities.invokeLater更新GUI。 这样你甚至不需要轮询percent变量, SwingThread也可以自由地渲染其他UI东西。

Bikeshedder是对的(+1),你阻止了EDT。

 while(percent <= 100) { System.out.println((width*percent)/100); g.drawRect(0, height-50, (int)((width*percent)/100), 50); percent += 1; try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

使用SwingUtilities.invokeAndWait((new Splash()));Runnable放到事件队列中,这意味着当您输入while循环和Thread.sleep ,您将阻止事件队列调度任何新事件,包括重绘请求

您应该使用类似SwingWorker东西来执行实际加载(在后台线程中),发布进度结果,启动屏幕可以显示....

在此处输入图像描述

 public class TestSplashScreen { public static void main(String[] args) { new TestSplashScreen(); } public TestSplashScreen() { SplashScreenWorker worker = new SplashScreenWorker(); worker.execute(); try { worker.get(); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("All Done..."); // Launch main application... // SwingUtilities.invokeLater(...); } public class SplashScreenWorker extends SwingWorker { private SplashScreen splash; public SplashScreenWorker() { splash = SplashScreen.getSplashScreen(); if (splash == null) { System.out.println("SplashScreen.getSplashScreen() returned null"); return; } } @Override protected void process(List chunks) { Graphics2D g = splash.createGraphics(); if (g == null) { System.out.println("g is null"); return; } float progress = chunks.get(chunks.size() - 1); int height = splash.getSize().height; int width = splash.getSize().width; g.setComposite(AlphaComposite.Clear); g.fillRect(0, 0, width, height); g.setPaintMode(); g.setColor(Color.WHITE); g.drawRect(0, height - 50, width, 50); g.setColor(Color.RED); int y = height - 50; g.fillRect(0, y, (int) (width * progress), 50); FontMetrics fm = g.getFontMetrics(); String text = "Loading Microsoft Windows..." + NumberFormat.getPercentInstance().format(progress); g.setColor(Color.WHITE); g.drawString(text, (width - fm.stringWidth(text)) / 2, y + ((50 - fm.getHeight()) / 2) + fm.getAscent()); g.dispose(); splash.update(); } @Override protected Void doInBackground() throws Exception { for (int value = 0; value < 1000; value++) { float progress = value / 1000f; publish(progress); Thread.sleep(25); } return null; } } }