📄 blockmetrics.java
字号:
/* * File: BlockMetrics.java * Project: MPI Linguistic Application * Date: 02 May 2007 * * Copyright (C) 2001-2007 Max Planck Institute for Psycholinguistics * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package mpi.eudico.client.annotator.interlinear;import mpi.eudico.server.corpora.clomimpl.abstr.AbstractAnnotation;import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;import mpi.eudico.util.TimeRelation;import mpi.util.TimeFormatter;import java.awt.Font;import java.awt.FontMetrics;import java.awt.Graphics;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.Enumeration;import java.util.HashMap;import java.util.Iterator;import java.util.Vector;import javax.swing.tree.DefaultMutableTreeNode;/** * The BlockMetrics class contains fields and methods for storing and * calculating blocks of annotations in an interlinear way. * * @author Han Sloetjes */public class BlockMetrics { private TranscriptionImpl transcription; /** * the interlinear object holding all parameters and a reference to the * Transcription object containing the data */ private final Interlinear interlinearizer; /** constant for a timecode tier label */ public final String TC_TIER_NAME = "TC"; /** constant for a timecode separator */ public final String TIME_SEP = " - "; /** constant for a space character */ public final char SPACE_CHAR = ' '; private HashMap tierHeights; private HashMap timecodeLabels; private ArrayList annotationBlocks; private ArrayList printBlocks; private ArrayList pageBreaks; private ArrayList visibleTiers; private ArrayList tierTemplate; private int leftMargin; private DefaultMutableTreeNode tierTree; /** * Creates a new BlockMetrics instance * * @param interlinearizer the Interlinear object holding parameters and * data */ public BlockMetrics(Interlinear interlinearizer) { this.interlinearizer = interlinearizer; transcription = interlinearizer.getTranscription(); tierHeights = new HashMap(); timecodeLabels = new HashMap(); annotationBlocks = new ArrayList(); tierTemplate = new ArrayList(); printBlocks = new ArrayList(); pageBreaks = new ArrayList(); tierTree = new DefaultMutableTreeNode(); //visibleTiers = interlinearizer.getVisibleTiers(); } /** * Reset the previously calculated blocks and pages etc. */ public void reset() { tierHeights.clear(); timecodeLabels.clear(); annotationBlocks.clear(); tierTemplate.clear(); visibleTiers = interlinearizer.getVisibleTiers(); tierTree = new DefaultMutableTreeNode(); } /** * Calculate annotation blocks, tier heights and margin using the specified * Graphics object for measurements. * * @param g the <code>Graphics</code> object for measurements */ public void calculateAnnotationBlocks(Graphics g) { //calculateTierHeightsAndMargin(g); AnnotationBlockCreator creator = new AnnotationBlockCreator(); tierTree = creator.createTierTree(interlinearizer.getTranscription(), visibleTiers); boolean pixelBased = (interlinearizer.getAlignmentUnit() == Interlinear.PIXELS); int maxTierLabelWidth = 0; Font font = null; FontMetrics fontMetrics = null; // create a list of relevant top level tiers, meaning all top level // tiers that is either in the visible tiers list itself or has a // child tier in the visible tiers list ArrayList relevantTopTiers = new ArrayList(); TierImpl tier; TierImpl rootTier; for (int i = 0; i < visibleTiers.size(); i++) { tier = (TierImpl) visibleTiers.get(i); String name = tier.getName(); tierTemplate.add(name); rootTier = tier.getRootTier(); if (!relevantTopTiers.contains(rootTier)) { relevantTopTiers.add(rootTier); if (interlinearizer.isTimeCodeShown()) { String tcLabel = TC_TIER_NAME; if (interlinearizer.getTimeCodeMultiplicity() == Interlinear.SINGLE_TIMECODE) { tcLabel = createTCLabel(""); } else { tcLabel = createTCLabel(rootTier.getName()); } if (tcLabel != null) { timecodeLabels.put(rootTier.getName(), tcLabel); if (pixelBased) { interlinearizer.setFontSize(tcLabel, Interlinear.TIMECODE_FONT_SIZE); interlinearizer.setFont(tcLabel, Interlinear.DEFAULTFONT); font = interlinearizer.getFont(tcLabel); fontMetrics = g.getFontMetrics(font); int tierHeight = fontMetrics.getHeight(); setTierHeight(tcLabel, tierHeight); int labWidth = fontMetrics.stringWidth(TC_TIER_NAME); if (labWidth > maxTierLabelWidth) { maxTierLabelWidth = labWidth; } } else { // the timecode label is 2 chars if (maxTierLabelWidth < 2) { maxTierLabelWidth = 2; } } } } } if (pixelBased) { font = interlinearizer.getFont(name); fontMetrics = g.getFontMetrics(font); int tierHeight = fontMetrics.getHeight(); setTierHeight(name, tierHeight); int labWidth = fontMetrics.stringWidth(name); if (labWidth > maxTierLabelWidth) { maxTierLabelWidth = labWidth; } } else { setTierHeight(name, Interlinear.DEFAULT_FONT_SIZE); int labWidth = name.length(); if (labWidth > maxTierLabelWidth) { maxTierLabelWidth = labWidth; } } } if (pixelBased) { setLeftMargin(maxTierLabelWidth + interlinearizer.getEmptySpace()); } else { setLeftMargin(maxTierLabelWidth + Interlinear.LABEL_VALUE_MARGIN); } // create blocks, using the annotations on relevant top level tiers // as the root tier = null; rootTier = null; DefaultMutableTreeNode node = null; InterlinearAnnotation prann = null; //AnnotationBlockCreator creator = new AnnotationBlockCreator(); long selBT = 0; long selET = Long.MAX_VALUE; if (interlinearizer.isSelectionOnly() && (interlinearizer.getSelection() != null) && (interlinearizer.getSelection()[0] != interlinearizer.getSelection()[1])) { selBT = interlinearizer.getSelection()[0]; selET = interlinearizer.getSelection()[1]; } for (int i = 0; i < relevantTopTiers.size(); i++) { rootTier = (TierImpl) relevantTopTiers.get(i); Vector annots = rootTier.getAnnotations(); Iterator anIter = annots.iterator(); AbstractAnnotation ann; while (anIter.hasNext()) { ann = (AbstractAnnotation) anIter.next(); // check selection if (TimeRelation.overlaps(ann, selBT, selET)) { if (interlinearizer.isEmptySlotsShown()) { node = creator.createBlockFillEmptyPositions(ann, visibleTiers); } else { node = creator.createBlockForAnnotation(ann, visibleTiers); } if (node != null) { // add a TimeCode annotation, if applicable if (interlinearizer.isTimeCodeShown()) { prann = (InterlinearAnnotation) node.getUserObject(); if (prann != null) { StringBuffer timeString = new StringBuffer(); if (interlinearizer.getTimeCodeType() == Interlinear.HHMMSSMS) { timeString.append(TimeFormatter.toString( prann.bt)); timeString.append(TIME_SEP); timeString.append(TimeFormatter.toString( prann.et)); } else if (interlinearizer.getTimeCodeType() == Interlinear.SSMS) { timeString.append(TimeFormatter.toSSMSString( prann.bt)); timeString.append(TIME_SEP); timeString.append(TimeFormatter.toSSMSString( prann.et)); } else { timeString.append(prann.bt); timeString.append(TIME_SEP); timeString.append(prann.et); } String tcLabel = (String) timecodeLabels.get(rootTier.getName()); InterlinearAnnotation tcAnn = new InterlinearAnnotation(timeString.toString(), tcLabel); node.add(new DefaultMutableTreeNode(tcAnn)); } } annotationBlocks.add(node); calculateBlock(node, g); // printoutNode(node); // sort the printannotations } } } } Collections.sort(annotationBlocks, new PrintAnnotationComparator()); /* System.out.println("\n" + "Sorted... "); for (int i = 0; i < annotationBlocks.size(); i++) { DefaultMutableTreeNode n = (DefaultMutableTreeNode) annotationBlocks.get(i); printoutNode(n); } */ } /** * When annotations have been put into an interlinear layout, they are * added to output or print blocks. Wrapping and empty line style etc are * taken into account. */ public void calculatePrintBlocks() { if (annotationBlocks.size() == 0) { return; } // add the timecode tier/tiers to the template, at the right position // after the last tier of a tiergroup, or at the end if only one timecode tier is used if (interlinearizer.isTimeCodeShown()) { if (interlinearizer.getTimeCodeMultiplicity() == Interlinear.SINGLE_TIMECODE) { // the timecode tier is the last one tierTemplate.add(createTCLabel("")); } else { ArrayList done = new ArrayList(); for (int i = tierTemplate.size() - 1; i >= 0; i--) { String name = (String) tierTemplate.get(i); TierImpl t = (TierImpl) transcription.getTierWithId(name); TierImpl root = t.getRootTier(); if (!done.contains(root.getName())) { // this is the last tier from it's tier group, // add the tc after this one tierTemplate.add(i + 1, timecodeLabels.get(root.getName())); done.add(root.getName()); } } } } // create PrintBlocks switch (interlinearizer.getBlockWrapStyle()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -