2012-12-26 89 views
5

我正在考慮把進度條放入一個遊戲中,我正在從一個從5到20之間的隨機數下降到0的遊戲。這是我的代碼到目前爲止:如何在不使用JProgressBar的情況下製作進度條?

軟件包軟件;

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class CountDownProgressBar extends JPanel { 

    RandomValues randomNum; 
    int timeValue; 
    Timer timer; 
    int length, newLength; 

    public CountDownProgressBar() { 
     timer = new Timer(24, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (int i = timeValue; i > 0; --i) { 
         newLength = length - (length/timeValue); 
         length = newLength; 
         repaint(); 
        } 
       } 
      }); 
     randomNum = new RandomValues(); 
     this.timeValue = 0; 
     this.setBackground(Color.GRAY); 
    } 

    @Override 
    public void paint(Graphics g) { 
     super.paintComponent(g); 
     g.setColor(Color.green); 
     g.fillRect(0, 0, length, 50); 
    } 

    public void setTimeLength() { 
     this.timeValue = randomNum.integer(5, 20); 
    } 

    public int getTimeLength() { 
     return this.timeValue; 
    } 
} 

我知道大部分是錯誤的,我只是不知道該怎麼做。它不需要使用JProgressBar,而是使用圖形(一個綠色的矩形),它越來越小,時間倒數。以及我如何製作它,因此屏幕可以調整大小,並且相對於屏幕大小,條形仍然會倒數。所以它只是一個固定的大小,但只是穿過屏幕的底部。

+0

您可以自定義JComponent –

+5

1)'JProgressBar' * *可以直接繪製到'Graphics'實例。 2)不要阻塞EDT(Event Dispatch Thread) - 當發生這種情況時,GUI將「凍結」。而不是調用'Thread.sleep(n)'實現一個Swing'Timer'來重複任務。有關更多詳細信息,請參見[Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 3)*「穿過屏幕的底部。」*將JProgressBar放入BorderLayout的'PAGE_END'而不是遊戲區域。 –

+0

+1 @AndrewThompson評論。請參閱我的答案,瞭解使用該邏輯的示例:http://stackoverflow.com/a/14052118/1133011 –

回答

12

這是一個自定義JProgressBar我很久以前做的代碼(我知道這個問題各國不使用JProgressBar但你可以抓住從它的代碼的想法),它被設計爲類似進度條看起來&從感覺在Ubuntu 9.04 「人」 的主題:

import java.awt.AlphaComposite; 
import java.awt.Color; 
import java.awt.Composite; 
import java.awt.FontMetrics; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 

import javax.swing.JProgressBar; 

/** 
* A progressBar that looks like the progress bar from Ubuntu 9.04 Human Theme 
*/ 
public class HumanProgressBar extends JProgressBar { 
    private static final long serialVersionUID = 1L; 

    private static final String DISABLED_PERCENT_STRING = " --- "; 

    private static final Color gradientEndingColor = new Color(0xc0c0c0); 
    private static final Color borderColor = new Color(0x736a60); 
    private static final Color disabledBorderColor = new Color(0xbebebe);  

