Thread funktioniert nicht

  • Themenstarter Themenstarter IDler
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
I

IDler

Gast
Hallo!
Also ich habe in einer Klasse "MyThread" die run methode für den Thread erstellt. Wenn ich das in einer Testklasse anwenden will (per ActionListener auf einen Button), dann funktioniert es leider nicht.

Hier der code:
Code:
public class BanditGUI extends JFrame{
	private JLabel zahlen1, zahlen2, zahlen3;
	private JButton start, stop1, stop2, stop3;
	MyThread thread1 = new MyThread(zahlen1);
	MyThread thread2 = new MyThread(zahlen2);
	MyThread thread3 = new MyThread(zahlen3);
	public BanditGUI(String title){
		super(title);
		
		getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER,10,10));
		getContentPane().add(createContent());
		
		pack();
		
	}
	/**
	 * In dieser Methode wird hauptsächlich der Inhalt des Fensters gestaltet.
	 * 
	 * @return panel	Das Panel mit seinen Komponenten
	 */
	public JPanel createContent(){
		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(3,3,20,20));
		
		//Die Labels mit den Zahlen
		zahlen1 = new JLabel("");
		zahlen2 = new JLabel("");
		zahlen3 = new JLabel("");
		
		//Buttons mit Beschriftung.
		start = new JButton("Start");
		stop1 = new JButton("Stop");
		stop2 = new JButton("Stop");
		stop3 = new JButton("Stop");
		
		//Die Komponenten werden dem Panel hinzugefügt
		panel.add(new JLabel());
		panel.add(start);
		panel.add(new JLabel());
		
		panel.add(zahlen1);
		panel.add(zahlen2);
		panel.add(zahlen3);
		
		panel.add(stop1);
		panel.add(stop2);
		panel.add(stop3);
	
		return panel;
	}
	
	public static void main(String args[]){
		BanditGUI gui = new BanditGUI("Bandit");
		gui.setVisible(true);
	}
	
	  class MyActionListener implements ActionListener{
		  public void actionPerformed(ActionEvent e){
			Object button = e.getSource();
			
			if(button == start){
				thread1.start(); thread2.start(); thread3.start();
			}
			if(button == stop1){
				thread1.stop();
			}
			if(button == stop2){
				thread1.stop();
			}
			if(button == stop3){
				thread1.stop();
			}
		}
	}
	
	

}

Und die Klasse MyThread:

Code:
import javax.swing.*;
import java.lang.Thread;

public class MyThread extends Thread{
	private JLabel label;
	
	public MyThread(JLabel label){
		this.label = label;		
	}
	
	public void run(){
		int i = 0;
		while(true){
			label.setText(""+i++);
		}
	}

}
[/code]
 
swing ist nicht threadsicher... schau mal in die FAQs, da gibt es einen beitrag zum Thema Multihreading und swing
 
Moin,

nee, das setText(...) funktioniert schon. Aber:

1. Du kannst die Threads sowieso nur einmal starten. Erzeuge also die Threads erst im actionPerformed() !

2. Ich würde in der Thread-while-Schleife noch eine kleine Pause einbauen.

3. Nimm nicht das Thread#stop. Baue stattdessen ein cancel-Flag in den Thread, das du in der while-Bedingung abfragst.

Gruß
Mag1c
 
Ok ich habe es jetzt geschafft. Aber nun gibt es noch ein Problem, unswar: immer wenn ich auf Start drücke fängt er an die Zahlen von 0 bis 9 durchzuzählen, aber wenn ich nochmal auf start drücke dann wird es schneller. Je öfter ich auf start drücke desto schneller wird es.
 
Code:
public class BanditGUI extends JFrame{ 
	   private JLabel zahlen1, zahlen2, zahlen3; 
	   private JButton start, stop1, stop2, stop3; 
	   public BanditGUI(String title){ 
	      super(title); 
	       
	      getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER,10,10)); 
	      getContentPane().add(createContent()); 
	       
	      pack(); 
	       
	   } 
	   /** 
	    * In dieser Methode wird hauptsächlich der Inhalt des Fensters gestaltet. 
	    * 
	    * @return panel   Das Panel mit seinen Komponenten 
	    */ 
	   public JPanel createContent(){ 
	      JPanel panel = new JPanel(); 
	      panel.setLayout(new GridLayout(3,3,20,20)); 
	       
	      //Die Labels mit den Zahlen 
	      zahlen1 = new JLabel(""+(int)(Math.random()*10)); 
	      zahlen2 = new JLabel(""+(int)(Math.random()*10)); 
	      zahlen3 = new JLabel(""+(int)(Math.random()*10)); 
	       
	      //Buttons mit Beschriftung. 
	      start = new JButton("Start");
	      start.addActionListener(new MyActionListener()); 
	      stop1 = new JButton("Stop"); 
	      stop1.addActionListener(new MyActionListener()); 
	      stop2 = new JButton("Stop"); 
	      stop2.addActionListener(new MyActionListener()); 
	      stop3 = new JButton("Stop"); 
	      stop3.addActionListener(new MyActionListener()); 
	       
	      //Die Komponenten werden dem Panel hinzugefügt 
	      panel.add(new JLabel()); 
	      panel.add(start); 
	      panel.add(new JLabel()); 
	       
	      panel.add(zahlen1); 
	      panel.add(zahlen2); 
	      panel.add(zahlen3); 
	       
	      panel.add(stop1); 
	      panel.add(stop2); 
	      panel.add(stop3); 
	    
	      return panel; 
	   } 
	    
	   public static void main(String args[]){ 
	      BanditGUI gui = new BanditGUI("Bandit"); 
	      gui.setVisible(true); 
	   } 
	    
	     class MyActionListener implements ActionListener{ 
	        public void actionPerformed(ActionEvent e){ 
	         Object button = e.getSource(); 
	         
	  	   	 MyThread thread1 = new MyThread(zahlen1); 
	  	   	 MyThread thread2 = new MyThread(zahlen2); 
	  	   	 MyThread thread3 = new MyThread(zahlen3); 
		   
	         if(button == start){ 
	            thread1.start(); thread2.start(); thread3.start(); 
	         } 
	         else if(button == stop1){ 
	            thread1.stop(); 
	         } 
	         else if(button == stop2){ 
	            thread1.stop(); 
	         } 
	         else if(button == stop3){ 
	            thread1.stop(); 
	         } 
	      } 
	   } 
	    
	    

	}

