Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1

    GUI Swing e Thread

    ciao a tutti,

    sto realizzando un applicazione java e avrei bisogno di qualche consiglio.

    Il mio scopo è realizzare un simulatore che eseguendo dei calcoli su varie disposizioni di elementi geometrici mostri tramite un Thread di Visualizzazione l'evoluzione dei vari elementi geometrici.

    Sono riuscito a implementare tutto del mio simulatore l'unica cosa che mi manca è la possibilità durante l'esecuzione dei calcoli di sospendere l'esecuzione del Thread di Visualizzazione; questo è in realta banale lo so pero mi sono imbattuto in un problema che non riesco a risolvere.

    Durante l'esecuzione tutti i miei elementi swing di controllo (sono tutti JButton) sono come bloccati non è possibile cioè clikkarci sopra.

    Ho gia provato a forzare il setEnabled() durante l'esecuzione ma non va. qualcuno ha un idea di cosa possa provocare questo malfunzionamento ?

    Considerate che l'applicazione in questione esegue un volume di calcoli notevole, quindi potrebbe essere un problema di risorse, ma secondo me non puo essere ho controllato tramite JConsole e infatti ho fugato anche questo dubbio.

    Grazie per l'attenzione

  2. #2
    Sicuramente il thread non funziona correttamente, quindi, in parole povere, l'elaborazione viene eseguita "dalla classe che crea la gui" ...
    Experience is what you get when you don’t get what you want

  3. #3
    Il Thread di visualizzazione funziona bene e visualizza a schermo tutto quello che deve visualizzare. Non capisco a cosa ti riferisci quando dici che il Thread non funziona bene.

    Fondamentalmente questo Thread è strutturato come un ciclo while che termina quando una apposita variabile condivisa viene posta a true. Il Thread ha una struttura dati di tipo Vector condivisa con la classe che crea il Thread e da questa legge gli oggetti da visualizzare a schermo.

    Per implementare questo tipo di Thread ho creato una Classe che estende JPanel e implementa Runnable in maniera tale da poter attaccare direttamente il Thread all'interfaccia.

    Nel metodo paintComponent di questa classe non faccio altro che scorrere la struttura dati e disegnare i vari elementi mentre nel metodo run non faccio altro che leggere questa struttura dati copiarla in una di appoggio ed invocare paintImmediately su this (ho provato con repaint ma non funzionava)

    Se vuoi posso farti avere del codice cosi mi dici cosa ne pensi.

    grazie ancora

  4. #4
    Intendevo dire che se il thread non è implementato correttamente viene utilizzato come se fosse una semplice classe...
    Ossia se hai usato l'ActionListener, ad esempio, il codice del thread viene eseguito nell'actionPerformed e non come se fosse un processo separato, bloccando così l'interfaccia ...

    Esempietto:
    codice:
      import java.awt.*;
      import java.awt.event.*;
    
      public class prova extends Frame implements ActionListener 
         {
         public prova ()
            {
            Button b1 = new Button("Premimi");
            Button b2 = new Button("Premimi");
            Button b3 = new Button("Premimi");
            add (b1, "North");
            add (b2, "Center");
            add (b3, "South");
            b1.addActionListener(this);
            b2.addActionListener(this);
            b3.addActionListener(this);
            setSize(300,103);
            setVisible (true);
            } 
         public void actionPerformed(ActionEvent event)
            {
            while (true); 
            }
         public static void main (String args[])
            {
            prova finestra = new prova ();
            }   
      }
    Se "esegui" questo codice il risultato è un interfaccia utente "bloccata", dopo la pressione di un qualsiasi tasto ...

    Quindi controlla il thread. Magari è un thread "fittizio"
    Experience is what you get when you don’t get what you want

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,480

    Moderazione

    Ho spostato la discussione nel forum dedicato a Java.
    In futuro, poni qui le tue domande relative a questo linguaggio.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    ah ok ora ho capito cosa intendi. Quindi se il Thread è implementato male ho questo comportamento, pero mi sembra ci siano delle differenze con il tuo esempio. ti metto di seguito il codice del mio Thread cosi lo puoi vedere.


    package CrazyTrain;

    import javax.swing.*;
    import java.awt.*;
    import java.util.*;
    import java.awt.geom.*;

    public class VisualThread extends JPanel implements Runnable {

    private Interfaccia mainFrame;

    private volatile Vector<Binario> configurazione;

    private Rectangle2D.Double BoundingBox;

    private TrainArray treno;

    public VisualThread(Interfaccia parent, TrainArray x) throws InterruptedException{

    super();

    this.setSize(800, 700);

    this.setBackground(java.awt.Color.lightGray);

    this.setVisible(true);

    this.configurazione = new Vector<Binario>();

    this.mainFrame = parent;

    this.treno = x;
    }

    public void run(){

    int i = 0;

    synchronized(this){
    while(this.treno.getSemaforo()){

    try {

    Thread.sleep(100);

    } catch (InterruptedException ex) {
    ex.printStackTrace();
    }

    while(!this.treno.getNuovaConfigurazione()){

    //il Thread è in attesa dell'unlock per poter leggere la nuova configurazione
    }
    System.out.println("CICLO DEL THREAD");

    this.configurazione = (Vector<Binario>) this.treno.getPista().clone();

    this.BoundingBox = this.treno.getBB();

    this.treno.setNuovaConfigurazione(false);

    this.paintImmediately(this.getBounds());

    i++;
    }
    }

    System.out.println("FINE METODO RUN DEL VISUAL THREAD");
    }

    public synchronized void paintComponent(Graphics g){


    Point2D.Double massimo = new Point2D.Double(this.BoundingBox.getMaxX(), this.BoundingBox.getMaxY());

    Point2D.Double minimo = new Point2D.Double(this.BoundingBox.getMinX(), this.BoundingBox.getMinY());

    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;

    for(int i = 0; i < this.configurazione.size(); i++){
    this.configurazione.get(i).disegnaBinario(g2, massimo, minimo);
    }
    }
    }

    La classe che instanzia il Thread è TrainArray che sostanzialmente è un contatore in modulo 3 che su ogni configurazione possibile del contatore esegue dei test geometrici popolando una struttura dati condivisa di tipo Vector che viene clonata dal Thread nel momento in cui si ha l'unlock sulla risorsa. Il Thread ora come ora funziona ma senza la modalità di sospensione esecuzione. Secondo te questo codice potrebbe essere un Thread "fittizio" ?

  7. #7
    E' corretto ...
    Come lo lanci ?

    PS: guarda un po' questo ...
    codice:
      import java.awt.*;
      import java.awt.event.*;
      import java.io.*;
    
      class provaProcesso implements Runnable
      {
         public void run ()  
            {
            while (true)
               System.out.println("AAAAAAAAAAAAAAAAAAAAAAA"); 
            }    
      }
    
      public class prova extends Frame implements ActionListener
         {
         boolean primaVolta;
         public prova ()
            {
            primaVolta = true;
            Button b1 = new Button("Premimi");
            Button b2 = new Button("Premimi");
            Button b3 = new Button("Premimi");
            add (b1, "North");
            add (b2, "Center");
            add (b3, "South");
            b1.addActionListener(this);
            b2.addActionListener(this);
            b3.addActionListener(this);
            setSize(300,103);
            setVisible (true);
            } 
         public void actionPerformed(ActionEvent event)
            {
            	if (primaVolta)
                    {
                    primaVolta = false;
                    provaProcesso classeRunnable = new provaProcesso ();
                    Thread processo = new Thread (classeRunnable);
                    processo.start ();
                    }
            }
         public static void main (String args[])
            {
            prova finestra = new prova ();
            } 
      }
    Experience is what you get when you don’t get what you want

  8. #8
    dunque per il lancio del Thread avviene tutto in automatico. C'e la mia classe diciamo principale che ha un metodo Contatore che crea tutte queste configurazioni. Nel costruttore di questa classe creo il mio oggetto che implementa Runnable e poi nel mio metodo Contatore instanzio il Thread e invoco start. L'attivazione e la creazione del Thread non dipendono da event legati a qualche componente swing. In pratica

    //...nel costruttore

    VisualThread x = new VisualThread();

    mainFrame.getContentPane().add(x);

    //nel metodo Contatore

    Thread processo = new Thread(x);

    processo.start();

    Anche qui credo che non ci siano errori. Sono giorni che penso a cosa possa causare questo comportamento. Rimango sempre convinto che qualcosa possa dipendere dal volume di calcoli che ci sono e che potrebbero sovraccaricare il sistema....ma d'altronde sono necessari.

  9. #9
    Non ho idea del perché si possa comportare così ...
    Ho fatto questo:
    codice:
      class provaProcesso extends Frame implements Runnable
      {
      	 public provaProcesso ()
      	    {
      	    Button b1 = new Button ();
                add (b1,"Center");  	 
                setSize(300,300);
      	    setVisible (true);
      	    }
         public void run ()  
            {
            while (true)
               System.out.println("au au au"); 
            }    
      }
    ... e devo dire che non si blocca, il bottone funziona correttamente ...
    Experience is what you get when you don’t get what you want

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    906
    Non credo che l'elevato numero di calcoli sia la causa del malfunzionamento. Il problema sta nel fatto che thread e swing non vanno d'accordo. I thread che operano operazioni dirette sulla parte grafica spesso impallano la coda eventi dell'applicazione e ti bloccano tutto.
    Solitamente si usa la classe SwingWorker e non la classe Thread che e' pensata appositamente per queste cose. Per l'utilizzo rimando alla documentazione della Sun.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.