/************************************************************************** OmegaT - Computer Assisted Translation (CAT) tool with fuzzy matching, translation memory, keyword search, glossaries, and translation leveraging into updated projects. Copyright (C) 2009 Alex Buloichik Home page: http://www.omegat.org/ Support center: http://groups.yahoo.com/group/OmegaT/ This file is part of OmegaT. OmegaT 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. OmegaT 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 org.omegat.gui.common; import javax.swing.SwingUtilities; import org.omegat.core.data.SourceTextEntry; import org.omegat.util.Log; /** * Base class for search info about current entry in the separate thread. * * Implementation must check isEntryChanged method and exit if antry changed, * against create multimple threads when user travels by entries fast. * * @author Alex Buloichik (alex73mail@gmail.com) * * @param <T> * result type of found data */ public abstract class EntryInfoSearchThread<T> extends Thread { private final EntryInfoThreadPane<T> pane; /** * Entry which processed currently. * * If entry in pane was changed, it means user was moved to other entry, and * there is no sense to continue search. */ protected final SourceTextEntry currentlyProcessedEntry; /** * Constructor. * * @param pane * entry info pane * @param entry * current entry */ public EntryInfoSearchThread(final EntryInfoThreadPane<T> pane, final SourceTextEntry entry) { this.pane = pane; this.currentlyProcessedEntry = entry; } /** * Check if current entry was changed. If user moved to other entry, there * is no sence to continue search. * * @return true if current entry was changed */ protected boolean isEntryChanged() { return currentlyProcessedEntry != pane.currentlyProcessedEntry; } /** * Throws exception if entry changed for stop processing. */ protected void checkEntryChanged() throws EntryChangedException { if (isEntryChanged()) { throw new EntryChangedException(); } } @Override public void run() { if (isEntryChanged()) { return; } T result = null; Exception error = null; try { result = search(); } catch (EntryChangedException ex) { // entry changed - there is no sence to display results return; } catch (Exception ex) { error = ex; Log.log(ex); } if (isEntryChanged()) { return; } final T fresult = result; final Exception ferror = error; SwingUtilities.invokeLater(new Runnable() { public void run() { if (isEntryChanged()) { return; } if (ferror != null) { pane.setError(ferror); } else { pane.setFoundResult(currentlyProcessedEntry, fresult); } } }); } /** * Implementation-dependent method for search info. * * If entry changed, method can return null. * * @return result of search */ protected abstract T search() throws EntryChangedException, Exception; /** * Any search can generate this exception for stop searching if entry changed. All callers must catch it * and just skip. */ @SuppressWarnings("serial") public static class EntryChangedException extends RuntimeException { } }