Visualizzazione dei risultati da 1 a 4 su 4

Discussione: GUI interattiva

  1. #1

    GUI interattiva

    Salve ragazzi,
    volevo chiedermi se potevate darmi una mano con un problema. Sto sviluppando un applicazioncina che lavora sulle liste concatenate, quella presente in questo codice può essere sostituita con la Linked List di java.
    Arrivo al dunque, ho creato un frame in cui è contenuto un pannello su cui vado a disegnare gli elementi contenuti nella lista.
    All'inizio creo una lista, gli aggiungo un elemento e la passo al costruttore del pannello per poterla rappresentare, fin qui tutto ok.
    Ho aggiunto un pulstante che se cliccato crea una nuova lista, vi aggiunge un elemento. questa lista viene passato al costruttore che riassegna l'area disegno. Qui ho il problema, ovvero l'area non viene aggiornata e mi rimangono le informazioni precedenti, anche richiamando il metodo "repaint()"


    codice:
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.font.*;
    import java.awt.geom.*;
    import java.util.ListIterator;
    
    import javax.swing.*;
    
    import poo.progetto.Lista;
    import poo.progetto.ListaConcatenata;
    
    public class FontTest
    {  
       public static void main(String[] args)
       {  
    	   TestFrame frame = new TestFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setVisible(true);
       }
    }
    
    /**
       A frame with a text message panel
    */
    class TestFrame extends JFrame
    {
    	private Lista l = null;
    	private Lista l2 = null;
    	private AreaDisegno area = null;
       public TestFrame()
       {
          setTitle("TestFrame");
          setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
          
         
          l = new ListaConcatenata<String>();
          l.addFirst("prova");
          
          area = new AreaDisegno(l) ;
        
          JScrollPane scroll = new JScrollPane(area);
          
          JButton prova = new JButton("prova");
          
          prova.addActionListener(new ActionListener() {		
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			l2 = creaLista();
    			l2.addFirst("aaaaaaaaaa");
    			area = new AreaDisegno(l2);
    			return;
    			
    		}
    	});
         // scroll.setPreferredSize(new Dimension(200,200));
          add(scroll, BorderLayout.CENTER);
          add(prova, BorderLayout.SOUTH);
    
       }
    
       public static final int DEFAULT_WIDTH = 300;
       public static final int DEFAULT_HEIGHT = 200;  
    
    public Lista creaLista(){
    	return new ListaConcatenata<String>();
    }}
    
    
    class AreaDisegno extends JPanel{
    	private Lista lista;
    	Dimension spazioUtilizzato = new Dimension(0, 0);
    	
    	public AreaDisegno(){
    		this.lista = null;
    		this.setBackground(Color.WHITE);
    		this.setPreferredSize(spazioUtilizzato);
    	}
    	
    	public AreaDisegno(Lista l){
    		this.lista = l;
    		this.setBackground(Color.WHITE);
    		
    		this.setPreferredSize(spazioUtilizzato);
    		
    	}
    	
    	
    	public void paintComponent(Graphics g) {
    		if(lista==null)
    	    	return;
    		super.paintComponent(g);
    		Graphics2D g2 = (Graphics2D) g;
    		//settiamo il font da utilizzare
    		Font f = new Font("Serif", Font.BOLD, 30);
    		g2.setFont(f);
    	    //le coordinate iniziali 
    	    double x = 20;
    	    double y = 20;
    	  
    	    
    	    ListIterator it = lista.listIterator();
    	    
    	    while(it.hasNext()){
    	    	//acquisiamo le info per il rettangolo k contiene la parola
    	    	
    	    	String info = it.next().toString();
    	    	
    	    	FontRenderContext context = g2.getFontRenderContext();
    	        Rectangle2D bounds = f.getStringBounds(info, context);
    	        //per inserire bene il testo
    	        double ascent = -bounds.getY();
    	        double baseY = y + ascent;
    	        //disegniamo la stringa
    	        g2.drawString(info, (int)x, (int)baseY);
    	        //disegnamo il rettangolo intorno
    	        Rectangle2D rect = new Rectangle2D.Double(x-5, y-5, bounds.getWidth()+10, bounds.getHeight()+10);
    	        g2.draw(rect);
    	        if(it.hasNext()){ 
    	        	int oldX = (int)(x+(bounds.getWidth()+5));
    	        	int newX = (int) oldX+40-10;
    	        	int lineY = (int) (y+(bounds.getHeight()/2));		        	
    	        	g2.drawLine(oldX, lineY, newX, lineY);
    	        }
    	        x += bounds.getWidth()+10+30;
    	    }
    	    
    	    if(x >= spazioUtilizzato.getWidth()){
    	    	setPreferredSize(new Dimension((int)x, 0));
    	    	revalidate();
    	    }
    	   
    	}
    }

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: GUI interattiva

    Originariamente inviato da odnoder90
    Ho aggiunto un pulstante che se cliccato crea una nuova lista, vi aggiunge un elemento. questa lista viene passato al costruttore che riassegna l'area disegno. Qui ho il problema, ovvero l'area non viene aggiornata e mi rimangono le informazioni precedenti, anche richiamando il metodo "repaint()"

    codice:
    area = new AreaDisegno(l2);
    Con la riga che ho appena quotato tu non hai fatto nulla di speciale se non istanziare solamente un nuovo oggetto AreaDisegno ed assegnarlo ad un campo di istanza. Ma non hai fatto nulla a video. Solo per il fatto di aggiornare un campo di istanza .... non vuol dire nulla. La nuova istanza del tuo nuovo pannello non l'hai appunto messa in un "contenitore".

    La soluzione più veloce sarebbe aggiungere semplicemente:

    scroll.setViewportView(area);

    Dove scroll è il tuo JScrollPane, che a questo punto sarebbe meglio se tieni tra i campi di istanza (altrimenti la variabile locale 'scroll' che hai adesso dovresti dichiararla final).

    Ma c'è una soluzione, a livello di design, più pulita. Invece di dover istanziare un nuovo AreaDisegno ogni volta fai in modo da cambiare lo "stato" di quello (unico) che hai già. Semplicemente metti nella tua classe AreaDisegno un metodo es. setLista(Lista lista) che fa banalmente 2 cose: a) Aggiorna il campo di istanza 'lista' (ovviamente) e poi invoca repaint().

    Tutto qui.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Grazie mille funzionano entrambi i metodi, ovviamenta

    però se utilizzo il secondo mi dà alcuni problemi di visualizzazione, ovvero alcune linee non vengono completamente disegnate (in corrispondenza di una finestra di dialogo che faccio aprire in un altra applicazione) oppure si vanno a sovrapporre ad altre, o infine non mi visualizza più le nuove informazioni aggiunte. Tutti questi problemi spariscono se ridimensione "manualmente" la finestra, mentre non si presentano se utilizzo:
    codice:
     scroll.setViewportView(area);
    sapresti dirmi il perchè?

  4. #4
    Il problema riportato si verifica solo se l'AreaDisegno è inserita in un Frame che contiene altri pannelli, se è da solo il funzionamento è perfetto con entrambi i metodi.


    Dopo ulteriori verifiche ho notato che in alcuni casi il problema si ripresenta anche se AreaDisegno è l'unico pannello del frame.

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.