Filling bar (progress bar) JApplet paint() Thread()

465 views Asked by At

Vertical bars should be filling to the height of the applet. When the top is reached, a new bar should start filling next to the previous. Problem: When the new bar starts filling the previous paint() /bar is cleared

img how it is: http://bayimg.com/DAEoeaagm

enter image description here

img how it should be: http://bayimg.com/dAeOgAaGm

enter image description here

the code:

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JApplet;


public class fillingbar extends JApplet implements Runnable{

    int shifting=0,filling=0;
    public void init()
    {
        Thread t= new Thread(this);
        t.start();
        setSize(400,250);
    }

    public void paint(Graphics g)
    {
        super.paint(g);

            g.setColor(Color.GREEN);
            g.fillRect(shifting,getHeight()-filling,20,filling);

            g.setColor(Color.BLACK);
            g.drawRect(shifting, getHeight()-filling, 20, filling);
    }

    public void run()
    {
        while(true)
        {
            repaint();
            try{
                if(shifting<getWidth())
                {
                    if(filling<getHeight())
                        filling+=10;                    
                    else {
                        shifting+=20;
                    filling=0;
                    }
                }       
                Thread.sleep(50);
            }catch(Exception E){
                System.out.println("Exception caught");
            }

        }
    }

}
1

There are 1 answers

0
Hovercraft Full Of Eels On BEST ANSWER
  1. You only draw one rectangle in your paint method, and so it makes sense that only one will show.
  2. If you need to draw more, do so, using a for loop that loops through perhaps a Rectangle ArrayList<Rectangle>.
  3. Another way is to make shifting local and do a bit of simple math inside paintComponent to see what to draw and where. For instance, draw your completed bars inside of a for loop, for (int i = 0; i < filling / getHeight(); i++) {, and your yet to be completed bar up to filling % getHeight().
  4. You should not draw directly within a JApplet but rather in the paintComponent method of a JPanel.
  5. A Swing Timer is easier to use than a thread (for me at least), and can be safer.

For example, this can be created by the code below:

Animated GIF of the JApplet

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.lang.reflect.InvocationTargetException;

import javax.swing.*;

@SuppressWarnings("serial")
public class FillingBar2 extends JApplet {
   @Override
   public void init() {
      try {
         SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
               FillingBarPanel fillingBarPanel = new FillingBarPanel();
               add(fillingBarPanel);
               add(new JButton(new StartAction(fillingBarPanel)), BorderLayout.PAGE_END);
               setSize(getPreferredSize());
            }
         });
      } catch (InvocationTargetException | InterruptedException e) {
         System.err.println("Big Problems");
         e.printStackTrace();
      }
   }
}

@SuppressWarnings("serial")
class StartAction extends AbstractAction {
   private FillingBarPanel fillingBarPanel;

   public StartAction(FillingBarPanel fillingBarPanel) {
      super("Start");
      putValue(MNEMONIC_KEY, KeyEvent.VK_S);
      this.fillingBarPanel = fillingBarPanel;
   }

   @Override
   public void actionPerformed(ActionEvent evt) {
      fillingBarPanel.start();
   }
}

@SuppressWarnings("serial")
class FillingBarPanel extends JPanel {
   private static final int BAR_WIDTH = 20;
   private static final int TIMER_DELAY = 100;
   private static final int PREF_W = 400;
   private static final int PREF_H = 250;
   private int filling = 0;
   private Timer timer;

   public FillingBarPanel() {
      timer = new Timer(TIMER_DELAY, new TimerListener());
   }

   public void start() {
      if (timer != null && !timer.isRunning()) {
         timer.start();
      }
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      int shifting = 0;
      for (int i = 0; i < filling / getHeight(); i++) {
         shifting = i * BAR_WIDTH;
         g.setColor(Color.GREEN);
         g.fillRect(shifting, 0, BAR_WIDTH, getHeight());

         g.setColor(Color.BLACK);
         g.drawRect(shifting, 0, BAR_WIDTH, getHeight());
      }
      shifting = BAR_WIDTH * (filling / getHeight());
      g.setColor(Color.GREEN);
      g.fillRect(shifting, getHeight() - (filling % getHeight()), BAR_WIDTH, getHeight());

      g.setColor(Color.BLACK);
      g.drawRect(shifting, getHeight() - (filling % getHeight()), BAR_WIDTH, getHeight());
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent evt) {
         filling += 10;
         repaint();
      }
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

}