org.zeromeaner.gui.reskin.StandaloneFrame.java Source code

Java tutorial

Introduction

Here is the source code for org.zeromeaner.gui.reskin.StandaloneFrame.java

Source

package org.zeromeaner.gui.reskin;

import static org.zeromeaner.util.Options.player;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileSystemView;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.zeromeaner.game.component.ReplayData;
import org.zeromeaner.game.component.ReplayData2;
import org.zeromeaner.game.component.RuleOptions;
import org.zeromeaner.game.play.GameManager;
import org.zeromeaner.game.randomizer.Randomizer;
import org.zeromeaner.game.randomizer.ReplayDataRandomizer;
import org.zeromeaner.game.subsystem.ai.AbstractAI;
import org.zeromeaner.game.subsystem.mode.AbstractNetMode;
import org.zeromeaner.game.subsystem.mode.GameMode;
import org.zeromeaner.game.subsystem.mode.MarathonMode;
import org.zeromeaner.game.subsystem.wallkick.Wallkick;
import org.zeromeaner.gui.knet.KNetPanel;
import org.zeromeaner.gui.knet.KNetPanelAdapter;
import org.zeromeaner.gui.knet.KNetPanelEvent;
import org.zeromeaner.knet.obj.KNetChannelInfo;
import org.zeromeaner.util.CustomProperties;
import org.zeromeaner.util.GeneralUtil;
import org.zeromeaner.util.Localization;
import org.zeromeaner.util.ModeList;
import org.zeromeaner.util.Options;
import org.zeromeaner.util.Session;
import org.zeromeaner.util.URLs;
import org.zeromeaner.util.Options.AIOptions;
import org.zeromeaner.util.Options.TuningOptions;
import org.zeromeaner.util.Version;
import org.zeromeaner.util.io.DavFileSystemView;
import org.zeromeaner.util.io.FileSystemViews;
import org.zeromeaner.util.ResourceInputStream;
import org.zeromeaner.util.RuleList;

public class StandaloneFrame extends JFrame {
    private static final Logger log = Logger.getLogger(StandaloneFrame.class);
    private static final Localization lz = new Localization();

    private static Icon icon(String name) {
        URL url = StandaloneFrame.class.getResource(name + ".png");
        return url == null ? null : new ImageIcon(url);
    }

    public static final String CARD_INTRO = "toolbar.intro";
    public static final String CARD_PLAY = "toolbar.play";
    public static final String CARD_PLAY_END = "toolbar.play.end";
    public static final String CARD_MODESELECT = "toolbar.modeselect";
    public static final String CARD_NETPLAY = "toolbar.netplay";
    public static final String CARD_NETPLAY_END = "toolbar.netplay.end";
    public static final String CARD_OPEN = "toolbar.open";
    public static final String CARD_OPEN_ONLINE = "toolbar.open_online";
    public static final String CARD_RULE_1P = "toolbar.rule_1p";
    public static final String CARD_KEYS_1P = "toolbar.keys_1p";
    public static final String CARD_TUNING_1P = "toolbar.tuning_1p";
    public static final String CARD_AI_1P = "toolbar.ai_1p";
    public static final String CARD_RULE_2P = "toolbar.rule_2p";
    public static final String CARD_KEYS_2P = "toolbar.keys_2p";
    public static final String CARD_TUNING_2P = "toolbar.tuning_2p";
    public static final String CARD_AI_2P = "toolbar.ai_2p";
    public static final String CARD_GENERAL = "toolbar.general";
    public static final String CARD_FEEDBACK = "toolbar.feedback";
    public static final String CARD_CLOSE = "toolbar.close";

    public JToolBar toolbar;
    private CardLayout contentCards;
    private String currentCard;
    private String nextCard;
    private JPanel content;

    private StandaloneLicensePanel introPanel;

    private JPanel playCard;
    private JPanel netplayCard;

    private JToggleButton playButton;
    private JToggleButton netplayButton;

    KNetPanel netLobby;
    volatile GameManager gameManager;
    private StandaloneGamePanel gamePanel;

