java - 不使用 JProgressBar 如何制作进度条?

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

最佳答案

这是我很久以前制作的自定义 JProgressBar 的代码(我知道问题说明不使用 JProgressBar 但您可以从中获取代码思路) ,它的设计类似于 ubuntu 9.04 中“Human”主题的进度条外观和感觉:

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

关于java - 不使用 JProgressBar 如何制作进度条?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14036173/

相关文章:

java - 切换顶级窗口时如何使主机保持在对话框后面?

android - 如何在 flutter 的后台运行时钟计时器?

C# : start up an application on specific time

java - 绕特定点旋转(例如,绕0,0,0旋转)

java - Repaint() 和 PaintComponent() 未正确更新

java swing 多个 jpanel

c# - 在 Windows 服务中使用的最佳计时器

java - 观察者模式 : Internal vs. 外部注册

java - 如何通过键集从哈希表中获取所有列表

java - 无法通过 com.sun.lwuit.image.createimage 从 vector 对象创建图像