Przez ostatnie dwa dni starałem się, aby zrozumieć jak Java obsługuje grafiki, ale nie udało się marnie właśnie. Moim głównym problemem jest zrozumienie, jak i kiedy należy wywołać paint() (lub nowszą funkcję paintComponent()).Dlaczego farba()/paintComponent() nigdy nie jest wywoływana?
W poniższym kodzie zrobiłem, aby zobaczyć, kiedy rzeczy są tworzone, paintComponent() nigdy nie jest wywoływany, chyba że ręcznie dodaję do niego wywołanie lub wywołania JFrame.paintAll()/JFrame.paintComponents().
Zmieniono nazwę metody paint() na paintComponent() w nadziei, że naprawię mój problem z tym, że nigdy nie zostanie wywołany (nawet przy odświeżaniu()), ale bez powodzenia.
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;
}
}
Dzięki, spróbuję. Ale czy naprawdę muszę używać setVisible na końcu, aby działał? Punktem wczesnego wywołania było zobaczenie, jak powinienem obsłużyć dodanie dodatkowych elementów graficznych w późniejszym czasie. Ale cała Runiczna sprawa była dla mnie nowa; Nie widziałem tego w żadnym z tutoriali, które widziałem (np. this one). – oligofren
Używanie ['java.awt.EventQueue.'] 'InvokeLater' sprawia, że działa on dla mnie. –
(Chociaż to prawdopodobnie tylko pokrywa błąd. Powinieneś 'revalidate' po' add', jak opisano w dokumentacji API dla 'add'.) –