forge.screens.match.views.VLog.java Source code

Java tutorial

Introduction

Here is the source code for forge.screens.match.views.VLog.java

Source

/*
 * Forge: Play Magic: the Gathering.
 * Copyright (C) 2011  Nate
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package forge.screens.match.views;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

import com.google.common.collect.Lists;

import forge.game.GameLogEntry;
import forge.game.GameLogEntryType;
import forge.game.GameView;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc;
import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.screens.match.GameLogPanel;
import forge.screens.match.controllers.CLog;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinFont;

/**
 * Assembles Swing components of game log report.
 *
 * <br><br><i>(V at beginning of class name denotes a view class.)</i>
 */
public class VLog implements IVDoc<CLog> {

    // Keeps a record of log entries currently displayed so we can
    // easily identify new entries to be added to the game log.
    private final List<GameLogEntry> displayedLogEntries = Lists.newArrayList();

    // Used to determine when a new game has started.
    private GameView gameLogModel = null;

    // Fields used with interface IVDoc
    private DragCell parentCell;
    private final DragTab tab = new DragTab("Log");

    // Other fields
    private final GameLogPanel gameLog;
    private JPanel p = null;

    private final CLog controller;

    //========== Constructor
    public VLog(final CLog controller) {
        this.controller = controller;
        gameLog = new GameLogPanel();
    }

    //========== Overridden methods
    /* (non-Javadoc)
     * @see forge.gui.framework.IVDoc#populate()
     */
    @Override
    public void populate() {
        // (Panel uses observers to update, no permanent components here.)
    }

    /* (non-Javadoc)
     * @see forge.gui.framework.IVDoc#setParentCell()
     */
    @Override
    public void setParentCell(final DragCell cell0) {
        this.parentCell = cell0;
    }

    /* (non-Javadoc)
     * @see forge.gui.framework.IVDoc#getParentCell()
     */
    @Override
    public DragCell getParentCell() {
        return this.parentCell;
    }

    /* (non-Javadoc)
     * @see forge.gui.framework.IVDoc#getDocumentID()
     */
    @Override
    public EDocID getDocumentID() {
        return EDocID.REPORT_LOG;
    }

    /* (non-Javadoc)
     * @see forge.gui.framework.IVDoc#getTabLabel()
     */
    @Override
    public DragTab getTabLabel() {
        return tab;
    }

    /* (non-Javadoc)
     * @see forge.gui.framework.IVDoc#getLayoutControl()
     */
    @Override
    public CLog getLayoutControl() {
        return controller;
    }

    /**
     * Called whenever there are new log entries to be displayed.
     * <p>
     * This is an Observer update method.
     * <p>
     * @param model contains list of log entries.
     */
    public void updateConsole() {
        final GameView model = controller.getMatchUI().getGameView();
        if (isGameLogConsoleVisible() && model != null) {
            resetDisplayIfNewGame(model);
            displayNewGameLogEntries(model);
            // Important : refreshLayout() needs to be called every update.
            refreshLayout();
        }
    }

    private boolean isGameLogConsoleVisible() {
        return parentCell.getSelected().equals(this);
    }

    private void resetDisplayIfNewGame(final GameView model) {
        if (this.gameLogModel != model) {
            gameLog.reset();
            this.displayedLogEntries.clear();
            this.gameLogModel = model;
        }
    }

    /**
     * Refreshes game log console container.
     * <p>
     * For some reason this needs to be called every time the console
     * is updated with a new event, otherwise if the console is dragged
     * to a new tab the log display disappears.
     * <p>
     * Since it is simply swapping in/out a reference to an existing object
     * I don't think it is a major concern but should probably try to
     * come up with more elegant solution some time.
     */
    private void refreshLayout() {
        //TODO: Find a way to avoid calling refreshLayout() on every update.
        p = parentCell.getBody();
        p.remove(gameLog);
        p.setLayout(new MigLayout("insets 1"));
        p.add(gameLog, "w 10:100%, h 100%");
    }

    private void displayNewGameLogEntries(final GameView model) {
        final List<GameLogEntry> newLogEntries = Lists.reverse(getNewGameLogEntries(model));
        if (newLogEntries.size() > 0) {
            addNewLogEntriesToJPanel(newLogEntries);
        }
    }

    private List<GameLogEntry> getNewGameLogEntries(final GameView model) {
        final String logEntryType = FModel.getPreferences().getPref(FPref.DEV_LOG_ENTRY_TYPE);
        final GameLogEntryType logVerbosityFilter = GameLogEntryType.valueOf(logEntryType);
        if (model != null && model.getGameLog() != null) {
            final List<GameLogEntry> logEntries = model.getGameLog().getLogEntries(logVerbosityFilter);
            // Set subtraction - remove all log entries from new list which are already displayed.
            logEntries.removeAll(this.displayedLogEntries);
            return logEntries;
        }
        return new ArrayList<GameLogEntry>();
    }

    private void addNewLogEntriesToJPanel(final List<GameLogEntry> newLogEntries) {
        for (final GameLogEntry logEntry : newLogEntries) {
            gameLog.setTextFont(getJTextAreaFont(logEntry.type));
            gameLog.addLogEntry(logEntry.message);
            this.displayedLogEntries.add(logEntry);
        }
    }

    private static SkinFont getJTextAreaFont(final GameLogEntryType logEntryType) {
        final boolean isNewTurn = (logEntryType == GameLogEntryType.TURN);
        return (isNewTurn ? FSkin.getBoldFont() : FSkin.getFont());
    }
}