Bijwerken JTextFields

Status
Niet open voor verdere reacties.

ifstatement

Gebruiker
Lid geworden
16 apr 2012
Berichten
91
Hallo iedereen,

Ik heb in een functie een for-lus staan, die vooraf wordt gegaan door het setten van Text in JTextFields. Het probleem is alleen dat de TextFields pas worden bijgewerkt als de functie eindigt, niet op de lijn: TextField.setText(string);. Hoe is dit te verhelpen?
Hier is het stuk van mijn code:

Code:
public void actionPerformed(ActionEvent e)
{        	
        	   Analyse.AnalyseStuk();
      	   Analyse.Plaatscontrole();
      		
      	   txtbxWarning.setText(Analyse.GetWarningText());
                if(Analyse.GetStartVoorwaarde() == true)
      	   {
              	    int number = Analyse.GetAantRij();
		    String[] AantalStuk = new String[3];
		    for (int i = 0; i < 3; i++)
                              {
        	                          Aantal[i] = Analyse.GetAantStuk(i).toString();
                              }
                              txtbxAantStukRij1.setText(AantalStuk[0]);
                              txtbxAantStukRij2.setText(AantalStuk[1]);
                              txtbxAantStukRij3.setText(AantalStuk[2]);
			
		     for(int i = 0; i < number; i++)
		     {
                                                   //Uitvoeren Code
		     }			    
                }        
}
 
Stom, het is inderdaad AantalStuk ipv Aantal. Maar dat was het probleem niet. Was uit een oudere versie. Maar AantalStuk en WarningText worden dus pas na de functie in de TextFields gezet.
 
setText(..) zal de text van het tekstveld aanpassen.

Deze nieuwe text zal pas zichtbaar worden als het textField opnieuw wordt getekend. Dit gebeurt pas weer als actionPerformed() actie klaar is.

je moet er daarom voor zorgen dat de code in actionPerformed snel klaar is. Als je iets wil gaan doen wat langer de tijd neemt moet je hiervoor zelf een achtergrond taak (thread) starten. Zodat java op de voorgrond kan blijven zorgen dat je scherm de tijd krijgt om te worden bijgewerkt.
 
Ja.. De actionPerformed() wordt uitgevoerd op de "event dispatch thread", deze thread regelt al het graphische gebeuren van je programma. Dus als je Java kan pas het scherm bijwerken als de code in actionPerfromed() klaar is.

Maar wat wil je doen in for lust waar staat "code uitvoeren" ?

Een eenvoudige workaround zou dit kunnen zijn;

Code:
public void actionPerformed(ActionEvent e)
{        	
        	   Analyse.AnalyseStuk();
      	   Analyse.Plaatscontrole();
      		
      	   txtbxWarning.setText(Analyse.GetWarningText());
                if(Analyse.GetStartVoorwaarde() == true)
      	   {
              	    [B][COLOR="#FF0000"]final[/COLOR][/B] int number = Analyse.GetAantRij();
		    [B][COLOR="#FF0000"]final[/COLOR][/B] String[] AantalStuk = new String[3];
		    for (int i = 0; i < 3; i++)
                              {
        	                          Aantal[i] = Analyse.GetAantStuk(i).toString();
                              }
                              txtbxAantStukRij1.setText(AantalStuk[0]);
                              txtbxAantStukRij2.setText(AantalStuk[1]);
                              txtbxAantStukRij3.setText(AantalStuk[2]);
			
                     SwingUtilities.invokeLater(new Runnable() {
                             public void run() {
		             for(int i = 0; i < number; i++)
		                 {
                                                   //Uitvoeren Code
		                 } 
                             }});		    
                }        
}

de code in de run() functie wordt dan niet direct uitgevoerd.. maar er wordt even in de wachtrij gezet. Zodat de "event dispatch thread" deze later (en hopelijk nadat het scherm is geupdate) uitvoert.

Doordat run() functie in een apart (anonieme) klasse staat kan je niet zomaar de variable gebruiken uit de code er omheen. Dit kan alleen als de variable "final" is.
 
Is het niet mogelijk om met threads te werken? Dat ik de Graphics en het uitvoeren van het programma beide in threads zet die in een ActionPreformed worden aangeroepen?
Ik kom echter op twee errors op de 'Thread.start()' die zeggen dat de identifier ontbreken. Heb nu dit:

Code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.lang.Thread;
import java.lang.Runnable;


public class ThreadPanel extends JPanel {
	JButton Draw;
	public void ThreadPanel()
	{
		setLayout( null );
   		setBackground(Color.LIGHT_GRAY);
   		
   		Draw = new JButton("Draw");
   		Draw.addActionListener();
   		Draw.setBounds(10, 10, 130, 130);
   		add(Draw);
	}
	class ThreadNmmr1 extends Thread{
		ThreadNmmr1(){
		}
		ThreadNmmr1(String Thrdnm){
			super(Thrdnm);
			start();
		}
		public void run(){
			System.out.print("Thread1");
		}
	}
	class ThreadNmmr2 extends Thread{
		ThreadNmmr2(){
		}
		ThreadNmmr2(String Thrdnm){
			super(Thrdnm);
			start();
		}
		public void run(){
			System.out.print("Thread2");
		}
	}
	class Hallo implements ActionListener
	{
		Thread Threadnmbr1 = new Thread(new ThreadNmmr1(), "Thread1");
		Thread Threadnmbr2 = new Thread(new ThreadNmmr2(), "Thread2");
		Threadnmbr1.start();
		Threadnmbr2.start();
		
	

	}
}

Ontbreekt er een import of wat vergeet ik?
De //Uitvoeren Code in mijn vorige post zet een bewegingroutine voor een robot in gang. Deze routine duurt enkele minuten, vandaar dat het rot is dat het scherm niet bijwerkt in de tussentijd.
 
implements Runnable{
nu ga je ook een run moeten voorzien

public final void run(){

ps u ziet het verkeert

u kan bij new threat een object met implements runnable meegeven en
extends threat is al een threat
draad aan draad maar u hebt om dat momment 2 draden waarbij je de eerst runt de tweede niet runt
 
Laatst bewerkt:
Normaal zal je zelf maar 1 thread aanmaken, deze zal dan de berekening uitvoeren die lang duurt. Het update van je scherm laat je over aan java die hiervoor een eigen thread gebruikt.

In jouw geval zal je als je de knop drukt het voglende doen:

- update text van de textfield
- start een thread die robot bestuurd.
- Deze robot thread mag nooit direct iets tekenen op het scherm! Hiervoor moet je SwingUtilities.invokeLater() constructie gebruiken.

In oude code zie je nog vaak dat the mensen Thread extenden, maar dit is niet echt netjes en het is beter om hier voor Runnable of Callable classes te gebruiken.

Maar mischien een beter alternatief is de java.swing.timer (er is ook nog een timer in java.util package maar deze is hier minder geschikt voor). Ik neem aan dat de code die je robot bestuurd niet echt reken intensief is maar gewoon elke seconde de robot beweegt. Dit is iets wat dan heel goed met de timer class kan:

Code:
Action updateRobotAction = new AbstractAction() {
    
public void actionPerformed(ActionEvent e) {
	//beweeg robot
    }
};

Timer t = new Timer(1000, updateRobotAction);
t.start();

De updateRobotAction wordt nu elke 1000 ms (1s) aangeroepen. Omdat je een Swing Timer gebruikt mag je wel direct het scherm updaten..
 
Status
Niet open voor verdere reacties.

Nieuwste berichten

Terug
Bovenaan Onderaan