Pętla while działa tylko raz

0

Witam. Niedawno zacząłem uczyć się programowania w Javie. Niestety napotkałem pierwszy problem którego nie jestem w stanie objeść. Może wy mi pomożecie.

Do rzeczy oto kod:
PanelLicznik.java

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.*;
import java.awt.geom.Line2D;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class PanelLicznik extends JPanel implements Runnable
{
    int srodek=450;
    Image bg;
    int a=400, i=0, t=0, v=0;
    double x=152, y=756;
    public PanelLicznik() {  
    Thread watek1=new Thread(this);
    watek1.start();
    }
    @Override
    public Dimension getPreferredSize() 
    { 
        return new Dimension(900, 900); 
    }
    @Override
    public void paintComponent(Graphics g)
    {
        Graphics2D g2=(Graphics2D)g; 
        g2.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
        bg=new ImageIcon(this.getClass().getResource("s.gif")).getImage();
        g2.drawImage(bg,0,0,null); 
        Line2D wsk=new Line2D.Double(srodek,srodek,x,y);
        g2.setColor(new Color(255,255,255));
        g2.setStroke(new BasicStroke(15.0f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER));
        g2.draw(wsk);
    }
    @Override
    public void run() {
      t=3;
      int ax=100;
      int bx=0;
      while(bx<ax){
      try{  
      Thread.sleep(100);
      }catch(Exception ek){}
      double stopien=231.4-(360/280);
      double radSek=Math.toRadians(stopien);
      x=srodek+(a*Math.cos(radSek));   
      y=srodek-(a*Math.sin(radSek));
      repaint();
      bx=bx++;
      }
    }
}

Licznik.java

import javax.swing.JApplet;

public class Licznik extends JApplet {
    @Override
    public void init() {
        setSize(900,900);
        PanelLicznik pl=new PanelLicznik();
    add(pl);
    } 
}

Otóż pętla while(bx<ax) działa tylko raz zamiast 100 razy. Coś zapewne powoduje problem, ale nie mam pojęcia co. Dlatego zwracam się o pomoc do was. Wiecie jak to naprawić ? Z góry dzięki za pomoc :)

1

Jak ta pętla while ma się wykonać 100 razy, skoro masz w jej warunku bx < ax, wartości startowe tychże, to: ax = 100, bx = 0; a pod koniec pętli przy każdej jej iteracji robisz bx = bx + 10;?

0

Bawiłem sie obliczeniami by sprawdzić czy tam nie ma jakiegoś błędu, dzięki za zwrócenie uwagi, poprawione

1
streetu napisał(a):

Bawiłem sie obliczeniami by sprawdzić czy tam nie ma jakiegoś błędu, dzięki za zwrócenie uwagi, poprawione

Jeszcze uwaga co do formatowania, którego nie poprawiłeś. Kod dla PanelLicznik.java powinien się od biedy prezentować w ten sposób:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class PanelLicznik extends JPanel implements Runnable {
     
     int srodek = 450, a = 400, i = 0, t = 0, v = 0;
     double x = 152, y = 756;
     Image bg;
     
     public PanelLicznik() {  
     
          Thread watek1 = new Thread(this);
          watek1.start();
     }
     
     @Override
     public Dimension getPreferredSize() { 
     
          return new Dimension(900, 900); 
     }
     
     @Override
     public void paintComponent(Graphics g) {
     
          Graphics2D g2 = (Graphics2D) g; 
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          
          bg = new ImageIcon(this.getClass().getResource("s.gif")).getImage();
          g2.drawImage(bg, 0, 0, null); 
          
          g2.setColor(new Color(255, 255, 255));
          g2.setStroke(new BasicStroke(15.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
          
          Line2D wsk = new Line2D.Double(srodek, srodek, x, y);
          g2.draw(wsk);
     }
     
     @Override
     public void run() {
     
          t = 3;
          int ax = 100;
          int bx = 0;
          
          while (bx < ax) {
          
               try {
                    
                    Thread.sleep(100);
                    
               } catch(Exception ex) {
                    
                    ex.printStackTrace();
               }
               
               double stopien = 231.4 - (360 / 280);
               double radSek = Math.toRadians(stopien);
               
               x = srodek + (a * Math.cos(radSek));   
               y = srodek - (a * Math.sin(radSek));
               
               repaint();
               
               bx = bx + 10;
          }
     }
}

Chodzi o to, że im lepiej i czytelniej prezentuje się Twój kod, tym łatwiej jest zrozumieć, gdzie może leżeć opisywany przez Ciebie problem.

2

Pliki graficzne powinieneś odczytywać raz, a nie wielokrotnie (w każdym przebiegu pętli).

0

@bogdans mógłbyś rozszerzyć swoją myśl ? W pętli mam tylko repaint, a s.gif jest odczytywane raz w paint component.

1

Każde repaint() wywołuje paintComponent. Każda zmiana rozmiaru okna również.

0

Dziękuje za pomoc z podstawami :)
Teraz mój PanelLicznik.java wygląda tak:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
 
import javax.swing.ImageIcon;
import javax.swing.JPanel;
 
public class PanelLicznik extends JPanel implements Runnable {
 
     int srodek = 450, a = 400, i = 0, t = 0, v = 0;
     double x = 152, y = 756;
     Image bg;
 
     public PanelLicznik() {  
 
          Thread watek1 = new Thread(this);
          watek1.start();
          
          bg = new ImageIcon(this.getClass().getResource("s.gif")).getImage();
     }
 
     @Override
     public Dimension getPreferredSize() { 
 
          return new Dimension(900, 900); 
     }
 
     @Override
     public void paintComponent(Graphics g) {
 
          Graphics2D g2 = (Graphics2D) g; 
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          
          g2.drawImage(bg, 0, 0, null); 
 
          g2.setColor(new Color(255, 255, 255));
          g2.setStroke(new BasicStroke(15.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
 
          Line2D wsk = new Line2D.Double(srodek, srodek, x, y);
          g2.draw(wsk);
     }
 
     @Override
     public void run() {
 
          t = 3;
          int ax = 100;
          int bx = 0;
 
          while (bx < ax) {
 
               try {
 
                    Thread.sleep(100);
 
               } catch(Exception ex) {
 
                    ex.printStackTrace();
               }
 
               double stopien = 231.4 - (360 / 280);
               double radSek = Math.toRadians(stopien);
 
               x = srodek + (a * Math.cos(radSek));   
               y = srodek - (a * Math.sin(radSek));
 
               repaint();
 
               bx = bx + 10;
          }
     }
}

(mam nadzieje że teraz jest dobrze napisane)
Jednak główny problem dalej pozostaje nie rozwiązany, pętla wykonuje przebieg tylko raz.

1

Nieprawda, pętla wykonuje się 10 razy. Trudno to zauważyć, bowiem w każdym przebiegu pętli ustawiasz takie same wartości zmiennych x,y i srodek.
Druga sprawa, masz taki kod

double stopien = 231.4 - (360 / 280);

Nie wiem co chcesz uzyskać, ale 360/280 = 1. Jeśli potrzebujesz innej wartości, to napisz 360.0/280

0
bogdans napisał(a):

Nieprawda, pętla wykonuje się 10 razy. Trudno to zauważyć, bowiem tylko w każdym przebiegu pętli ustawiasz takie same wartości zmiennych x,y i srodek.

Kurcze, nie zauważyłem tego wcześniej. Dzięki wielkie :D
Problem rozwiązany.

1 użytkowników online, w tym zalogowanych: 0, gości: 1