    private static final Composite transparent = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.45f); 
    private static final Composite veryTransparent = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f); 

    private static GradientPaint gradient; 

    private int oldWidth; 
    private int oldHeight; 

    private int displayWidth; 
    private int displayHeight; 

    private int insets[] = new int[4]; 
    private static final int TOP_INSET = 0; 
    private static final int LEFT_INSET = 1; 
    private static final int BOTTOM_INSET = 2; 
    private static final int RIGHT_INSET = 3; 

    private static final int PREFERRED_PERCENT_STRING_MARGIN_WIDTH = 3; 

    public static final Color PREFERRED_PROGRESS_COLOR = new Color(0x1869A6); 

    private boolean percentStringVisible = true; 

    private Color progressColor; 

    private String maxPercentString; 

    public HumanProgressBar() { 
     progressColor = PREFERRED_PROGRESS_COLOR; 
    } 

    public void updateGraphics() { 
     update(getGraphics()); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     int w = displayWidth != 0 ? displayWidth - 1 : getWidth() - 1; 
     int h = displayHeight != 0 ? displayHeight - 1 : getHeight() - 1; 

     int x = insets[LEFT_INSET]; 
     int y = insets[TOP_INSET]; 
     w -= (insets[RIGHT_INSET] << 1); 
     h -= (insets[BOTTOM_INSET] << 1); 

     if (gradient == null) { 
      gradient = new GradientPaint(0.0f, 0.0f, Color.WHITE, 0.0f, h, gradientEndingColor); 
     } 
     Graphics2D g2d = (Graphics2D) g; 
     // Clean background 
     if (isOpaque()) { 
      g2d.setColor(getBackground()); 
      g2d.fillRect(0, 0, getWidth(), getHeight()); 
     } 

     g2d.translate(x, y); 

     if (percentStringVisible) { 
      FontMetrics fm = g.getFontMetrics(); 
      int stringW = 0; 
      int stringH = 0; 

      g2d.setColor(getForeground()); 

      if (isEnabled()) { 
       int p = getValue(); 
       String percent = Integer.toString(p, 10) + "%"; 
       if (p < 10) { 
        percent = "0" + percent; 
       } 

       if (maxPercentString == null) { 
        maxPercentString = Integer.toString(getMaximum(), 10) + "%"; 
       } 
       stringW = fm.stringWidth(maxPercentString); 
       stringH = ((h - fm.getHeight())/2) + fm.getAscent(); 

       g2d.drawString(percent, w - stringW, stringH); 
      } else { 
       stringW = fm.stringWidth(DISABLED_PERCENT_STRING); 
       stringH = ((h - fm.getHeight())/2) + fm.getAscent(); 

       g2d.drawString(DISABLED_PERCENT_STRING, w - stringW, stringH); 
      } 
      w -= (stringW + PREFERRED_PERCENT_STRING_MARGIN_WIDTH);    
     } 

     // Control Border 
     g2d.setColor(isEnabled() ? borderColor : disabledBorderColor); 
     g2d.drawLine(1, 0, w - 1, 0); 
     g2d.drawLine(1, h, w - 1, h); 
     g2d.drawLine(0, 1, 0, h - 1); 
     g2d.drawLine(w, 1, w, h - 1); 

     // Fill in the progress 
     int min = getMinimum(); 
     int max = getMaximum(); 
     int total = max - min; 
     float dx = (float) (w - 2)/(float) total; 
     int value = getValue(); 
     int progress = 0; 
     if (value == max) { 
      progress = w - 1; 
     } else { 
      progress = (int) (dx * getValue());    
     } 

     g2d.setColor(progressColor); 
     g2d.fillRect(1, 1, progress, h - 1); 

     // A gradient over the progress fill 
     g2d.setPaint(gradient); 
     g2d.setComposite(transparent); 
     g2d.fillRect(1, 1, w - 1, (h >> 1)); 
     final float FACTOR = 0.20f; 
     g2d.fillRect(1, h - (int) (h * FACTOR), w - 1, (int) (h * FACTOR)); 

     if (isEnabled()) { 
      for (int i = h; i < w; i += h) { 
       g2d.setComposite(veryTransparent); 
       g2d.setColor(Color.GRAY); 
       g2d.drawLine(i, 1, i, h - 1); 
       g2d.setColor(Color.WHITE); 
       g2d.drawLine(i + 1, 1, i + 1, h - 1); 
      } 
     } else { 
      for (int i = 0; i < w; i += h) { 
       g2d.setComposite(veryTransparent); 
       g2d.setColor(Color.RED); 
       g2d.drawLine(i, h - 1, i + h, 1); 
       g2d.setColor(Color.WHITE); 
       g2d.drawLine(i + 1, h - 1, i + 1 + h, 1); 
      }    
     } 
    } 

    public void setInsets(int top, int left, int bottom, int right) { 
     insets[TOP_INSET] = top; 
     insets[LEFT_INSET] = left; 
     insets[BOTTOM_INSET] = bottom; 
     insets[RIGHT_INSET] = right; 
    } 

    public void setPercentStringVisible(boolean percentStringVisible) { 
     this.percentStringVisible = percentStringVisible; 
    } 

    @Override 
    protected void paintBorder(Graphics g) { 
    } 

    @Override 
    public void validate() { 
     int w = getWidth(); 
     int h = getHeight(); 

     super.validate(); 
     if (oldWidth != w || oldHeight != h) { 
      oldWidth = w; 
      oldHeight = h; 
      gradient = null; 
     } 
    } 

    @Override 
    public void setMaximum(int n) { 
     super.setMaximum(n); 
     maxPercentString = Integer.toString(n, 10) + "%"; 
    } 

    public void setDisplaySize(int width, int height) { 
     displayWidth = width; 
     displayHeight = height; 
    } 

    public Color getProgressColor() { 
     return progressColor; 
    } 

    public void setProgressColor(Color progressColor) { 
     this.progressColor = progressColor; 
    } 
} 

這裏是該成分的測試程序:

import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 

