How do I display images immediately in a java applet?
I created a simple memory game in Java applet There is a problem with the card At first appearance, the image requires some additional loading time How to solve it? I need to display the image immediately after the card is flipped
I display the load screen until the application is not in appstates Ready or appstates WAIT_ FOR_ Start status, but it does not help
Memo. CS – main class with image loading
public class Memo extends JApplet { //... public void init() { //... try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { createGUI(); }}); } catch(Exception e) { e.printStackTrace(); } } private void createGUI() { final Model model = new Model(...); final View view = new View(model); getContentPane().add(view,BorderLayout.CENTER); setBackground(backgroundColor); setPreferredSize(new Dimension(width,height)); model.setLoading(loadImages(loadingPath,format,1)); model.setCardsImages(loadImages(cardImagePath,13)); //... model.setAppState(AppStates.PROCESS); model.startNewGame(); view.repaint(); } private Image[] loadImages(String path1,String path2,int count) { Image[] imgs = new Image[count]; for(int i = 0; i < count; ++i) { imgs[i] = getImage(getCodeBase(),path1 + i + path2); } return imgs; } }
Model. CS – save image and application status, init board
public class Model { //... private AppStates appState; private Image[] cardsImages; public Model(...) { //... appState = AppStates.INIT; } public void startNewGame() { setAppState(AppStates.PROCESS); //... - init board - table with images' id setAppState(AppStates.WAIT_FOR_START); } public void setCardsImages(Image[] cardsImages) { this.cardsImages = cardsImages; } public Image getCardsImage(int v) { return cardsImages[v]; } public AppStates getAppState() { return appState; } public void setAppState(AppStates appState) { this.appState = appState; //... } //... }
View. CS – display panel
public class View extends JPanel { //... private Model model; public View(Model model) { this.model = model; //... } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; if(model != null) { switch (model.getAppState()) { //... case WAIT_FOR_START: case READY: //... drawBoard(g2d,model.getBoard(),model.getStates(),model.getFrontTypes()); break; } } repaint(); } private void drawBoard(Graphics2D g2d,int[][] board,int[][] states,int[][] frontTypes) { if(board != null && states != null && board.length > 0 && states.length > 0) { for(int x = 0; x < board.length; x++) { for(int y = 0; y < board[x].length; y++) { if(states[x][y] != Model.HIDE) { Image img = null; //... img = model.getCardsImage(board[x][y]); g2d.drawImage( img,model.getFirstCardX() + x * model.getCardDistance() + x * model.getCardWidth(),model.getFirstCardY() + y * model.getCardDistance() + y * model.getCardHeight(),model.getCardWidth(),model.getCardHeight(),null); //... } } } } } }
Solution
From JavaDocs
Use imageio instead read(URL). This method will "block" (it will stop at this line of code) until the image is read So when the application To use the image, it has been fully loaded
Another way to solve the problem (not the way you want) is to change
g2d.drawImage( img,null);
To
g2d.drawImage( img,this);
If the image is loaded asynchronously (for example, using applet. Getimage (URL)), the GUI notifies redrawing when more is available