Durante los últimos dos días he intentado comprender cómo maneja Java los gráficos, pero han fallado miserablemente en eso. Mi principal problema es entender exactamente cómo y cuándo se llama/debería llamarse paint() (o el paintComponent() más nuevo).¿Por qué paint()/paintComponent() nunca se llama?
En el siguiente código que hice para ver cuándo se crean las cosas, paintComponent() nunca se llama, a menos que agregue manualmente una llamada a él o llame a JFrame.paintAll()/JFrame.paintComponents().
Cambié el nombre del método paint() a paintComponent() con la esperanza de que solucionaría mi problema de que nunca se llamara (incluso en repaint()), pero no tuve suerte.
package jpanelpaint;
import java.awt.*;
import javax.imageio.*;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
public class ImageLoadTest extends JComponent {
ArrayList<Image> list;
public ImageLoadTest() {
list = new ArrayList<Image>();
try { //create the images (a deck of 4 cards)
for(String name : createImageFileNames(4)){
System.err.println(name);
list.add(ImageIO.read(new File(name)));
}
} catch (IOException e) { }
}
protected void paintComponent(Graphics g) {
int yOffset=0;
System.err.println("ImageLoadTest.paintComponent()");
for(Image img : list) {
g.drawImage(img, 0, yOffset, null);
yOffset+=20;
}
}
public static void main(String args[]) throws InterruptedException {
JFrame frame = new JFrame("Empty JFrame");
frame.setSize(new Dimension(1000, 500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Thread.sleep(1000);
frame.setTitle("Loading images");
ImageLoadTest ilt = new ImageLoadTest();
frame.add(ilt);
//update the screen
//DOESN'T WORK. only works if I call frame.paintAll(frame.getGraphics())
ilt.repaint();
frame.repaint();
Thread.sleep(1000);
frame.setTitle("Setting background");
ilt.setBackground(Color.BLACK);
//update the screen - DOESN'T WORK even if I call paintAll ..
ilt.repaint();
frame.repaint();
//have to call one of these to get anything to display
// ilt.paintComponent(frame.getGraphics()); //works
frame.paintComponents(frame.getGraphics()); //works
}
//PRIVATE HELPER FUNCTIONS
private String[] createImageFileNames(int count){
String[] fileNames = new String[count];
for(int i=0; i < count; i++)
fileNames[i] = "Cards" + File.separator + (i+1) + ".bmp";
return fileNames;
}
}
Gracias, lo intentaré. Pero, ¿debo usar setVisible al final para que funcione? El punto de llamarlo temprano era ver cómo debería manejar la adición de elementos gráficos adicionales en un momento posterior. Pero todo lo de Runnable era nuevo para mí; No he visto eso en ninguno de los tutoriales que he visto (como this one). – oligofren
El uso de ['java.awt.EventQueue']' invokeLater' lo hace funcionar para mí. –
(Aunque eso probablemente solo cubra un error. Deberías 'revalidar' después de' agregar' como se describe en los documentos de la API para 'agregar'.) –