public class T extends JFrame { 
    public T() { 
     super(); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setLayout(null); 
     this.setSize(350, 75); 
     HumanProgressBar p = new HumanProgressBar(); 
     p.setValue(50); 
     p.setBounds(15, 15, 300, 15); 
     this.add(p); 
     this.setVisible(true); 
    } 

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

enter image description here

+1

+1個很好的例子。請使用SwingUtilities.invokeLater進行調整。 – vels4j

+0

感謝您的建議!我更新了答案 – higuaro

+0

謝謝,它有幫助。只需要這個從20到0的簡單計數就可以填滿整個屏幕底部的jpanel。每秒鐘,酒吧的一部分被帶走,直到時間耗盡。 – KrazyKat89

3

您可能可以修改ProgressIcon,在JTabbedPane的選項卡中說明here

image

+0

+1不錯的例子我絕對會用 –

3

+1到AndrewThompsons評論。

這裏是我做了一個簡單的例子,而不是最好的,但顯示從頭開始創建自己的JProgressBar所需的邏輯通過使用JPanel

enter image description here

它也可以被設置爲不定:

enter image description here

經由取消註釋

myProgressBar.setBackground(new Color(0, 255, 0, 127)); 
    myProgressBar.setIndeterminate(true); //if progress unknown show ball moving from side to side 

CustomProgressBarTest.java:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.util.ArrayList; 
import javax.swing.AbstractAction; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 
import javax.swing.border.LineBorder; 

public class CustomProgressBarTest { 

    public CustomProgressBarTest() { 
     createAndShowGui(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new CustomProgressBarTest(); 
      } 
     }); 
    } 

    private void createAndShowGui() { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final MyProgressBar myProgressBar = new MyProgressBar(0, 100); 
     myProgressBar.setProgressColor(new Color(0, 255, 0, 127)); 
     //myProgressBar.setIndeterminate(true); //if progress unknown show ball moving from side to side 

     JPanel dummyPanel = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(300, 300); 
      } 
     }; 

     dummyPanel.add(new JLabel("DummyPanel")); 

     frame.add(dummyPanel); 

     frame.add(myProgressBar, BorderLayout.SOUTH); 

     frame.pack(); 
     frame.setVisible(true); 

     //create timer to decrease progressbar 
     createAndStartDecrementTimer(myProgressBar); 

     //create timer to increase progressbar 
     //myProgressBar.setValue(0);//set to 0 so we can increment 
     //createAndStartIncrementTimer(myProgressBar); 
    } 

    private void createAndStartIncrementTimer(final MyProgressBar myProgressBar) { 
     Timer progressBarIncrementTimer = new Timer(100, new AbstractAction() { 
      int count = 0; 

      @Override 
      public void actionPerformed(ActionEvent ae) { 
       if (count == 100) { 
        System.out.println("Done"); 
        ((Timer) ae.getSource()).stop(); 
       } else if (count < 100) { 
        //System.out.println("Here"); 
        count++; 
        myProgressBar.setValue(count); 
       } 
      } 
     }); 
     progressBarIncrementTimer.start(); 
    } 

    private void createAndStartDecrementTimer(final MyProgressBar myProgressBar) { 
     Timer progressBArCountDownTimer = new Timer(100, new AbstractAction() { 
      int count = 100; 

      @Override 
      public void actionPerformed(ActionEvent ae) { 
       if (count == 0) { 
        System.out.println("Done"); 
        ((Timer) ae.getSource()).stop(); 
       } else if (count > 0) { 
        count--; 
        myProgressBar.setValue(count); 
        System.out.println(myProgressBar.getValue()); 
       } 
      } 
     }); 
     progressBArCountDownTimer.start(); 
    } 
} 

class MyProgressBar extends JPanel { 

    private final int minValue, maxValue; 
    private boolean indeterminate = false; 
    private int currentValue; 
    private ArrayList<Rectangle> rects = new ArrayList<>(); 
    private Color PROGRESS_COLOR = Color.blue; 
    private int removeValue = 0; 
    private Timer indeterminateTimer; 
    private int x = 0, y = 0, ballSize = 25; 
    private boolean changeDirection = false; 

