2014-01-11 55 views
2

我在NetBeans中有一個項目,它使用分層窗格通過在必要時進行切換來顯示重疊面板。在啓動時,程序將顯示在面板上(在單獨的線程中運行)中的一個的介紹動畫,通過以下實現:Java JLayeredPane內容在刷新時閃爍

public class IntroPanel extends javax.swing.JPanel implements Runnable { 

private boolean finished; 
private int opacity; 
private JLabel[] labels = new JLabel[3]; 

public IntroPanel() { 
    initComponents(); 
    labels[0] = jLabel1; 
    labels[1] = jLabel2; 
    labels[2] = jLabel3; 
} 

@Override 
protected void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    for(JLabel label : labels) 
     label.setForeground(new Color(200,200,200,opacity)); 
} 

@Override 
public void run(){ 
    while (!finished) {    
     while (opacity < 255) { 
      try { 
       Thread.sleep(30); 
       opacity += 5; 
       repaint(); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    try { 
     repaint(); 
     Thread.sleep(3000); 
    } catch (InterruptedException ex) { 
     Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    while (opacity > 0) { 
     try { 
      Thread.sleep(30); 
      opacity -= 5; 
      repaint(); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
     try { 
      Thread.sleep(3000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(IntroPanel.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    finished = true; 
    } 
} 

的預期效果是具有三個的JLabel淡入,留在屏幕上的然後淡出。前兩個標籤包含斜體大小的字體,第三個包含小字體。這裏的問題:

  1. 前兩個標籤的文本在淡入或淡出時顯示爲非斜體,只是在標籤不衰落時暫時變爲斜體。
  2. 第三個標籤(小號,非斜體)完全不褪色,而是在重新繪製循環期間快速上下晃動。

我瞭解它是如何的一個更好的想法寫我自己積極的渲染方法,而不是使用的paintComponent(),但有以下替換的paintComponent():

public void render() { 
    Graphics g = getGraphics(); 
    for(JLabel label : labels) 
     label.setForeground(new Color(200,200,200,opacity)); 
    g.dispose(); 
} 

做同樣閃爍。我在這裏丟失了什麼東西,或者打了重漆和分層框架,卻不混合?

回答

1
  1. 你應該在你的paintComponent裏面沒有任何代碼。這應該在你的程序的另一個區域。 paintComponent僅用於繪畫,不用於設置狀態。
  2. 您的while循環應該被Swing Timer替換,並且這是setForground調用應該去的地方。
  3. 你應該發佈一個最小的,complete valid, example, a small program,我們可以編譯運行和測試。你的代碼不允許這樣做。

例如:

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.*; 

public class IntroPanel extends JPanel { 
    private static final int DELAY_TIME = 5; 
    protected static final Color FG_COLOR = Color.blue; 
    private List<JLabel> labelList = new ArrayList<JLabel>(); 
    private List<Color> colorList = new ArrayList<>(); 

    public IntroPanel() { 
     for (int i = 0; i < 255; i++) { 
     colorList.add(new Color(0, 0, 255, i)); 
     } 
     for (int i = 0; i < 255; i++) { 
     colorList.add(new Color(0, 0, 255, 255 - i)); 
     } 

     setLayout(new GridLayout(0, 1)); 

     JLabel label1 = new JLabel("Label 1"); 
     label1.setFont(label1.getFont().deriveFont(Font.ITALIC, 24)); 
     add(label1); 
     labelList.add(label1); 
     JLabel label2 = new JLabel("Label 2"); 
     label2.setFont(label2.getFont().deriveFont(Font.ITALIC, 24)); 
     add(label2); 
     labelList.add(label2); 
     JLabel label3 = new JLabel("Label 3"); 
     label3.setFont(label3.getFont().deriveFont(Font.PLAIN, 10)); 
     add(label3); 
     labelList.add(label3); 

     new Timer(DELAY_TIME, new ActionListener() { 
     private int index = 0; 

     @Override 
     public void actionPerformed(ActionEvent evt) { 
      if (index < colorList.size()) { 
       for (JLabel label : labelList) { 
        label.setForeground(colorList.get(index)); 
       } 
       index++; 
      } else { 
       ((Timer)evt.getSource()).stop(); 
      } 
     } 
     }).start(); 
    } 

    private static void createAndShowGUI() { 
     IntroPanel paintEg = new IntroPanel(); 

     JFrame frame = new JFrame("IntroPanel"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(paintEg); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGUI(); 
     } 
     }); 
    } 
} 
+0

1.這樣做,沒有效果。 2.如你所說,現在沒有任何重新粉刷,甚至沒有閃爍;它只是一個靜態圖像。 – amitakartok

+0

D'oh ...我沒有把setForeground放到Timer的ActionListener中。消失的斜體問題仍然存在,但我發現問題的根源在於小文字:文本不會褪色,因爲它被封裝在自動換行的標籤中。我已經發現線程正在討論它,現在正在研究它。 – amitakartok

+0

@amitakartok:你編譯並運行我的代碼? –