|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
[Java] problema metodo paint(Graphics g)
Ho scritto quest'applicazione che, una volta schiacciato il bottone, permette di disegnare delle piccole X con colore casuale sul pannello, mandando ai JtextField X e Y le coordinate in cui si è cliccato sul pannello.
Tuttavia non capisco perchè non mi disegna le crocette sul pannello, che ho settato come opaco e su cui invoco la repaint(); (ho provato anche a mettere la validate(); prima, ma non cambia nullla)..non capisco cosa sbaglio... Codice:
package pacchetto; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; public class Prova extends JFrame{ public static void main(String [] args){ JFrame x=new JFrame(); x.setSize(new Dimension(400,400)); x.setResizable(true); x.setContentPane(new Pannello()); x.setDefaultCloseOperation(EXIT_ON_CLOSE); x.setVisible(true); } } public class Pannello extends JPanel{ int red,green,blue,X,Y; Random generatore=new Random(System.currentTimeMillis()/27); JButton bottone; JLabel stato,x,y; JFormattedTextField uno,due; JPanel pane; public Pannello(){ this.setBackground(Color.LIGHT_GRAY); this.setLayout(new GridBagLayout()); GridBagConstraints c=new GridBagConstraints(); bottone=new JButton("Cambia stato"); bottone.addActionListener(new Abilita()); c.weightx=1; c.fill=GridBagConstraints.HORIZONTAL; c.weightx=1; c.weighty=0; c.gridx=0; c.gridy=0; c.gridwidth=1; add(bottone,c); stato=new JLabel(""); c.gridx=1; c.gridy=0; c.gridwidth=1; c.anchor=GridBagConstraints.CENTER; c.insets.left=5; add(stato,c); x=new JLabel("X="); c.gridx=2; c.gridy=0; c.anchor=GridBagConstraints.CENTER; c.gridwidth=1; c.weightx=1; c.weighty=0; c.insets.left=50; add(x,c); y=new JLabel("Y="); c.gridx=2; c.gridy=1; c.gridwidth=1; add(y,c); uno=new JFormattedTextField(); c.gridx=3; c.gridy=0; c.gridwidth=1; c.insets.left=5; add(uno,c); due=new JFormattedTextField(); c.gridx=3; c.gridy=1; c.gridwidth=1; add(due,c); pane=new JPanel(); pane.setBackground(Color.WHITE); pane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); pane.setOpaque(true); c.fill=GridBagConstraints.BOTH; c.gridx=0; c.gridy=2; c.gridwidth=4; c.gridheight=1; c.insets.top=5; c.weightx=1; c.weighty=1; add(pane,c); } class Abilita implements ActionListener{ boolean isActive=false; public void actionPerformed(ActionEvent e) { if(isActive==false){ stato.setText("ATTIVATO"); isActive=true; pane.addMouseListener(new Disegno()); } else if(isActive==true){ isActive=false; stato.setText("DISATTIVATO"); pane.removeMouseListener(pane.getMouseListeners()[0]); uno.setText(""); due.setText(""); } } } class Disegno implements MouseListener{ public void mouseClicked(MouseEvent e) { X=e.getX(); Y=e.getY(); uno.setText(String.valueOf(X)); due.setText(String.valueOf(Y)); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} } public void paint(Graphics g){ super.paint(g); green=generatore.nextInt(255)+1; red=generatore.nextInt(255)+1; blue=generatore.nextInt(255)+1; g.setColor(new Color(red,green,blue)); g.drawLine(X-5, Y+5, X+5, Y-5); g.drawLine(X-5, Y-5, X+5, Y+5); repaint(); } } |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Scusami, ma che ci fa un metodo paint() che prende un Graphics e ci disegna sopra dentro la classe Disegno che altro non è se non l'implementazione di un MouseListener?
Forse volevi fare l'override di paintComponent() del JPanel in cui vuoi eseguire il rendering... il MouseListener al massimo ascolterà, appunto, gli eventi del mouse che ti interessano per estrarre informazioni utili ai fini del tuo rendering (coordinate evento click del mouse, per esempio). Mi pare tu abbia ancora le idee poco chiare su certi concetti: ti rilinko questo otiimo e breve tutorial
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
il tutorial che hai linkato non parla mica del custom graphics...
il metodo paint(Graphics g); viene invocato ogni volta che clicco sul pannello pane. poichè il metodo paint non va mai richiamato direttamente, invoco il repaint su pane (le X vanno disegnate solo all'interno del pannello pane)... e infatti cliccando sul pannello, dopo averlo attivato, riesco a mandare le nformazioni sulle coordinate ai textfield. ma perchè non disegna la croce??? class Disegno implements MouseListener{ public void mouseClicked(MouseEvent e) { X=e.getX(); Y=e.getY(); uno.setText(String.valueOf(X)); due.setText(String.valueOf(Y)); pane.repaint(); } da quel che scrivi tu mi pare che non sia corretto usare il metodo paint, ma allora come si fa a disegnare?? ![]() |
![]() |
![]() |
![]() |
#4 | |||
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
![]() Quote:
Un JPanel, in quanto componente grafico, estende JComponent, dal quale eredita il metodo paintComponent(Graphics g) che è il metodo che viene invocato durante il ciclo di rendering dei componenti Swing. Quindi se tu definisci un tuo JPanel e vuoi renderizzare qualcosa sulla sua superficie devi fare l'ovveride di tale metodo, e definirne il corpo inserendo le tue operazioni di rendering (che tipicamente si fanno operando sul Graphics passato in ingresso). Ci penserà poi il framework Swing a invocare paintComponet() ogni volta che riterrà neccessario aggiornare la grafica. Tu puoi comunicare a Swing che ti interessa aggiornare la grafica del tal componente invocando il metodo repaint() sul componente specifico: sarà comunqe Swing a invocare dietro le quinte la paintComponent. Ti posto i javadoc del metodo paintComponent della classe JComponent: Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 02-07-2009 alle 14:38. |
|||
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
In pratica, dovresti sovvrascrivere il metodo paintComponet del JPanel sul quale disegni, con uno schema simile a questo:
Codice:
class MioPannelloDiRendering extends JPanel { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // comandi personalizzati di rendering sul Graphics... } } - Painting in Swing(in italiano, slide di una dispensa universitaria) - Painting in AWT e Swing(roba della Sun, in inglese, consigliata) - Lesson: performing custom painting(tutorial della Sun, preso dal vasto The Really Big Index, in inglese, consigliato)
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 02-07-2009 alle 14:49. |
![]() |
![]() |
![]() |
#6 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
ma quindi dovrei racchiudere pane in una classe, e specificare in essa il metodo paintComponent()?
del tipo class Pane extends JPanel{ JPanel pane=new JPanel(); proteced void paintComponent(Graphics g){ blablabla; } } e poi come lo aggiungo al pannello??? addComponent(new Pane()); ? |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
L'approccio che hai usato non è forse orotodosso ma, a parte due piccole incertezze, è tecnicamente corretto.
Le ragioni per cui non funziona sono due ma sono due piccole sviste. La prima è che devi aggiungere il tuo ascoltatore di eventi Disegno al pannello che metti nel frame: la semplice dichiarazione non basta. Il tuo metodo main diventa allora una cosa del genere: Codice:
public static void main(String [] args){ Pannello p = new Pannello(); p.addMouseListener(p.new Disegno()); JFrame x=new JFrame(); x.setSize(new Dimension(400,400)); x.setResizable(true); x.setContentPane(p); x.setDefaultCloseOperation(EXIT_ON_CLOSE); x.setVisible(true); } Togli repaint() dal metodo paint() e metti repaint() come ultima invocazione el metodo mouseClicked della classe Disegno. E tutto funzionerà. Per ragioni di concorrenza dovresti prendere quello che hai nel metodo main metterlo nel run() di un'istanza di Runnable e poi passare quel Runnable al metodo invokeLater di EventQueue ma questa è un'altra storia.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Postrsti usare una classe anonima per pane, così:
Codice:
JPanel pane; ... pane = new JPanel() { @Override protected void paintComponet(Graphics g); { super.paintComponet(g); // qui inserisci il tuo codice di rendering... } };
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
* edit
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 02-07-2009 alle 15:18. Motivo: ho "lisciato" |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Come non detto, ho mancato la lettura di una parentesi nel codice... chiedo venia
![]() @cory: scusa se ti ho fatto confusione.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
![]() |
![]() |
![]() |
#11 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
|
![]() |
![]() |
![]() |
#12 | |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
Quote:
![]() EDIT: magari non c'entra una tega, ma io ve lo dico lo stesso..uso Netbeans e la classe Prova è in un file e quella Pannello in un altro.. Ultima modifica di Cory : 02-07-2009 alle 15:29. |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Questo è il main:
Codice:
public static void main(String [] args){ Pannello p = new Pannello(); p.addMouseListener(p.new Disegno()); JFrame x=new JFrame(); x.setSize(new Dimension(400,400)); x.setResizable(true); x.setContentPane(p); x.setDefaultCloseOperation(EXIT_ON_CLOSE); x.setVisible(true); } Codice:
public void paint(Graphics g){ super.paint(g); green=generatore.nextInt(255)+1; red=generatore.nextInt(255)+1; blue=generatore.nextInt(255)+1; g.setColor(new Color(red,green,blue)); g.drawLine(X-5, Y+5, X+5, Y-5); g.drawLine(X-5, Y-5, X+5, Y+5); //repaint(); } Codice:
public void mouseClicked(MouseEvent e) { X=e.getX(); Y=e.getY(); uno.setText(String.valueOf(X)); due.setText(String.valueOf(Y)); repaint(); }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#14 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
ho apportato quella modifica al main ma non cambia nulla...
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Non è possibile.
Questo è il codice completo del programma. Codice:
package test; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; public class Prova extends JFrame{ public static void main(String [] args){ Pannello p = new Pannello(); p.addMouseListener(p.new Disegno()); JFrame x=new JFrame(); x.setSize(new Dimension(400,400)); x.setResizable(true); x.setContentPane(p); x.setDefaultCloseOperation(EXIT_ON_CLOSE); x.setVisible(true); } } class Pannello extends JPanel{ int red,green,blue,X,Y; Random generatore=new Random(System.currentTimeMillis()/27); JButton bottone; JLabel stato,x,y; JFormattedTextField uno,due; JPanel pane; public Pannello(){ this.setBackground(Color.LIGHT_GRAY); this.setLayout(new GridBagLayout()); GridBagConstraints c=new GridBagConstraints(); bottone=new JButton("Cambia stato"); bottone.addActionListener(new Abilita()); c.weightx=1; c.fill=GridBagConstraints.HORIZONTAL; c.weightx=1; c.weighty=0; c.gridx=0; c.gridy=0; c.gridwidth=1; add(bottone,c); stato=new JLabel(""); c.gridx=1; c.gridy=0; c.gridwidth=1; c.anchor=GridBagConstraints.CENTER; c.insets.left=5; add(stato,c); x=new JLabel("X="); c.gridx=2; c.gridy=0; c.anchor=GridBagConstraints.CENTER; c.gridwidth=1; c.weightx=1; c.weighty=0; c.insets.left=50; add(x,c); y=new JLabel("Y="); c.gridx=2; c.gridy=1; c.gridwidth=1; add(y,c); uno=new JFormattedTextField(); c.gridx=3; c.gridy=0; c.gridwidth=1; c.insets.left=5; add(uno,c); due=new JFormattedTextField(); c.gridx=3; c.gridy=1; c.gridwidth=1; add(due,c); pane=new JPanel(); pane.setBackground(Color.WHITE); pane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); pane.setOpaque(true); c.fill=GridBagConstraints.BOTH; c.gridx=0; c.gridy=2; c.gridwidth=4; c.gridheight=1; c.insets.top=5; c.weightx=1; c.weighty=1; add(pane,c); } class Abilita implements ActionListener{ boolean isActive=false; public void actionPerformed(ActionEvent e) { if(isActive==false){ stato.setText("ATTIVATO"); isActive=true; pane.addMouseListener(new Disegno()); } else if(isActive==true){ isActive=false; stato.setText("DISATTIVATO"); pane.removeMouseListener(pane.getMouseListeners()[0]); uno.setText(""); due.setText(""); } } } class Disegno implements MouseListener{ public void mouseClicked(MouseEvent e) { X=e.getX(); Y=e.getY(); uno.setText(String.valueOf(X)); due.setText(String.valueOf(Y)); repaint(); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} } public void paint(Graphics g){ super.paint(g); green=generatore.nextInt(255)+1; red=generatore.nextInt(255)+1; blue=generatore.nextInt(255)+1; g.setColor(new Color(red,green,blue)); g.drawLine(X-5, Y+5, X+5, Y-5); g.drawLine(X-5, Y-5, X+5, Y+5); //repaint(); } }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#16 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
eh oh..non va..
|
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se ridimensioni la finestra dopo aver fatto un po' di click compare la crocetta?
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#18 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
dopo aver cliccato a caso per un bel po', anche senza ridimensionare, m'è comparsa qualche X a fianco del bottone
![]() ![]() ![]() |
![]() |
![]() |
![]() |
#20 |
Member
Iscritto dal: Jan 2009
Città: Trento
Messaggi: 81
|
Codice:
package pacchetto; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; public class Prova extends JFrame{ public static void main(String [] args){ JFrame x=new JFrame(); x.setSize(new Dimension(400,400)); x.setResizable(true); x.setContentPane(new Pannello()); x.setDefaultCloseOperation(EXIT_ON_CLOSE); x.setVisible(true); } } public class Pannello extends JPanel{ int red,green,blue,X,Y; Random generatore=new Random(System.currentTimeMillis()/27); JButton bottone; JLabel stato,x,y; JFormattedTextField uno,due; JPanel pane; public Pannello(){ this.setBackground(Color.LIGHT_GRAY); this.setLayout(new GridBagLayout()); GridBagConstraints c=new GridBagConstraints(); bottone=new JButton("Cambia stato"); bottone.addActionListener(new Abilita()); c.weightx=1; c.fill=GridBagConstraints.HORIZONTAL; c.weightx=1; c.weighty=0; c.gridx=0; c.gridy=0; c.gridwidth=1; add(bottone,c); stato=new JLabel(""); c.gridx=1; c.gridy=0; c.gridwidth=1; c.anchor=GridBagConstraints.CENTER; c.insets.left=5; add(stato,c); x=new JLabel("X="); c.gridx=2; c.gridy=0; c.anchor=GridBagConstraints.CENTER; c.gridwidth=1; c.weightx=1; c.weighty=0; c.insets.left=50; add(x,c); y=new JLabel("Y="); c.gridx=2; c.gridy=1; c.gridwidth=1; add(y,c); uno=new JFormattedTextField(); c.gridx=3; c.gridy=0; c.gridwidth=1; c.insets.left=5; add(uno,c); due=new JFormattedTextField(); c.gridx=3; c.gridy=1; c.gridwidth=1; add(due,c); pane=new JPanel(); pane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); c.fill=GridBagConstraints.BOTH; c.gridx=0; c.gridy=2; c.gridwidth=4; c.gridheight=1; c.insets.top=5; c.insets.left=0; c.weightx=1; c.weighty=1; add(pane,c); } class Abilita implements ActionListener{ boolean isActive=false; public void actionPerformed(ActionEvent e) { if(isActive==false){ stato.setText("ATTIVATO"); isActive=true; pane.addMouseListener(new Disegno()); } else if(isActive==true){ isActive=false; stato.setText("DISATTIVATO"); pane.removeMouseListener(pane.getMouseListeners()[0]); uno.setText(""); due.setText(""); } } } class Disegno implements MouseListener{ public void mouseClicked(MouseEvent e) { X=e.getX(); Y=e.getY(); uno.setText(String.valueOf(X)); due.setText(String.valueOf(Y)); repaint(); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} } protected void paintComponent(Graphics g){ super.paintComponent(g); green=generatore.nextInt(256)+1; red=generatore.nextInt(256)+1; blue=generatore.nextInt(256)+1; g.setColor(new Color(red,green,blue)); g.drawLine(X-5, Y+5, X+5, Y-5); g.drawLine(X-5, Y-5, X+5, Y+5); } } Allora ho provato a sostituire il repaint(); del MouseListener con pane.repaint(); ma 1. nel JPanel pane non disegna nulla, pur inviando le giuste coordinate ai textfield 2. a furia di cliccare a caso e per un bel po' di tempo mi spunta qualche X sulla parte sopra il pannello, senza nessuna logica precisa.. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:32.