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

    JFrame repaint

    Salve a tutti ho un problemino in un programma java che sto facendo, sono alle prime armi, l'idea di base è fare un piccolo paint che disegni figure geometriche.Ho creato un JFrame e ho inserito dentro un Jpanel per disegnare,il problema è che se ridimensiono il JFrame con il mouse il disegno sparisce.
    Sicuramente sarà una stupidata da niubbo cmq posto un pò di codice:
    codice:
    import java.awt.*;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.Line2D;
    import java.awt.geom.Rectangle2D;
    import java.util.LinkedList;
    
    import javax.swing.*;
    
    public class Interface {
    	PanPaint drawpan;
    	
    public Interface(){
    	JFrame frame = new JFrame("Paint");
    	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	frame.setSize(1300,800);
    	frame.setVisible(true);
    	drawpan = new PanPaint();
    	JMenuBar bar = new JMenuBar();
    	JMenu file = new JMenu("File");
    	JMenuItem nuovo =new JMenuItem("Nuovo");
    	JMenuItem apri = new JMenuItem("Apri");
    	JMenuItem salva = new JMenuItem("Salva");
    	JMenu shape = new JMenu("Figura");
    	JMenuItem line = new JMenuItem("Linea");
    	JMenuItem ellipse =new JMenuItem("Cerchio");
    	JMenuItem square = new JMenuItem("Rettangolo");
    	Open open= new Open(drawpan);
    	Save save = new Save(drawpan);
    	New pulisci = new New(drawpan);
    	Line linea = new Line(drawpan);
    	Rect rettangolo = new Rect(drawpan);
    	Ellipse ellisse = new Ellipse(drawpan);
    	salva.addActionListener(save);
    	apri.addActionListener(open);
    	nuovo.addActionListener(pulisci);
    	line.addActionListener(linea);
    	ellipse.addActionListener(ellisse);
    	square.addActionListener(rettangolo);
    	shape.add(line);
    	shape.add(ellipse);
    	shape.add(square);
    	file.add(nuovo);
    	file.add(apri);
    	file.add(salva);
    	bar.add(BorderLayout.EAST,file);
    	bar.add(shape);
    	frame.add(BorderLayout.NORTH,bar);
    	frame.add(BorderLayout.CENTER,drawpan);
    	
    	
    }
    
    
    public static void main(String[] args){
    	Interface interfaccia = new Interface();
    	}
    }
    class PanPaint extends JPanel {
    	private static final long serialVersionUID = 1L;
    	public LinkedList<Shape> shapes;
    	public Line2D linea;
    	public Rectangle2D rect;
    	public Ellipse2D ellipse;
    	boolean repaintReq= false;
    	
    	public PanPaint(){
    		shapes = new LinkedList<Shape>();
    		setLayout(new BorderLayout());
    	}
    	
    	public void draw(int x1,int y1,int x2, int y2,char a){
    		switch(a) {
    		case 'l':	linea = new Line2D.Double(x1,y1,x2,y2);
    					shapes.addFirst(linea);
    					repaintReq = true;
    					repaint();
    					break;
    			
    		case 'r':	rect = new Rectangle2D.Double(x1,y1,x2,y2);
    					shapes.addFirst(rect);
    					repaintReq = true;
    					repaint();
    			break;
    			
    		case 'e':	ellipse= new Ellipse2D.Double(x1,y2,x2,y2);
    					shapes.addFirst(ellipse);
    					repaintReq=true;
    					repaint();
    			break;
    			}
    	}
    	public void paintComponent(Graphics g){
    		super.paintComponents(g);
    		Graphics2D g2=(Graphics2D) g;
    		if(shapes.size()!=0)
    		if(repaintReq){
    			repaintReq = false; 
    			g2.draw(shapes.getFirst());
    		}
    		else
    			for(int i = 0; i==shapes.size();i++)
    				g2.draw(shapes.get(i));
    		
    	}
    	
    }

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

    Re: JFrame repaint

    Originariamente inviato da goldegard
    Ho creato un JFrame e ho inserito dentro un Jpanel per disegnare,il problema è che se ridimensiono il JFrame con il mouse il disegno sparisce.
    Dovrei provare il tuo codice per vedere come si comporta realmente. Ma già solo a vedere il codice posso dirti e suggerirti alcune cose.

    Innanzitutto il concetto di passare al draw un "flag" che indica il tipo di elemento da disegnare non è di per sé sbagliato. Ma è tuttavia poco "pulito" e intuitivo. Sarebbe meglio avere dei metodi separati es. addLine, addRectangle, addEllipse o cose del genere. Eviti lo switch e rendi più chiaro cosa fanno i metodi.

    Nota subito bene che hai fatto:

    super.paintComponents(g);

    NO, non è paintComponents() da invocare ma super.paintComponent(g) (senza s). Questo è importante.

    Poi il fatto del flag repaintReq per disegnare solo il primo NON è una buona cosa. paintComponent è il "contesto" di disegno del componente e dovrebbe operare in maniera "totalitaria": disegno tutto.

    Se anche correggi e metti super.paintComponent(g); questo resetta tutto e se repaintReq è true tu vedresti solo l'ultimo aggiunto e non tutto, perché il resto è nel ramo else del if.

    Se vuoi fare delle "ottimizzazioni" per evitare ri-disegni inutili, si possono fare. Ma non in quel modo.

    Infine:
    for(int i = 0; i==shapes.size();i++)

    i==shapes.size() comunque non è corretto.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Originariamente inviato da goldegard
    il problema è che se ridimensiono il JFrame con il mouse il disegno sparisce.
    PanPaint è un componente lightweight, quindi puoi benissimo fare l'override del metodo paint().
    Il problema dovrebbe risolversi.

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da VincenzoTheBest
    PanPaint è un componente lightweight, quindi puoi benissimo fare l'override del metodo paint().
    Ehm .. no. Allora: tecnicamente sì, certo che si può fare. Ma in generale sarebbe meglio di no (e salvo casi particolari).

    Per i componenti Swing (per cui c'è l'apposito paintComponent), l'override di paint andrebbe fatto SOLO se si sa davvero che cosa si sta facendo. Chiarisco meglio: il paint in JComponent "fattorizza" il disegno in 3 fasi (in questo ordine): prima paintComponent, poi paintBorder, poi paintChildren.

    Se si facesse banalmente l'override di paint così:

    codice:
    public void paint(Graphics g) {
        super.paint(g);
        .........
    }
    Se nel componente ci fosse un bordo (Border) e/o dei componenti dentro, si potrebbe (anche solo per errore) andare a disegnare sopra bordi/componenti!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Originariamente inviato da andbin
    Se nel componente ci fosse un bordo (Border) e/o dei componenti dentro, si potrebbe (anche solo per errore) andare a disegnare sopra bordi/componenti!
    In questo caso non ci sono nè bordi nè sub-componenti. Il PanPaint è creato appositamente per disegnarci sopra, non per apportare modifiche strutturali.

    Poi se l'utente vuole continuare ad usare paintComponent per me va benissimo.

  6. #6
    ok andbin ti ringrazio per i consigli e mi applico subito per apportare le modifiche! Tuttavia mi viene un dubbio teorico cioè: quando ridimensiono la finestra con il mouse viene automaticamente chiamato un repaint() del JFrame...ma i componenti interni come vengono ridisegnati?in sostanza il repaint tiene conto del metodo paint() di cui ho fatto l'override all'interno della classe PanPaint che estende il JPanel?

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da goldegard
    quando ridimensiono la finestra con il mouse viene automaticamente chiamato un repaint() del JFrame...
    Tecnicamente (e detto così) no. Il ridimensionamento causa sì, certamente, un ridisegno del JFrame ma tecnicamente non passa dal repaint() sul JFrame. Non ci vuole molto per verificarlo (e se vuoi, provalo pure): se in un TuoJFrame fai l'override di repaint(), esso non viene chiamato se ridimensioni solo il frame.

    Originariamente inviato da goldegard
    ma i componenti interni come vengono ridisegnati?
    Con dei repaint() in "cascata" lungo tutto l'albero di componenti.

    Originariamente inviato da goldegard
    in sostanza il repaint tiene conto del metodo paint() di cui ho fatto l'override all'interno della classe PanPaint che estende il JPanel?
    Come ho già chiarito prima, nei componenti Swing meglio gestire/sovrascrivere paintComponent, non paint.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8
    si scusa intendevo l'override di paintComponent().Ma allora attraverso quale sistema posso fare in modo che una volta che la finestra sia ridimensionata o ridotta a icona e poi richiamata, mi ridisegni tutti i componenti dentro al JPanel?

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da goldegard
    si scusa intendevo l'override di paintComponent().Ma allora attraverso quale sistema posso fare in modo che una volta che la finestra sia ridimensionata o ridotta a icona e poi richiamata, mi ridisegni tutti i componenti dentro al JPanel?
    Niente di particolare ... solo "disegnare" nel paintComponent del tuo pannello.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  10. #10
    Bueno cercherò di capire dove stà l'inghippo...per ora grazie della consulenza!!

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.