如何在不使用JProgressBar的情况下制作进度条?

时间:2012-12-26 05:01:44

标签: java swing timer progress-bar java-2d

我正在考虑将进度条放入我正在制作的游戏中,从5到20之间的随机数减少到0。这是我的代码到目前为止:

包软件;

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,而是使用图形(绿色矩形),它变得越来越小,时间倒计时。我将如何制作它以便屏幕可以调整大小,并且条形图仍将相对于屏幕尺寸倒计时。所以它不是一个固定的大小,而只是穿过屏幕的底部。

4 个答案:

答案 0 :(得分:11)

这是我很久以前制作的自定义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 :(得分:3)

您可以在ProgressIcon的标签中调整JTabbedPane,图示为here

image

答案 2 :(得分:2)

+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;
    }
}

答案 3 :(得分: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;
    }
}