how can you make a progress bar without using JProgressBar?

后端 未结 4 759
生来不讨喜
生来不讨喜 2020-12-15 14:04

i am looking at putting a progress bar into a game i am making with a count down from a random number between 5 and 20 down to 0. this is my code so far:

package Sof

相关标签:
4条回答
  • 2020-12-15 14:13

    Here is what I made for my game. Feel free to utilize this anyone who may find this question like I did.

    Enjoy.

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-15 14:16

    +1 to AndrewThompsons comment.

    Here is a short example I made, not the best but shows the logic needed to create your own JProgressBar from scratch by using JPanel:

    enter image description here

    it can also be set to indeterminate:

    enter image description here

    via uncommenting:

        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;
        }
    }
    
    0 讨论(0)
  • 2020-12-15 14:18

    You might be able to adapt ProgressIcon, illustrated here in the tabs of a JTabbedPane.

    image

    0 讨论(0)
  • 2020-12-15 14:29

    This is the code of a custom JProgressBar I made long time ago (I know the question states to not use a JProgressBar but you can grab code ideas from it), it was designed to resemble the progress bar look & feel from the "Human" theme in 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;
        }
    }
    

    Here is a test program for the component:

    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

    0 讨论(0)
提交回复
热议问题