E' già stato ridefinito![]()
E' già stato ridefinito![]()
Io non posso sapere di quali "sfarfallii" parli.
Questo codice, ad esempio, disegna una linea a partire da un punto X, Y cliccato col mouse fino al punto attuale del mouse e non ha alcuno sfarfallio
codice:import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Finestra extends JApplet { private class MouseControl extends MouseAdapter implements MouseMotionListener { @Override public void mouseClicked(MouseEvent me) { setStartPoint(me.getX(), me.getY()); } @Override public void mouseDragged(MouseEvent me) { } @Override public void mouseMoved(MouseEvent me) { setEndPoint(me.getX(), me.getY()); } } private class MioPanel extends JPanel { @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.drawLine(startPointX, startPointY, endPointX, endPointY); } } private int startPointX; private int startPointY; private int endPointX; private int endPointY; @Override public void init() { Container c = getContentPane(); c.setLayout( new BorderLayout() ); MouseControl control = new MouseControl(); MioPanel mp = new MioPanel(); mp.addMouseListener( control ); mp.addMouseMotionListener( control ); c.add(mp, BorderLayout.CENTER); } private void setStartPoint(int x, int y) { startPointX = x; startPointY = y; } private void setEndPoint(int x, int y) { endPointX = x; endPointY = y; repaint(); } }
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
Forse la cosa più corretta da fare è ripristinare il codice funzionante che avevo e riseguire la procedura passo passo, che ne dici?
@LeleFT @mkd_
Il fatto è questo: un discorso è se la paint() o paintComponent() viene chiamata 1 sola volta perché chiamo repaint 1 sola volta in tutto il programma e allora il flicker non può sussistere.
Ma se paint() o paintComponent() viene chiamata in continuazione in seguito al richiamare la repaint perché il grafico è in tempo reale e cambia in continuazione (questo dall'esposizione del programma di mkd non lo so) allora certamente un flicker ci sarà e sono i casi in cui si usa proprio il double buffering per ovviare il problema.
Grazie per il tuo contributo c0der, senza dubbio molto apprezzato. Il flicker di cui parlo è un ritardo: la sua espressione più lampante è che sul grafico il puntatore a croce che si muove assieme al mouse "segue" quest' ultimo con grande ritardo, risultando fastidioso agli occhi.
Il bello è che ho appena ripristinato la copia di sicurezza effettuata prima di eseguire l' intervento di LeleFT (che molto probabilmente ha fatto delle osservazioni corrette): funziona tutto alla grande.
Attualmente ho una JApplet che contiene un JPanel sul quale è mostrato il grafico e il mouse. Ecco come scrivo sul grafico
Tutto qui..! Nessun paintComponent() è overridato in nessuna classe. Poi avevo cercato di aggiungere un ulteriore JPanel e un JSplitPane e c'era un piccolo errore grafico (non si vedeva il divider) e poi è scoppiato il putiferiocodice:public void paint(Graphics g) { Image buffervirtuale=createImage(pannelloGrafico.getWidth() ,pannelloGrafico.getHeight()); Graphics2D gr=(Graphics2D)buffervirtuale.getGraphics(); grafico.draw(gr,mouseX,mouseY); //ESEGUE VARI CALCOLI ((Graphics2D)pannelloGrafico.getGraphics()).drawImage(buffervirtuale,0,0,this); }(se non hai presente l' altra discussione ti posto il link)
Tu il double buffering lo usi già: è proprio il disegnare su una immagine e poi chiamare drawImage alla fine.
Il ritardo potrebbe stare probabilmente nel fatto che ricrei buffervirtuale tutte le volte.
Dovresti dichiarare buffervirtuale come variabile privata della classe e poi:
codice:private Image buffervirtuale; public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; if (buffervirtuale == null) buffervirtuale = createImage(pannelloGrafico.getWidth(), pannelloGrafico.getHeight()); //else // qui se ti serve fai un fillRect su buffervirtuale per ripulirlo Graphics2D gr = (Graphics2D)buffervirtuale.getGraphics(); grafico.draw(gr, mouseX, mouseY); //ESEGUE VARI CALCOLI g2.drawImage(buffervirtuale, null, 0, 0); }
Questa che ho appena postato è la situazione precedente quando tutto funzionava.. e grazie al cielo funziona
Ora, in effetti il problema è che dovrei aggiungere un secondo pannello, che mostra un altro grafico. E fino a qui nessun problema; il problema viene nel momento in cui io devo inserire questi due pannelli dentro ad un altro JPanel che li contenga (o ad un contenitore come il JSpletPane). Ho appena provato ma il risultato è che non si vede nulla.. tu come ti muoveresti?P
Quel che farei, e che ho è fatto, è stato
1) Creare un nuovo JPanel
2) addare il nuovo JPanel all' applet
3) addare il JPanel del grafico al JPanel appena creato
ma purtroppo non si vede nullae qui vengono le ragioni di lele che propone l' override del paintComponent, ma proprio non vuol funzionare nulla... tant'è che ho ripristinato il backup
![]()
A me quello che sembra sbagliato nel tuo codice è che la drawImage dell'ultima riga la devi chiamare sull'oggetto Graphics che viene passato come argomento alla paint() o alla paintComponent() non su un altro. Vedi come ho corretto nel mio.
Ho provato, ma saltano fuori errori grafici. Non dovrebbe essere necessario che si disegni nel JPanel? Se disegno direttamente sulla JApplet possono verificarsi degli errori, in quanto è il pannello che deve contenere l' immagine del grafico
Qui mi sembra che regni un po' la confusione, riprovo a fare un sommario della situazione.
Hai:
- ClassePrincipale (JApplet)
- ChartWindow (JPanel) - già qui non mi è chiaro perché la chiami Window, non essendo una finestra
- nel costrutture di ChartWindow aggiungi 2 oggetti Grafico - sono solo strutture dati e funzioni non derivano da swing, giusto?
Ora questo metodo paint(), o paintComponent() che sia, io ho capito che è della classe ChartWindow, che è un JPanel.
È giusto così? Non vedo dove siano i problemi.
P.S. Aggiungo che tu puoi avere anche 100 JPanel e disegnarli tutti da un metodo in una classe esterna. Basta che ogni JPanel abbia la proprio immagine buffer e rendi visibili tutte queste immagini buffer e i JPanel al metodo che disegna.
Poi in quel metodo per ogni JPanel fai:
Graphics2D gr = (Graphics2D)buffervirtuale.getGraphics();
... disegni con gr ...
panel.repaint();
la repaint causerà l'esecuzione del metodo paint() o paintComponent del tuo JPanel in cui semplicemente disegnerai quella immagine buffer a schermo tramite la drawImage chiamata sul Graphics che ti arriva come argomento.