|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Junior Member
Iscritto dal: Feb 2010
Messaggi: 4
|
[Java] Swing - Problema aggiornamento pannello tramite Graphics2D
Ciao a tutti,
Avrei bisogno di un consiglio per completare un piccolo programmino che sto facendo... Il programma disegna una funzione con dei pallini al posto della tracciatura del grafico, ho fatto decine di prove, ma evidentemente non ho capito bene come si faccia a disegnare "progressivamente" su di un panel... l'applicazione in se funziona e fa quello che deve, solo che non è completa, e dovrei completarla facendo appunto fare la progressione del disegno di tale funzione sul pannello invece me la disegna o tutta ( tutta in blocco) oppure son riuscito a disegnare solo un pallino... Inoltre la progressione mi è venuto in mente che potrebbe essere "rallentata" attraverso un thread, tuttavia son riuscito a rallentare al massimo l'aggiornamento dello coordinate e non il disegno in se... So che sto sbagliando il "modo" in cui richiamo il paintComponent(Graphics g).. però mi sembra che il metodo update() non abbia effetto... Insomma, mi son un pò impantanato.. qualche consiglio ??? Ho trovato esempi in giro, tuttavia riguardano al 90% applet e purtroppo io non posso lavorare con le applet ma Devo per forza risolvere questo "mistero"... Grazie in anticipo. Codice:
import java.awt.*; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.*; // necessario per le linee 2D import javax.swing.*; import javax.swing.event.*; // necessario per changelistener import java.util.Random; class EsercizioTrigonometrico extends JFrame { private Pannello panTrigo; private JSlider ctrCicli; private JButton crea; private JButton cancella; private Random rand; // per il numero random public EsercizioTrigonometrico() { Container cnt = getContentPane(); panTrigo = new Pannello(); rand = new Random(); crea = new JButton("Draw"); cancella = new JButton("Cancel"); panTrigo.setBounds (0,0,400,400); panTrigo.creaCordinate(); cnt.add(BorderLayout.CENTER, panTrigo); cnt.add(BorderLayout.EAST, cancella); cnt.add(BorderLayout.WEST, crea); } // Metodo che genera un colore random public Color randomColor(){ return(new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255))); // l'ultimo serve per la trasparenza del colore } // pannello della funzione trigonometrica class Pannello extends JPanel { private int DensPUNTI = 60; // densità dei punti 30 private static final int nrCicli =3; // numero dei cicli private int nrPunti = 360; // numero dei punti 180 private static final int NrBOLLExCICLO = 30; private double[] cordinateDouble = new double[nrPunti];// array di double di 180 posizioni ? private int[] cordinateInt; // altre dichiarazioni private int numeroBolle = nrPunti / (NrBOLLExCICLO*nrCicli); // 180 punti diviso 180 bolle private int maxHeight = 400; private int maxWidth = 400; private double h = (double) maxWidth/(double)nrPunti; // Determinazione del passo di campionamento public Pannello() { } public void creaCordinate() { for(int i = 0; i < nrPunti; i++) { double rad = (Math.PI / DensPUNTI) * i; cordinateDouble[i] = Math.sin(rad); } // Determinazione delle coordinate intere di visualizzazione cordinateInt = new int[nrPunti]; for(int i = 0; i < nrPunti; i++) { cordinateInt[i] = (int)(cordinateDouble[i] * maxHeight/2 * .95+maxHeight/2); } } // uso di paintComponent() public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; for(int i = 0; i < nrPunti; i++) { // Tracciatura del grafico nrPunti int x1 = (int) ((i)*h); int y1 = cordinateInt[i]; if(i % numeroBolle == 0) { g2.setColor(randomColor()); g2.fill(new Ellipse2D.Double(x1,y1, 30, 30)); /* try{ Thread.sleep(100); repaint(); System.out.println(i); }catch(InterruptedException e) {}*/ } } } } public static void main(String[] args) { JFrame trigonometria = new EsercizioTrigonometrico(); trigonometria.setBounds(100,100,700,500); trigonometria.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); trigonometria.setVisible(true); } } Sistema Operativo - Ubuntu Compilatore - Geany 0.16 Ultima modifica di JavaError : 08-02-2010 alle 16:04. |
![]() |
![]() |
![]() |
#2 |
Junior Member
Iscritto dal: Feb 2010
Messaggi: 4
|
piccolo passo in avanti...
Ho creato un metodo apposta per suddividere il lavoro, tuttavia rimane il fatto che crea effettivamente le bolle ( con System.out.prinltln) lo controllo...
Però non riesco a disegnarle sul pannello! Codice:
//metodo che dovrebbe mandare in creazione tutte le bolle una dietro l'altra // e lo fa!!! ma viene disegnata solo l'ultima bolla! public void disegnaBolle() { for(int i = 0; i < 360; i++) { // Tracciatura del grafico 360 punti int x1 = (int) ((i)*h); int y1 = cordinateInt[i]; if(i % numeroBolle == 0) { disegnaUnaBolla(x1, y1, 30, randomColor()); System.out.println(bolla.getX()+" "+bolla.getY()); } } } // metodo che dovrebbe disegnare una unica bolla public void disegnaUnaBolla(int x1, int y1, int r, Color c) { bolla = new Bolla(x1,y1,r,c); System.out.println("Hai creato una bolla"); // verifica che venga creata repaint(); } // metodo che dovrebbe servire a mantenere i dati presenti in graphics ( g ) public void update(Graphics g) { paint(g); } // uso di paintComponent() - Disegna 1 Bolla con i valorei passati public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; if(bolla != null) { // disegna l'interfaccia anche se non ci sono bolle g2.setColor(bolla.getColore()); g2.fill(new Ellipse2D.Double(bolla.getX(),bolla.getY(),bolla.getR(),bolla.getR())); } } idee... ? ( anche vaghe!) brancolo nel buio.. ![]() |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Il problema ha molte soluzioni, abbastanza per poter affermare: "puoi fare come preferisci". Si tratta semplicemente di scegliere l'astrazione che più ti convince. Esempio.
Supponiamo di avere un componente P che estende JPanel e ha una lista L di oggetti "Paintable". Un oggetto "Paintable" è tale se possiede un metodo paint(Graphics g). Il metodo paintComponent di P dice: per ogni Paintable x in L, x.paint(g) Questo pannello "P" ha un metodo, "addPaintable(Paintable p)" che: aggiunge p a L invoca repaint Fine. Il disegno di P è cumulativo nel senso che puoi passargli un nuovo punto ogni 3 secondi, quel punto va nella lista, e l'invocazione di repaint causa il disegno di tutti i punti finora aggiunti a P. Per temporizzare il disegno puoi generare una pila di punti e poi passare quella pila a un Timer (javax.swing.Timer) che ogni X millisecondi estrae un punto e lo passa a P.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#4 |
Junior Member
Iscritto dal: Feb 2010
Messaggi: 4
|
Molte soluzioni...
Capisco quello che mi hai postato, ma cercherò di essere più preciso..
Allora... io ho creato una classe che crea una elemento Bolla che contiene i parametri di un Ellipse2D... tale oggetto bolla, viene poi creato in modo sequenziale in base alle coordinate che un altro metodo mi crea per il disegno del grafico sul JPanel... Per disegnare il tutto insieme, c'ero già riuscito come dicevo all'inizio ora...dovrei ottenere un animazione incrementale del processo di disegno... Ora visto che le bolle ci sono, le coordinate pure, il passaggio di parametri pure, mi chiedo perché il metodo paintComponent(Graphics g) mi disegna solamente l'ultima bolla ?? praticamente il repaint() è come se non lo sentisse infatti viene invocato 2 volte... ho notato che: super.paintComponent(g); basandomi su altri esercizi dovrebbe servire a ripulire il pannello prima di disegnare altro e quindi non dovrei usarlo infatti per ora l'ho messo tra \\.... Ora mi domando come posso conservare il disegno effettuato sul pannello tramite paintComponent(Graphics g) ?? Se sposto tutto il processo di disegno all'interno del paintComponent ottengo il risultato che vedi in figura... il risultato deve essere il medesimo, tuttavia utilizzando un Thread e non un timer dovrei vedere lo sviluppo.. sinceramente il thread non dovrei avere problemi ad implementarlo invece il fatto di disegnare 2 bolle una consecutiva all'altra senza che venga resettato il pannello quello per ora ( anche se mi sembra strano che in altri esercizi ( applet ) mi venga) non riesco a farlo... Se puoi/vuoi sai dove trovare un esempio che mi disegni tramite paintComponent 2 ellissi sullo stesso panello.. Io sto cercando ma non trovo niente.. da notare che invece.. con il metodo public void paint (Graphics g) { sto facendo delle prove e non mi sembra che ci sian gli stessi problemi.. ![]() |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Una soluzione è quella che ti ho già proposto. Posso farti un esempio:
Codice:
import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import java.util.LinkedList; import java.util.Random; public class Main { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { new Main().execute(); } }); } private void execute() { final int WIDTH = 500; final int HEIGHT = 500; final long DURATIONMS = 10000; final int RESOLUTIONMS = 25; final PCanvas CANVAS = new PCanvas(); final Parametric PARAMETRIC = new Sinusoid(CANVAS, WIDTH, HEIGHT); final Generator GENERATOR = new Generator(PARAMETRIC, DURATIONMS, RESOLUTIONMS); final JFrame WINDOW = new JFrame("Test"); final JButton START = new JButton(new AbstractAction("Start") { public void actionPerformed(ActionEvent e) { GENERATOR.start(); } }); CANVAS.getComponent().setPreferredSize(new Dimension(WIDTH, HEIGHT)); CANVAS.getComponent().setBackground(Color.WHITE); WINDOW.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); WINDOW.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { GENERATOR.stop(); } }); WINDOW.add(CANVAS.getComponent()); WINDOW.add(START, BorderLayout.SOUTH); WINDOW.pack(); WINDOW.setVisible(true); } } class Sinusoid implements Parametric { private final Random RANDOM = new Random(0); private final PCanvas CANVAS; private final int WIDTH; private final int HEIGHT; public Sinusoid(PCanvas canvas, int width, int height) { CANVAS = canvas; WIDTH = width; HEIGHT = height; } public void apply(Double t) { final double Y = HEIGHT / 2 * Math.sin(t * 2 * Math.PI) + HEIGHT / 2; final double X = WIDTH * t; //(0 ~ WIDTH) final double RAY = 5; final Color FILL = new Color(RANDOM.nextInt(255), RANDOM.nextInt(255), RANDOM.nextInt(255)); final Bubble BUBBLE = new Bubble(X, Y, RAY, FILL); CANVAS.push(BUBBLE); } } class Generator { private final TimeLine TIMELINE = new TimeLine(); private final Parametric FUNCTION; private final javax.swing.Timer TIMER; private final long DURATION; public Generator(Parametric fun, long durationMs, int resolutionMs) { FUNCTION = fun; DURATION = durationMs; TIMER = new javax.swing.Timer(resolutionMs, new ActionListener() { public void actionPerformed(ActionEvent e) { applyParametric(); } }); } private void applyParametric() { double t = (double)TIMELINE.get() / (double) DURATION; TIMELINE.update(); if(t >= 1) { t = 1; FUNCTION.apply(t); stop(); } else { FUNCTION.apply(t); } } public void start() { TIMELINE.start(); TIMER.restart(); } public void stop() { TIMER.stop(); } } class TimeLine { private final long MILLION = 1000000; private long then; private long time; public void start() { then = System.nanoTime(); time = 0; } public void update() { long now = System.nanoTime(); long dTimeNanos = now - then; then = now; time += dTimeNanos / MILLION; } public long get() { return time; } } interface Parametric { public void apply(Double t); } interface Paintable { void paint(Graphics g); } class PCanvas { private final LinkedList<Paintable> PAINTABLES = new LinkedList<Paintable>(); private final JPanel PANEL = new JPanel() { @Override protected void paintComponent(Graphics graphics) { super.paintComponent(graphics); for(Paintable p : PAINTABLES) { p.paint(graphics); } } }; public void push(Paintable p) { PAINTABLES.push(p); PANEL.repaint(); } public void clear() { PAINTABLES.clear(); PANEL.repaint(); } public Component getComponent() { return PANEL; } } class Bubble implements Paintable { private final Color FILL; private final Shape SHAPE; public Bubble(double x, double y, double ray, Color fill) { FILL = fill; SHAPE = new Ellipse2D.Double(x - ray, y - ray, 2 * ray, 2 * ray); } public void paint(Graphics g) { Graphics2D graphics = (Graphics2D) g; graphics.setPaint(FILL); graphics.fill(SHAPE); } }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#6 |
Junior Member
Iscritto dal: Feb 2010
Messaggi: 4
|
ok, ho risolto
![]() ![]() alla prox. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:22.