如何在Java Applet中立即显示图像?

reb*_*mer 3 java applet swing image

我在Java Applet中创建了一个简单的内存游戏.卡有问题.在第一次出现时,图像需要一些额外的加载时间.如何解决?我需要在卡片翻转后立即显示图像.

我显示加载屏幕,直到应用程序不在AppStates.READYAppStates.WAIT_FOR_START状态,但它没有帮助.

Memo.cs - 带图像加载的主类

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, format, 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Model.cs - 保存图像和应用程序状态,init板

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;
        //...
    }

    //...
}
Run Code Online (Sandbox Code Playgroud)

View.cs - 显示板

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);

                        //...
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*son 6

来自JavaDocs ..

public Image getImage(URL url)

..

无论图像是否存在,此方法始终立即返回.当此applet尝试在屏幕上绘制图像时,将加载数据.

ImageIO.read(URL)改用.此方法将"阻止"(它将停在该代码行),直到读取图像.所以当应用程序.去使用图像,它已经完全加载.

解决问题的另一种方法(不是你想要的方式)是改变..

g2d.drawImage(
    img,
    model.getFirstCardX() + x * model.getCardDistance() + x * model.getCardWidth(), 
    model.getFirstCardY() + y * model.getCardDistance() + y * model.getCardHeight(), 
    model.getCardWidth(), 
    model.getCardHeight(),
    null);
Run Code Online (Sandbox Code Playgroud)

至..

g2d.drawImage(
    img,
    model.getFirstCardX() + x * model.getCardDistance() + x * model.getCardWidth(), 
    model.getFirstCardY() + y * model.getCardDistance() + y * model.getCardHeight(), 
    model.getCardWidth(), 
    model.getCardHeight(),
    this);
Run Code Online (Sandbox Code Playgroud)

如果图像是异步加载的(例如使用Applet.getImage(URL)),则会在更多可用时通知GUI重新绘制.