Trong hai ngày qua, tôi đã cố gắng hiểu cách Java xử lý đồ họa, nhưng đã thất bại thảm hại ở mức đó. Vấn đề chính của tôi là hiểu chính xác cách thức và khi nào thì paint() (hoặc mới hơn paintComponent()) là/nên được gọi.Tại sao sơn()/paintComponent() không bao giờ được gọi?
Trong mã sau tôi đã thực hiện để xem khi nào mọi thứ được tạo, paintComponent() không bao giờ được gọi, trừ khi tôi tự thêm cuộc gọi vào đó hoặc gọi tới JFrame.paintAll()/JFrame.paintComponents().
Tôi đổi tên phương thức paint() thành paintComponent() với hy vọng rằng sẽ khắc phục được sự cố của tôi về nó chưa bao giờ được gọi (ngay cả ở repaint()), nhưng không may mắn.
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;
}
}
Cảm ơn, sẽ thử điều đó. Nhưng tôi có thực sự sử dụng setVisible ở cuối để nó hoạt động không? Điểm có gọi nó sớm là để xem làm thế nào tôi nên xử lý thêm các yếu tố đồ họa bổ sung tại một thời gian sau đó. Nhưng toàn bộ điều Runnable là mới đối với tôi; Tôi chưa thấy điều đó trong bất kỳ hướng dẫn nào tôi đã thấy (như this one). – oligofren
Sử dụng ['java.awt.EventQueue.']' invokeLater' làm cho nó hoạt động đối với tôi. –
(Mặc dù đó có thể là chỉ bao gồm một lỗi. Bạn nên 'revalidate' sau khi' add' như được mô tả trong tài liệu API cho 'add'.) –