    public StandaloneFrame() {
        setTitle("zeromeaner " + Version.getBuildVersion());
        if (!Version.getBuildRevision().isEmpty())
            setTitle(getTitle() + " rev " + Version.getBuildRevision());

        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        setLayout(new BorderLayout());
        add(toolbar = createToolbar(), BorderLayout.EAST);
        add(content = new JPanel(contentCards = new CardLayout()), BorderLayout.CENTER);

        netLobby = new KNetPanel(Session.getUser(), false);
        netLobby.setPreferredSize(new Dimension(800, 250));
        netLobby.addKNetPanelListener(new KNetPanelAdapter() {
            @Override
            public void knetPanelShutdown(KNetPanelEvent e) {
                content.remove(netLobby);
                content.revalidate();
                content.repaint();
            }

            @Override
            public void knetPanelJoined(KNetPanelEvent e) {
                if (e.getChannel().getId() != KNetChannelInfo.LOBBY_CHANNEL_ID
                        && e.getSource().getClient().getCurrentChannel() != null) {
                    startNewGame(e.getChannel().getRule().resourceName, null, e.getChannel().getMode(), e);
                    gamePanel.displayWindow();
                }
            }

            @Override
            public void knetPanelParted(KNetPanelEvent e) {
                gamePanel.shutdown();
                try {
                    gamePanel.shutdownWait();
                } catch (InterruptedException ex) {
                }
            }
        });

        gamePanel = new StandaloneGamePanel(this);

        createCards();

        setMinimumSize(new Dimension(900, 550));
    }

    private static void add(JToolBar toolbar, ButtonGroup g, AbstractButton b) {
        b.setFocusable(false);
        b.setBorder(null);
        b.setHorizontalAlignment(SwingConstants.LEFT);
        toolbar.add(b);
        if (g != null)
            g.add(b);
    }