    public MyProgressBar(int min, int max) { 
     indeterminateTimer = new Timer(50, new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       repaint(); 
      } 
     }); 
     maxValue = max; 
     minValue = min; 
     currentValue = maxValue; 
     setBorder(new LineBorder(Color.BLACK)); 
    } 

    @Override 
    protected void paintComponent(Graphics grphcs) { 
     super.paintComponent(grphcs); 
     Graphics2D g2d = (Graphics2D) grphcs; 

     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     if (!indeterminate) {//if normal progress bar 
      rects.clear(); 
      int rectWidths = getWidth()/maxValue; 
      int startingX = 0; 

      if (currentValue < maxValue) {//we started off with a value less than the max 
       for (int i = minValue; i < currentValue; i++) { 
        rects.add(new Rectangle(startingX, 0, rectWidths, getHeight())); 
        startingX += rectWidths; 
       } 
      } else { 
       for (int i = minValue; i < (maxValue - removeValue); i++) { 
        rects.add(new Rectangle(startingX, 0, rectWidths, getHeight())); 
        startingX += rectWidths; 
       } 
      } 

      for (Rectangle r : rects) { 
       g2d.setColor(PROGRESS_COLOR); 
       g2d.fillRect(r.x, r.y, r.width, r.height); 
      } 
     } else {//if indeterminate 
      if (!indeterminateTimer.isRunning()) { 
       indeterminateTimer.start(); 
      } 
      g2d.setColor(PROGRESS_COLOR); 
      if (!changeDirection) { 
       if (x + 10 < getWidth() - (ballSize/2)) { 
        x += 10; 
       } else { 
        changeDirection = true; 
       } 
      } else if (changeDirection) { 
       if (x + 10 > 0) { 
        x -= 10; 
       } else { 
        changeDirection = false; 
       } 
      } 
      g2d.fillOval(x, y, ballSize, getHeight()); 
     } 
    } 

    int getValue() { 
     return currentValue; 
    } 

    public void setIndeterminate(boolean indeterminate) { 
     this.indeterminate = indeterminate; 
    } 

    void setValue(int value) { 
     if (value > maxValue) { 
      return; 
     } 
     if (value < minValue) { 
      return; 
     } 
     if (value < currentValue) { 
      removeValue++; 
     } else { 
      int rem = value - currentValue; 
      removeValue -= rem; 
     } 
     currentValue = value; 
     repaint(); 
    } 

    void setProgressColor(Color c) { 
     PROGRESS_COLOR = c; 
    } 

    Color getProgressColor() { 
     return PROGRESS_COLOR; 
    } 
} 
+2

'myProgressBar.setBackground(Color.GREEN);''那最好是'myProgressBar.setBackground(new Color(0,255,0,127) )); //部分透明「,因爲它大概會出現在活動的遊戲區域之上。 –

+1

@AndrewThompson +1更新了我的代碼以適應上面的情況,並增加了一些額外內容,例如'setIndeterminate(..)'和'getValue(..)',使其更像JProgressBar,如:P –

+0

哇感謝jsut可能會幫助我:) 好極了!!! – KrazyKat89

0

以下是我爲我做遊戲。隨意利用這個可能像我一樣發現這個問題的人。

享受。

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 

import javax.swing.JPanel; 

import com.jayavon.game.client.MyClient; 

public class CustomJProgressBar extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private Color color; 
    private int width, height; 
    private double minimum = 0.0; 
    private double maximum = 100.0; 
    private double value = 100.0; 
    private Font font = MyClient.theme_font.deriveFont(Font.PLAIN, 12); 

    public CustomJProgressBar(Color color) { 
     super(); 
     this.color = color; 
     setBounds(0, 0, width, height); 
     setFont(font); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     //border 
     g.setColor(MyClient.THEME_LIGHT_TEXT); 
     g.drawRect(0, 0, getWidth()-1, getHeight()-1); 

     //progress 
     int drawAmount = (int) (((value - minimum)/(maximum - minimum)) * getWidth()); 
     g.setColor(color); 
     g.fillRect(1, 1, drawAmount-2, getHeight()-2); //-2 to account for border 

     //string painting 
     String stringToPaint = (int)value + "/" + (int)maximum; 
     Canvas c = new Canvas(); 
     FontMetrics fm = c.getFontMetrics(font); 
     final int stringWidth = fm.stringWidth(stringToPaint); 
     final int stringHeight = fm.getHeight(); 
     g.setColor(MyClient.THEME_LIGHT_TEXT); 
     g.drawString(stringToPaint, (getWidth()/2) - (stringWidth/2), ((getHeight()/2) + (stringHeight/2))-2); //-2 to account for border 
    } 

    public void setColor(Color _color){ 
     this.color = _color; 
    } 

    public void setMinimum(double _minimum){ 
     this.minimum = _minimum; 
    } 

    public void setMaximum(double _maximum){ 
     this.maximum = _maximum; 
    } 

    public void setValue(double _value){ 
     this.value = _value; 
    } 
} 
相關問題