2014-12-30 13 views
1

源自代碼 Circular Progress Bar for Java Swing not working的較低源代碼是一個很棒的Swing特性。如何調整擺動進度指示器上的圖形?

我希望能夠用「透明」 JFrame或玻璃面板 但圖形「花瓣」用它,在paint()方法,希望與後臺交互, 所以如果的不透明度背景非常低,幾乎可以看到「花瓣」 。不熟悉Graphics2D的功能,我在黑暗中嘗試調整代碼,但沒有運氣,所以知道這些功能如何工作的人, 建議更改,以便「花瓣」不要「 t與背景進行交互,並開始出現白色,並逐漸淡出,如代碼所示?

我也不需要任何淡入或淡出延遲,而且我也有 有困難,但如果有人只是建議 修改爲「花瓣」,那將是偉大的!

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import javax.swing.*; 
import javax.swing.plaf.LayerUI; 

public class Loading_Test { 

static final WaitLayerUI layerUI = new WaitLayerUI(); 
JFrame frame = new JFrame("JLayer With Animated Gif"); 

public Loading_Test() { 
    JPanel panel = new JPanel() { 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(400, 300); 
     } 
    }; 
    JLayer<JPanel> jlayer = new JLayer<>(panel, layerUI); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.add(jlayer); 
    frame.pack(); 
    frame.setVisible(true); 
    layerUI.start(); 
} 

public static void main(String args[]) { 
    java.awt.EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      Loading_Test loading_Test = new Loading_Test(); 

     } 
    }); 
} 
} 

class WaitLayerUI extends LayerUI<JPanel> implements ActionListener { 

private boolean mIsRunning; 
private boolean mIsFadingOut; 
private Timer mTimer; 
private int mAngle; 
private int mFadeCount; 
private int mFadeLimit = 15; 

@Override 
public void paint(Graphics g, JComponent c) { 
    int w = c.getWidth(); 
    int h = c.getHeight(); 
    super.paint(g, c); // Paint the view. 
    if (!mIsRunning) { 
     return; 
    } 
    Graphics2D g2 = (Graphics2D) g.create(); 
    float fade = (float) mFadeCount/(float) mFadeLimit; 
    Composite urComposite = g2.getComposite(); // Gray it out. 
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f * fade)); 
    g2.fillRect(0, 0, w, h); 
    g2.setComposite(urComposite); 
    int s = Math.min(w, h)/5;// Paint the wait indicator. 
    int cx = w/2; 
    int cy = h/2; 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    g2.setStroke(new BasicStroke(s/4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 
    g2.setPaint(Color.white); 
    g2.rotate(Math.PI * mAngle/180, cx, cy); 
    for (int i = 0; i < 12; i++) { 
     float scale = (11.0f - (float) i)/11.0f; 
     g2.drawLine(cx + s, cy, cx + s * 2, cy); 
     g2.rotate(-Math.PI/6, cx, cy); 
     g2.setComposite(AlphaComposite.getInstance(
       AlphaComposite.SRC_OVER, scale * fade)); 
    } 
    g2.dispose(); 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    if (mIsRunning) { 
     firePropertyChange("tick", 0, 1); 
     mAngle += 3; 
     if (mAngle >= 360) { 
      mAngle = 0; 
     } 
     if (mIsFadingOut) { 
      if (--mFadeCount == 0) { 
       mIsRunning = false; 
       mTimer.stop(); 
      } 
     } else if (mFadeCount < mFadeLimit) { 
      mFadeCount++; 
     } 
    } 
} 

public void start() { 
    if (mIsRunning) { 
     return; 
    } 
    mIsRunning = true;// Run a thread for animation. 
    mIsFadingOut = false; 
    mFadeCount = 0; 
    int fps = 24; 
    int tick = 1000/fps; 
    mTimer = new Timer(tick, this); 
    mTimer.start(); 
} 

public void stop() { 
    mIsFadingOut = true; 
} 

@Override 
public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) { 
    if ("tick".equals(pce.getPropertyName())) { 
     l.repaint(); 
    } 
} 
} 
+0

你問如何使這是半透明的部件上此代碼的工作(也就是描繪它的內容與0之間的α和1)? – VGR

+0

非常。我可以告訴paint()中的複合相關指令與目標,背景交互,並且我希望進度指示器很好地顯示。另外,我見過JXBusyLabel,但我更願意使用這個更短的代碼。 – user1572522

回答

1

我看到的一個問題是代碼是在循環中的錯誤位置設置複合。它可以工作,但正如你發現的那樣,很難保持或改變。

g2.setComposite正在循環的處被調用。這爲下一個繪製的花瓣設置了alpha。這意味着你無法輕易改變第一片花瓣的阿爾法。

首先,我想使代碼更符合人類認爲(至少,我的思考方式)的方式行:設置你要畫線的α,你畫它的權利之前:

for (int i = 0; i < 12; i++) { 
    float scale = (12 - i)/12f; 
    g2.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC_OVER, scale * fade)); 
    g2.drawLine(cx + s, cy, cx + s * 2, cy); 
    g2.rotate(-Math.PI/6, cx, cy); 
} 

現在,使它與任何背景alpha的工作很容易。我們只是調整的scale值:

float componentAlpha = 0.5f; 

for (int i = 0; i < 12; i++) { 
    float scale = (12 - i)/12f; 

    // Give petals the same relative alpha as the component 
    // they're overlaying. 
    scale *= componentAlpha; 

    g2.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC_OVER, scale * fade)); 
    g2.drawLine(cx + s, cy, cx + s * 2, cy); 
    g2.rotate(-Math.PI/6, cx, cy); 
} 
+0

非常感謝!如果有人感興趣,原始代碼Taptaptap.java來自這裏:http://www.liafa.jussieu.fr/~yunes/cours/annexes/java/docs/tutorial/uiswing/misc/jlayer.html – user1572522

+0

盡我所能,但我確信這裏有一些由@aterai提供的優秀代碼示例 – mKorbel