Thread-Klasse:

Code:
public class MyThread extends Thread{
	private JLabel label;
	
	public MyThread(JLabel label){
		this.label = label;		
	}
	
	public void run(){
		int i;
		while(true){
			i = Integer.parseInt(label.getText());
			if(i < 9){
				i++;
			}else if(i == 9){
				i = 0;
			}
			label.setText(""+i);

	        try {
	            sleep(150);
	        }
	        catch (Exception exc) {
	            System.out.println(exc.getMessage());
	        }
		}
	}
}
 
Hi,

mit jedem Klick auf "Start" startest du für jedes Textfeld einen Thread, der den Inhalt hochzählt. Die Threads laufen endlos, ein Klick auf "Stop" bewirkt nix, da nun die Thread-Variablen lokal sind. Je mehr Threads laufen, desto schneller wird der Wert hochgezählt ... logisch.

sollte in etwa so aussehen:

Code:
public class BanditGUI extends JFrame{
      private JLabel zahlen1, zahlen2, zahlen3;
      private JButton start, stop1, stop2, stop3;
      private MyThread thread1, thread2, thread3;

      public BanditGUI(String title){
         super(title);
          
         getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER,10,10));
         getContentPane().add(createContent());
          
         pack();
          
      }
      /**
       * In dieser Methode wird hauptsächlich der Inhalt des Fensters gestaltet.
       *
       * @return panel   Das Panel mit seinen Komponenten
       */
      public JPanel createContent(){
         JPanel panel = new JPanel();
         panel.setLayout(new GridLayout(3,3,20,20));
          
         //Die Labels mit den Zahlen
         zahlen1 = new JLabel(""+(int)(Math.random()*10));
         zahlen2 = new JLabel(""+(int)(Math.random()*10));
         zahlen3 = new JLabel(""+(int)(Math.random()*10));
          
         //Buttons mit Beschriftung.
         start = new JButton("Start");
         start.addActionListener(new MyActionListener());
         stop1 = new JButton("Stop");
         stop1.addActionListener(new MyActionListener());
         stop2 = new JButton("Stop");
         stop2.addActionListener(new MyActionListener());
         stop3 = new JButton("Stop");
         stop3.addActionListener(new MyActionListener());
          
         //Die Komponenten werden dem Panel hinzugefügt
         panel.add(new JLabel());
         panel.add(start);
         panel.add(new JLabel());
          
         panel.add(zahlen1);
         panel.add(zahlen2);
         panel.add(zahlen3);
          
         panel.add(stop1);
         panel.add(stop2);
         panel.add(stop3);
      
         return panel;
      }
      
      public static void main(String args[]){
         BanditGUI gui = new BanditGUI("Bandit");
         gui.setVisible(true);
      }
      
        class MyActionListener implements ActionListener{
           public void actionPerformed(ActionEvent e){
            Object button = e.getSource();
            
            if(button == start){
               thread1 = new MyThread(zahlen1).start();;
               thread2 = new MyThread(zahlen2).start();
               thread3 = new MyThread(zahlen3).start();
            }
            else if(button == stop1){
               thread1.stop();
            }
            else if(button == stop2){
               thread1.stop();
            }
            else if(button == stop3){
               thread1.stop();
            }
         }
      }
   }

Als nächstes muß noch das "stop()" raus und du könntest die Buttons aktivieren/deaktivieren und so verhindern, daß zu viele Threads gestartet werden.

Gruß
Mag1c
 
Mag1c hat gesagt.:
Hi,

setEnabled(boolean);

Gruß
Mag1c

LoL, thx ich habs grad selber per if-Abfrage und einem booleschen Wert gemacht^^
Und das Thread#stop? das sollte man ja nicht machen...
 
Hi,

Flag im Thread:

Code:
public class MyThread extends Thread{
   private JLabel label;
   private boolean terminate;

   public MyThread(JLabel label){
      this.label = label;      
      this.terminate = false;
   }

   public void terminate () {
      terminate = true;
   }

   public void run(){
      int i;
      while(!terminate){
         i = Integer.parseInt(label.getText());
         if(i < 9){
            i++;
         }else if(i == 9){
            i = 0;
         }
         label.setText(""+i);

           try {
               sleep(150);
           }
           catch (Exception exc) {
               System.out.println(exc.getMessage());
           }
      }
   }
}

Gruß
Mag1c
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben