Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [JAVA] Problema del produttore-consumatore con interfaccia grafica

    salve,
    Ecco cosa richiede l'applicazione:
    Bisogna gestire il flusso di persone che arriva allo sportello postale. L'applicazione ha un'interfaccia grafica che consente di inserire il nome e cognome della persona. L'insieme delle persone viene mantenuto in una struttura dati con politica fifo, e ogni persona viene associata a uno sportello libero per la durata compresa tra i 5 e 20 secondi, mentre se lo sportello è occupato , la persona viene messa in attesa. il numero massimo di persone in attesa è 10.


    Ora veniamo al dunque:
    Non so proprio come gestire questa situazione con l'utilizzo dei thread produttori - consumatori. Qualcuno può aiutarmi?

    ho creato la seguente interfaccia grafica :
    codice:
    package it.unisa.oop;
    
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    import javax.swing.UIManager.LookAndFeelInfo;
    
    
    public class InterfacciaGrafica extends JFrame{
        private JLabel lSportello1;
        private JLabel lSportello2;
        private JLabel lSportello3;
        private JLabel lSportello4;
        private JTextField tSportello1;
        private JTextField tSportello2;
        private JTextField tSportello3;
        private JTextField tSportello4;
        private JLabel lNome;
        private JLabel lCognome;
        private JTextField tNome;
        private JTextField tCognome;
        private JButton inserimento;
        
        
        
        public InterfacciaGrafica(){
            super();
            initGui();
        }
        
        private void initGui() {
         try{
             for(LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()){
                 if("Nimbus".equals(info.getName())){
                     UIManager.setLookAndFeel(info.getClassName());
                     break;
                 }
             }
             
            this.setTitle("POSTE ITALIANE");
            this.setSize(1200,270);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setResizable(false);
            this.setLocation(100,300);
            
            GridBagLayout gb = new GridBagLayout();
            gb.columnWeights = new double[]{0.1,0.1,0.1,0.1,0.1};
            gb.columnWidths = new int[]{200,280,200,200,330};
            gb.rowWeights = new double[]{0.1,0.1,0.1,0.1};
            gb.rowHeights = new int []{10,10,10,10};
            this.setLayout(gb);
            
            
            {
                lSportello1 = new JLabel("Sportello 1");
                lSportello1.setFont(new Font("", Font.BOLD,22));
                this.add(lSportello1, new GridBagConstraints(0,0,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,10,0,0),0,0));
            }
            
            {
                lSportello2 = new JLabel("Sportello 2");
                lSportello2.setFont(new Font("", Font.BOLD,22));
                this.add(lSportello2, new GridBagConstraints(0,1,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,10,0,0),0,0));
            }
            
            {
                lSportello3 = new JLabel("Sportello 3");
                lSportello3.setFont(new Font("", Font.BOLD,22));
                this.add(lSportello3, new GridBagConstraints(0,2,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,10,0,0),0,0));
            }
            
            {
                lSportello4 = new JLabel("Sportello 4");
                lSportello4.setFont(new Font("", Font.BOLD,22));
                this.add(lSportello4, new GridBagConstraints(0,3,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,10,0,0),0,0));
            }
            
            {
                tSportello1 = new JTextField();
                tSportello1.setToolTipText("Utente Corrente");
                tSportello1.setFont(new Font("", Font.BOLD,22));
                tSportello1.setEditable(false);
                this.add(tSportello1, new GridBagConstraints(1,0,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
            }
            
            
            {
                tSportello2 = new JTextField();
                tSportello2.setToolTipText("Utente Corrente");
                tSportello2.setFont(new Font("", Font.BOLD,22));
                tSportello2.setEditable(false);
                this.add(tSportello2, new GridBagConstraints(1,1,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
            }
            
            {
                tSportello3 = new JTextField();
                tSportello3.setToolTipText("Utente Corrente");
                tSportello3.setFont(new Font("", Font.BOLD,22));
                tSportello3.setEditable(false);
                this.add(tSportello3, new GridBagConstraints(1,2,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
            }
            
            
            {
                tSportello4 = new JTextField();
                tSportello4.setToolTipText("Utente Corrente");
                tSportello4.setFont(new Font("", Font.BOLD,22));
                tSportello4.setEditable(false);
                this.add(tSportello4, new GridBagConstraints(1,3,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
            }
            
            {
                lNome = new JLabel("Nome:");
                lNome.setFont(new Font("", Font.ITALIC,22));
                this.add(lNome, new GridBagConstraints(3,0,1,1,0.0,0.0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
            }
            
            {
                lCognome = new JLabel("Cognome:");
                lCognome.setFont(new Font("", Font.ITALIC,22));
                this.add(lCognome, new GridBagConstraints(3,1,1,1,0.0,0.0,GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
            }
            
            {
                tNome = new JTextField();
                tNome.setToolTipText("Inserire il nome dell'utente!!!");
                tNome.setFont(new Font("", Font.ITALIC,22));
                this.add(tNome, new GridBagConstraints(4,0,1,1,0.0,0.0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,30),0,0));
            }
            
            {
                tCognome = new JTextField();
                tCognome.setToolTipText("Inserire il cognome dell'utente!!!");
                tCognome.setFont(new Font("", Font.ITALIC,22));
                this.add(tCognome, new GridBagConstraints(4,1,1,1,0.0,0.0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,30),0,0));
            }
            
            {
                inserimento = new JButton("Inserimento");
                inserimento.setFont(new Font("", Font.TYPE1_FONT,22));
                this.add(inserimento, new GridBagConstraints(3,2,2,1,0.0,0.0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,30),0,0));
                inserimento.addActionListener(new ActionListener(){
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if(tNome.getText().isEmpty() || tCognome.getText().isEmpty()){
                            JOptionPane.showMessageDialog(getContentPane(),"Riempire tutti i campi!!!", "Warning",JOptionPane.WARNING_MESSAGE);
                        }
                    }
                    
                });
            }
        }catch(Exception e){}
         
      }
        public static void main(String [] args){
            SwingUtilities.invokeLater(new Runnable(){
    
                @Override
                public void run() {
                    InterfacciaGrafica gui = new InterfacciaGrafica();
                    gui.setVisible(true);
                }
                
            });
        }
        
        
        
        
    }

  2. #2
    Secondo me dovresti prima concentrarti a risolvere il problema proposto senza preoccuparti della grafica. Una volta che hai realizzato il programma funzionante puoi iniziare a realizzare la versione interattiva. Ovviamente questo è solo un mio consiglio. Comunque credo che tu debba intanto creare una classe Persona con i campi nome e cognome, dopodiché dovresti sfruttare una struttura del tipo:

    codice:
    Queue<Persona> persone = new LinkedList<Persona>();
    Tutto ciò che so del produttore-consumatore è che hai una classe Receiver ed una Trasmitter le quali implementano Runnable. I nomi sono abbastanza autoesplicativi circa la loro funzione. Suppongo che il Receiver debba implementare lo sportello, nella quale metterai un metodo per estrapolare le persone da servire, inserendo un controllo circa il numero limite di persone.

  3. #3
    Quote Originariamente inviata da Javino89 Visualizza il messaggio
    Secondo me dovresti prima concentrarti a risolvere il problema proposto senza preoccuparti della grafica. Una volta che hai realizzato il programma funzionante puoi iniziare a realizzare la versione interattiva. Ovviamente questo è solo un mio consiglio. Comunque credo che tu debba intanto creare una classe Persona con i campi nome e cognome, dopodiché dovresti sfruttare una struttura del tipo:

    codice:
    Queue<Persona> persone = new LinkedList<Persona>();
    Tutto ciò che so del produttore-consumatore è che hai una classe Receiver ed una Trasmitter le quali implementano Runnable. I nomi sono abbastanza autoesplicativi circa la loro funzione. Suppongo che il Receiver debba implementare lo sportello, nella quale metterai un metodo per estrapolare le persone da servire, inserendo un controllo circa il numero limite di persone.

    Grazie intanto. Ho fatto il problema senza l'interfaccia grafica ed il risultato è il seguente:
    Classe Produttore:
    codice:
    public class Produttore implements Runnable {    private Buffer<Persona> buffer;
      
        
    
    
        public Produttore(Buffer<Persona> buffer) {
            this.buffer = buffer;
        }
    
    
        
        @Override
        public void run() {
            for(int i = 0;true;i++){
                Persona p = new Persona("Nome " + i, "Cognome " + i);
                buffer.put(p);
                System.out.println("Inserito " + p.toString());
                try{
                    Thread.sleep(1);
                }catch(InterruptedException e){}
      
            }
        }
        
    }
    Classe Consumatore:
    codice:
    public class Consumatore  implements Runnable{    private Buffer <Persona>   buffer;
        private int id;
    
    
        public Consumatore(Buffer<Persona> buffer, int id) {
            this.buffer = buffer;
            this.id = id;
        }
    
    
        @Override
        public void run() {
            while(true){
                Persona p = (Persona) buffer.get();
                System.out.println("Sportello " + id + " servisce Persona : " + p.toString());
                
                 try{
                    Thread.sleep((int) (5000+Math.random() * 20000));
                }catch(InterruptedException e){
                                                    }
            }
        
        }
    }
    Il Buffer:
    codice:
    public class Buffer<T> {    private LinkedList<T> queue;
        private int index;
        private int max;
    
    
        public Buffer(int max) {
            this.queue = new LinkedList<T>();
            this.max = max-1;
            index = 0;
        }
        
        
        /**
         * Restituisce l'elemento in cima alla coda
         * @return la testa della lista
         */
        public synchronized T get(){
            while(index ==0){
                try{
                    wait();
                }catch(InterruptedException e){}
            }
            T element = queue.getFirst();
            queue.remove();
            index--;
            notifyAll();
            
            return element;
        }
        
        /**
         *Inserisce un elemento in coda
         * @param element 
         */
        public synchronized void put(T element){
            while(index==max){
                try{
                   wait();
                }catch(InterruptedException e){}
            }
            queue.addLast(element);
            index++;
            notifyAll();
        }
    }
    Il main:
    codice:
    public class TestMain {    public static void main(String [] args) throws InterruptedException{
            Buffer<Persona> buffer;
            Produttore prod;
            Consumatore cons;
    
    
            buffer=new Buffer<Persona>(10);
            
            prod=new Produttore(buffer);
            Thread producer=new Thread(prod);
            producer.start();
           
            
            for(int i=1;i<=4;i++){
                cons=new Consumatore(buffer,i);
                Thread consumator=new Thread(cons);
                consumator.start();
            }
            
            
        }
    }
    Se l'eseguo sembra funzionare e il risultato mi esce scritto sulla console. Ora il mio problema è come fare in modo che il consumatore scriva nei jtextfield degli sportelli....Come posso procedere? In modo particolare come collego la gui con quanto scritto sopra?Inoltre qua ho ipotizzato che nome e cognome fossero numeri, che derivano dalla variabile del ciclo for.

  4. #4
    Ci sono utenti su questo forum molto ma molto più competenti di me in materia che saprebbero risponderti (ma non lo fanno XD). Tutto ciò che posso consigliarti è provare a dare un'occhiata al pattern observer. Io ho provato ad usarlo per problemi relativamente semplici ed è molto intuitivo. Detto in parole molto povere, le interfacce grafiche che devono modificarsi al seguito di un evento si registrano come observer, mentre chi scatena l'evento si registra come observable. Le varie views letteralmente "osservano" le classi "osservabili". Observer è un'interfaccia, quindi la classe che la implementa deve definire il metodo update(Observable obs, Object mex). In questo metodo provvederai a svolgere le operazioni che modificheranno la tua UI. Gli observable notificano che è avvenuto un cambiamento tramite i metodi setChanged() + notifyObservers(messaggio). Dovrai quindi anche creare una classe apposita che rappresenta un messaggio, in modo che all'interno del metodo update(...) potrai capire che tipo di cambiamento è avvenuto.

    Esempio di messaggio:

    codice:
    package it.dadi.message;
    
    
    public class MsgObserver {
    	
    	public final static int TURNOCOMPUTER = 0;  
    	public final static int PCGIOCATO = 1;
    	public final static int TURNOUTENTE = 2;
    	public final static int UTENTEGIOCATO = 3;
    	public final static int VINTOMANOCOMPUTER = 4;
    	public final static int VINTOMANOGIOCATORE = 5;
    	public final static int PAREGGIOMANO = 6;
    	public final static int VINTOCOMPUTER = 7;
    	public final static int VINTOGIOCATORE = 8;
    	public final static int PAREGGIO = 9;
    	public int code;
    	public Object msg;
    
    
    	public MsgObserver(int code, Object msg) {
    		this.code = code;
    		this.msg = msg;
    	}
    }
    L'ho usato per il mio giochino di dadi.

  5. #5
    Grazie dellla risposta. Comunque ho risolto passando come parametri del costruttore del consumatore i riferimenti ai componenti grafici.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Quote Originariamente inviata da paulinho Visualizza il messaggio
    Grazie dellla risposta. Comunque ho risolto passando come parametri del costruttore del consumatore i riferimenti ai componenti grafici.
    ed è sbagliato.
    All'implementazione che risolve il problema produttore/consumatore NON deve interessare di come ci si interfaccia con il mondo esterno. E' indifferente se leggi i dati da file, da console, da un altro stream oppure da grafica.
    Se tu aggiungi nel costruttore di produttore e consumatore i componenti grafici (per farci delle setText) stai di fatto creando un legame che non esiste, bypassi la logica ad oggetti e se fossi il revisore del tuo esercizio, io lo considererei errato.
    Ti è stato già suggerita la soluzione: l'observable. Quello che ti si suggerisce è che la tua applicazione crea un evento e dice "mondo io ho messo un messaggio". Il componente grafico (ma capisci bene che gestire il tutto con un componente grafico è un dettaglio) si registra come "ascoltatore" di questo evento e quando verrà creato, lui saprà come gestirlo.

    IN parole povere hai:

    1. EventMessage, classe che modellizza l'evento (ho mandato un messaggio/devo ricevere un messaggio
    2. Interfaccia EventMessageListener, avrà quando meno un metodo handle (MessageEvent) che gestisce il messaggio
    3. Classe che implementa questa interfaccia. Bada bene che può anche essere la classe che estende JFrame, questa sa chi ha dentro e sa come aggiornarsi. Se l'output fosse su file, la classe che gestisce l'output implementerà tale interfaccia, garantendo la scrittura su file
    4. EventManager, gestore degli eventi, tiene conto di chi si è registrato in ascolto di tale evento e scatena l'azione.

    Di esempi di applicazioni con eventi custom ce ne sono tanti in rete, usa google e non è difficile
    RTFM Read That F*** Manual!!!

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.