    private void createCards() {
        introPanel = new StandaloneLicensePanel();
        content.add(introPanel, CARD_INTRO);

        playCard = new JPanel(new BorderLayout());
        content.add(playCard, CARD_PLAY);

        JPanel confirm = new JPanel(new GridBagLayout());
        JOptionPane option = new JOptionPane("A game is in open.  End this game?", JOptionPane.QUESTION_MESSAGE,
                JOptionPane.YES_NO_OPTION);
        option.addPropertyChangeListener(JOptionPane.VALUE_PROPERTY, new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (!CARD_PLAY_END.equals(currentCard))
                    return;
                if (evt.getNewValue().equals(JOptionPane.YES_OPTION)) {
                    gamePanel.shutdown();
                    try {
                        gamePanel.shutdownWait();
                    } catch (InterruptedException ie) {
                    }
                    contentCards.show(content, nextCard);
                    currentCard = nextCard;
                }
                if (evt.getNewValue().equals(JOptionPane.NO_OPTION)) {
                    contentCards.show(content, CARD_PLAY);
                    currentCard = CARD_PLAY;
                    playButton.setSelected(true);
                }

                ((JOptionPane) evt.getSource()).setValue(-1);
            }
        });
        GridBagConstraints cx = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER,
                GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0);
        confirm.add(option, cx);
        content.add(confirm, CARD_PLAY_END);

        content.add(new StandaloneModeselectPanel(), CARD_MODESELECT);

        netplayCard = new JPanel(new BorderLayout());
        netplayCard.add(netLobby, BorderLayout.SOUTH);
        content.add(netplayCard, CARD_NETPLAY);

        confirm = new JPanel(new GridBagLayout());
        option = new JOptionPane("A netplay game is open.  End this game and disconnect?",
                JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
        option.addPropertyChangeListener(JOptionPane.VALUE_PROPERTY, new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (!CARD_NETPLAY_END.equals(currentCard))
                    return;
                if (evt.getNewValue().equals(JOptionPane.YES_OPTION)) {
                    gamePanel.shutdown();
                    try {
                        gamePanel.shutdownWait();
                    } catch (InterruptedException ie) {
                    }
                    netLobby.disconnect();
                    contentCards.show(content, nextCard);
                    currentCard = nextCard;
                }
                if (evt.getNewValue().equals(JOptionPane.NO_OPTION)) {
                    contentCards.show(content, CARD_NETPLAY);
                    currentCard = CARD_NETPLAY;
                    netplayButton.setSelected(true);
                }

                ((JOptionPane) evt.getSource()).setValue(-1);
            }
        });
        cx = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.NONE,
                new Insets(10, 10, 10, 10), 0, 0);
        confirm.add(option, cx);
        content.add(confirm, CARD_NETPLAY_END);

        StandaloneKeyConfig kc = new StandaloneKeyConfig(this);
        kc.load(0);
        content.add(kc, CARD_KEYS_1P);
        kc = new StandaloneKeyConfig(this);
        kc.load(1);
        content.add(kc, CARD_KEYS_2P);

        StandaloneGameTuningPanel gt = new StandaloneGameTuningPanel();
        gt.load(0);
        content.add(gt, CARD_TUNING_1P);
        gt = new StandaloneGameTuningPanel();
        gt.load(1);
        content.add(gt, CARD_TUNING_2P);

        StandaloneAISelectPanel ai = new StandaloneAISelectPanel();
        ai.load(0);
        content.add(ai, CARD_AI_1P);
        ai = new StandaloneAISelectPanel();
        ai.load(1);
        content.add(ai, CARD_AI_2P);

        StandaloneGeneralConfigPanel gc = new StandaloneGeneralConfigPanel();
        gc.load();
        content.add(gc, CARD_GENERAL);

        final JFileChooser fc = FileSystemViews.get().fileChooser("replay/");

        fc.setFileFilter(new FileFilter() {
            @Override
            public String getDescription() {
                return "Zeromeaner Replay Files";
            }

            @Override
            public boolean accept(File f) {
                return f.isDirectory() || f.getName().endsWith(".zrep");
            }
        });

        fc.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!e.getActionCommand().equals(JFileChooser.APPROVE_SELECTION))
                    return;
                JFileChooser fc = (JFileChooser) e.getSource();
                String path = fc.getSelectedFile().getPath();
                if (!path.contains("replay/"))
                    path = "replay/" + path;
                startReplayGame(path);
            }
        });
        fc.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentShown(ComponentEvent e) {
                fc.rescanCurrentDirectory();
            }
        });
        content.add(fc, CARD_OPEN);

        content.add(new StandaloneFeedbackPanel(), CARD_FEEDBACK);
    }

    private void playCardSelected() {
        playCard.add(gamePanel, BorderLayout.CENTER);
        //      playCard.add(musicPanel, BorderLayout.WEST);
        gamePanel.shutdown();
        try {
            gamePanel.shutdownWait();
        } catch (InterruptedException ie) {
        }
        gamePanel.modeToEnter.offer("");
        startNewGame();
        gamePanel.displayWindow();
    }

    private void netplayCardSelected() {
        netplayCard.add(gamePanel, BorderLayout.CENTER);
        //      netplayCard.add(musicPanel, BorderLayout.WEST);
        gamePanel.shutdown();
        try {
            gamePanel.shutdownWait();
        } catch (InterruptedException ie) {
        }
        //      enterNewMode(null);
    }

    private JToolBar createToolbar() {
        JToolBar t = new JToolBar(JToolBar.VERTICAL);
        t.setFloatable(false);
        t.setLayout(new GridLayout(0, 1));

        ButtonGroup g = new ButtonGroup();

        AbstractButton b;

        b = playButton = new JToggleButton(new ToolbarAction("toolbar.play") {
            @Override
            public void actionPerformed(ActionEvent e) {
                super.actionPerformed(e);
                if (CARD_PLAY.equals(currentCard))
                    playCardSelected();
            }
        });
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.modeselect"));
        add(t, g, b);

        b = netplayButton = new JToggleButton(new ToolbarAction("toolbar.netplay") {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (CARD_NETPLAY.equals(currentCard))
                    return;
                super.actionPerformed(e);
                netplayCardSelected();
            }
        });
        add(t, g, b);

        /*
        b = new JToggleButton(new ToolbarAction("toolbar.rule_1p"));
        add(t, g, b);
        */

        b = new JToggleButton(new ToolbarAction("toolbar.keys_1p"));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.tuning_1p"));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.ai_1p"));
        add(t, g, b);

        /*
        b = new JToggleButton(new ToolbarAction("toolbar.rule_2p"));
        add(t, g, b);
         */

        b = new JToggleButton(new ToolbarAction("toolbar.keys_2p"));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.tuning_2p"));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.ai_2p"));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.general"));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.open"));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction(CARD_FEEDBACK));
        add(t, g, b);

        b = new JToggleButton(new ToolbarAction("toolbar.close") {
            @Override
            public void actionPerformed(ActionEvent e) {
                StandaloneMain.saveConfig();
                System.exit(0);
            }
        });
        add(t, g, b);

        return t;
    }

    private class ToolbarAction extends AbstractAction {
        private String cardName;

        public ToolbarAction(String name) {
            super(lz.s(name), icon(name));
            this.cardName = name;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (CARD_PLAY.equals(currentCard)) {
                if (gamePanel.isInGame[0]) {
                    nextCard = cardName;
                    contentCards.show(content, CARD_PLAY_END);
                    currentCard = CARD_PLAY_END;
                    return;
                } else {
                    gamePanel.shutdown();
                    try {
                        gamePanel.shutdownWait();
                    } catch (InterruptedException e1) {
                    }
                }
            }
            if (CARD_NETPLAY.equals(currentCard) && netLobby.getClient() != null) {
                nextCard = cardName;
                contentCards.show(content, CARD_NETPLAY_END);
                currentCard = CARD_NETPLAY_END;
                return;
            }
            contentCards.show(content, cardName);
            currentCard = cardName;
        }
    }

    /**
     * Start a new game (Rule will be user-selected one))
     */
    public void startNewGame() {
        startNewGame(null, null, null, null);
    }

    /**
     * Start a new game
     * @param strRulePath Rule file path (null if you want to use user-selected one)
     */
    public void startNewGame(String strRulePath, String replayPath, String modeName, KNetPanelEvent e) {
        //      if(gameManager == null) {
        StandaloneRenderer rendererSwing = new StandaloneRenderer(this);
        gameManager = new GameManager(rendererSwing);
        //      }

        boolean isNetPlay = (modeName != null);

        // Mode
        if (modeName == null)
            modeName = Options.general().MODE_NAME.value();

        if (replayPath != null) {
            log.info("Loading Replay:" + replayPath);
            CustomProperties prop = new CustomProperties();

            try {
                InputStream stream = new ResourceInputStream(replayPath);
                if (replayPath.endsWith(".zrep"))
                    stream = new GZIPInputStream(stream);
                prop.load(stream);
                stream.close();
            } catch (IOException ex) {
                log.error("Couldn't load replay file from " + replayPath, ex);
                return;
            }

            gameManager.replayMode = true;
            gameManager.replayProp = prop;

            // Mode
            modeName = prop.getProperty("name.mode", "");
        }

        GameMode modeObj = StandaloneMain.modeManager.get(modeName);
        if (modeObj == null) {
            log.error("Couldn't find mode:" + modeName);
            gameManager.mode = new MarathonMode();
        } else {
            gameManager.mode = modeObj;
            gamePanel.modeToEnter.offer(modeName);
        }

        if (e != null) {
            ((AbstractNetMode) modeObj).setKnetPanel(e.getSource());
        }

        gameManager.init();

        if (e != null) {
            ((AbstractNetMode) modeObj).netplayInit(e.getSource());
            ((AbstractNetMode) modeObj).netOnJoin(e.getClient(), e.getChannel());
        }

        // Initialization for each player
        for (int i = 0; i < gameManager.getPlayers(); i++) {
            // Tuning settings
            TuningOptions tune = player(i).tuning;
            gameManager.engine[i].owRotateButtonDefaultRight = tune.ROTATE_BUTTON_DEFAULT_RIGHT.value();
            gameManager.engine[i].owSkin = tune.SKIN.value();
            gameManager.engine[i].owMinDAS = tune.MIN_DAS.value();
            gameManager.engine[i].owMaxDAS = tune.MAX_DAS.value();
            gameManager.engine[i].owDasDelay = tune.DAS_DELAY.value();
            gameManager.engine[i].owReverseUpDown = tune.REVERSE_UP_DOWN.value();
            gameManager.engine[i].owMoveDiagonal = tune.MOVE_DIAGONAL.value();
            gameManager.engine[i].owBlockOutlineType = tune.BLOCK_OUTLINE_TYPE.value();
            gameManager.engine[i].owBlockShowOutlineOnly = tune.BLOCK_SHOW_OUTLINE_ONLY.value();

            // Rule
            RuleOptions ruleopt = null;
            String rulename = strRulePath;
            if (gameManager.replayMode) {
                rulename = gameManager.replayProp.getProperty("name.rule");
                ruleopt = RuleList.getRules().getNamed(rulename);
                ruleopt.readProperty(gameManager.replayProp, i);
            }
            if (rulename == null) {
                //            rulename = StandaloneMain.propConfig.getProperty(i + ".rule", "");
                rulename = player(i).RULE_NAME.value();
                if (gameManager.mode.getGameStyle() > 0) {
                    //               rulename = StandaloneMain.propConfig.getProperty(i + ".rule." + gameManager.mode.getGameStyle(), "");
                    rulename = player(i).RULE_NAME_FOR_STYLE(gameManager.mode.getGameStyle()).value();
                }
            }
            if ((rulename != null) && (rulename.length() > 0)) {
                if (ruleopt == null) {
                    log.debug("Load rule options from " + rulename);
                    ruleopt = GeneralUtil.loadRule(rulename);
                }
            } else {
                log.debug("Load rule options from setting file");
                ruleopt = new RuleOptions();
                ruleopt.readProperty(Options.GLOBAL_PROPERTIES, i);
            }
            gameManager.engine[i].ruleopt = ruleopt;

            // NEXTOrder generation algorithm
            if ((ruleopt.strRandomizer != null) && (ruleopt.strRandomizer.length() > 0)) {
                Randomizer randomizerObject;
                if (!gameManager.replayMode)
                    randomizerObject = GeneralUtil.loadRandomizer(ruleopt.strRandomizer, gameManager.engine[i]);
                else {
                    ReplayData rd = new ReplayData2();
                    rd.readProperty(gameManager.replayProp, i);
                    randomizerObject = new ReplayDataRandomizer(rd);
                    randomizerObject.setEngine(gameManager.engine[i]);
                }
                gameManager.engine[i].randomizer = randomizerObject;
            }

            // Wallkick
            if ((ruleopt.strWallkick != null) && (ruleopt.strWallkick.length() > 0)) {
                Wallkick wallkickObject = GeneralUtil.loadWallkick(ruleopt.strWallkick);
                gameManager.engine[i].wallkick = wallkickObject;
            }

            // AI
            if (!gameManager.replayMode && !isNetPlay) {
                AIOptions ai = Options.player(i).ai;
                String aiName = ai.NAME.value();
                if (aiName.length() > 0 && replayPath == null) {
                    AbstractAI aiObj = GeneralUtil.loadAIPlayer(aiName);
                    gameManager.engine[i].ai = aiObj;
                    gameManager.engine[i].aiMoveDelay = ai.MOVE_DELAY.value();
                    gameManager.engine[i].aiThinkDelay = ai.THINK_DELAY.value();
                    gameManager.engine[i].aiUseThread = ai.USE_THREAD.value();
                    gameManager.engine[i].aiShowHint = ai.SHOW_HINT.value();
                    gameManager.engine[i].aiPrethink = ai.PRETHINK.value();
                    gameManager.engine[i].aiShowState = ai.SHOW_STATE.value();
                }
                gameManager.showInput = Options.standalone().SHOW_INPUT.value();
            }

            // Called at initialization
            gameManager.engine[i].init();
        }

        gamePanel.isNetPlay = isNetPlay;
    }

    public void startReplayGame(String filename) {
        contentCards.show(content, currentCard = CARD_PLAY);
        playCard.add(gamePanel, BorderLayout.CENTER);
        gamePanel.shutdown();
        try {
            gamePanel.shutdownWait();
        } catch (InterruptedException ie) {
        }
        startNewGame(null, filename, null, null);
        gamePanel.displayWindow();
    }

}