[英]Java splash screen not working on Mac OSX but working on a PC
下面的代碼是我用Eclipse開發的一個小型Java應用程序的啟動屏幕的實現。 初始屏幕在PC上可完美運行,但在MAC上則無法完美運行。 在MAC OSX上,該框首先在2秒鍾內出現一個灰色區域,然后在剩下的4秒鍾內出現該圖像。 該圖像通常應立即顯示並持續4秒鍾。 您是否知道為什么在PC上一切正常時,圖像出現在MAC上會有一定的延遲? PS:我已經將該應用程序部署為可執行的Jar,並且在所有計算機上都使用Java 8。 謝謝。
public static void main(String[] args)
{
SplashScreen splSplashScreen = new SplashScreen();
//Main window
FenetrePrincipale fenetrePrincipale = new FenetrePrincipale();
}
public class SplashScreen extends JWindow
{
/**
* Numéro de série
*/
private static final long serialVersionUID = 1592663893301307318L;
private final static long TEMP_AFFICHAGE = 4000;
/**
* Constructeur par initialisation
* @param p_Frame Frame
* @param p_TempsAffichage Temps d'affichage en millisecondes
*/
public SplashScreen()
{
super(new Frame());
JLabel lblImage = new JLabel(new ImageIcon(this.getClass().getResource("/res/ui/splashScreen.jpg")));
Container container = this.getContentPane();
container.add(lblImage, BorderLayout.CENTER);
pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = lblImage.getPreferredSize();
this.setLocation(screenSize.width/2 - (labelSize.width/2), screenSize.height/2 - (labelSize.height/2));
this.setVisible(true);
try
{
Thread.sleep(TEMP_AFFICHAGE);
}
catch (InterruptedException ex)
{
ApplicationLogger.getInstance().severe(ex.getLocalizedMessage());
}
finally
{
this.setVisible(false);
}
}
}
編輯這與原始答案完全不同。 我將在下面保留原始答案。
看起來最初的JLabel渲染在OSX上是緩慢的-刪除所有睡眠仍然使我在Java渲染標簽時停留約2秒的暫停時間。 因此,我們更改了規則。
首先,我們創建一個JPanel類,該類接受一個緩沖的圖像:
class ImgPanel extends JPanel {
private BufferedImage img;
public ImgPanel(BufferedImage img) {
this.img = img;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(img.getWidth(), img.getHeight());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
}
}
然后,我們如下更改初始屏幕構造函數:
public SplashScreen()
{
BufferedImage img = null;
try {
img = ImageIO.read(this.getClass().getResource("/res/ui/splashScreen.jpg"));
} catch (Exception ex) {
}
ImgPanel panel = new ImgPanel(img);
Container container = this.getContentPane();
container.add(panel);
pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(screenSize.width/2 - (img.getWidth()/2), screenSize.height/2 - (img.getHeight()/2));
this.setVisible(true);
}
一旦面板出現而沒有暫停,就會渲染圖像。
注意-我刪除了整個睡眠代碼以減少混亂-在單獨的SwingWorker中更好地捕獲邏輯以執行初始屏幕的隱藏和主屏幕的顯示:
class worker extends SwingWorker<String, Object> {
private final static long TEMP_AFFICHAGE = 4000;
private SplashScreen splash;
private FenetrePrincipale principale;
public worker(SplashScreen splash, FenetrePrincipale principale) {
this.splash = splash;
this.principale = principale;
this.splash.setVisible(true);
}
@Override
public String doInBackground() {
try
{
Thread.sleep(TEMP_AFFICHAGE);
}
catch (InterruptedException ex)
{
ApplicationLogger.getInstance().severe(ex.getLocalizedMessage());
}
return "";
}
@Override
protected void done() {
splash.setVisible(false);
principale.setVisible(true);
}
};
然后,主代碼如下所示:
public static void main(String[] args)
{
SplashScreen splSplashScreen = new SplashScreen();
//Main window
FenetrePrincipale fenetrePrincipale = new FenetrePrincipale();
worker w = new worker(splSplashScreen, fenetrePrincipale);
w.execute();
}
原始答案 -將線程休眠到SwingWorker中仍然是一個好主意,因為它將允許您在初始化之前執行實際的工作。
好的,一個使用您的啟動代碼使gui線程退出睡眠的簡單示例-該代碼位於this.setVisible(true)
,並替換了try {} catch {} finally {}子句:
this.setVisible(true);
worker do_work = new worker(this);
do_work.execute();
}
class worker extends SwingWorker<String, Object> {
private SplashScreen parent;
public worker(SplashScreen parent) {
this.parent = parent;
}
@Override
public String doInBackground() {
try
{
Thread.sleep(TEMP_AFFICHAGE);
}
catch (InterruptedException ex)
{
ApplicationLogger.getInstance().severe(ex.getLocalizedMessage());
}
return "";
}
@Override
protected void done() {
parent.setVisible(false);
}
};
我只是創建了一個SwingWorker,它像doWorkInBackground
一樣進行睡眠,一旦結束,它將關閉父框架,即初始屏幕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.