📄 lgprotegeeditor.java
字号:
/*
* Copyright: (c) 2004 Mayo Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must include
* the following acknowledgment:
* "This product includes software developed by Mayo Clinic Division of Biomedical
* Informatics Research (http://informatics.mayo.edu/)."
* Alternately, this acknowledgment may appear in the software itself, if and wherever
* such third-party acknowledgments normally appear.
*
* 4. The names "Mayo", "Mayo Clinic", "Mayo Foundation", "LexGrid", or "LexGrid Editor"
* must not be used to endorse or promote products derived from this software without
* prior written permission. For written permission, please contact the author
* or copyright holder.
*
* 5. Products derived from this software may not be called "LexGrid Editor", nor may
* "LexGrid" or "Mayo" appear in their name, without prior written permission of the
* author or copyright holder.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MAYO CLINIC OR OTHER
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lexgrid.ui.extension.protege;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.JComponent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
import edu.stanford.smi.protege.model.Project;
import edu.stanford.smi.protege.ui.ProjectView;
/**
* Provides an Eclipse compatible wrapper over the standard Protege application.
*
* @author <A HREF="mailto:johnson.thomas@mayo.edu">Thomas M Johnson</A>
*/
public class LgProtegeEditor extends EditorPart {
/**
* Shows a message and activity indicator in the SWT label space.
*/
class AnimatedMsgThread extends Thread {
final char[] rotoChars = new char[] {'\\', '|', '/', '-'};
String label = null;
boolean done = false;
public AnimatedMsgThread(String label) {
super("AnimatedMsgThread");
setDaemon(true);
this.label = label;
}
public void run() {
int r = 0;
// Give it a second (literally) to see if the operation completes
// before starting the animation ...
try {
sleep(1000);
} catch (InterruptedException e) {
}
// Start simple animation ... update every .5 seconds
try {
while (!done) {
final char ch = rotoChars[r = (++r == rotoChars.length) ? 0 : r];
if (display != null)
display.asyncExec(new Runnable() {
public void run() {
if (!done)
showLabel(new StringBuffer(128)
.append(" ").append(ch).append('\t')
.append(label).toString());
}
});
sleep(500);
}
} catch (InterruptedException e) {
}
}
public void end() {
done = true;
}
}
/**
* Provides access to the AWT frame to display swing-based controls.
*/
class SwingFrameAccess extends Frame implements ActionListener {
private Project p = null;
private ProjectView pv = null;
private Frame f = null;
private boolean disposed = false;
public SwingFrameAccess() {
display.syncExec(new Runnable() {
public void run() {
f = SWT_AWT.new_Frame(getSWTSwingContainer());
}
});
}
public void actionPerformed(ActionEvent e) {
}
public void dispose() {
if (!disposed)
try {
if (f != null && display != null)
display.asyncExec(new Runnable() {
public void run() {
if (f != null) f.dispose();
}
});
if (p != null)
p.dispose();
} catch (Exception e) {
Plugin.log(IStatus.ERROR, "Error disposing graph frame.", e);
} finally {
p = null;
pv = null;
disposed = true;
}
}
public Frame getFrame() {
return f;
}
public JComponent getComponent() {
return pv;
}
public void init() throws SwingInitException {
try {
final IFileEditorInput input = (IFileEditorInput) getEditorInput();
if (input != null) {
Collection errs = new ArrayList();
p = new Project(((org.eclipse.core.internal.resources.File) input.getStorage()).getRawLocation().toString(), errs);
if (!disposed) {
if (!errs.isEmpty()) {
for (Iterator errIt = errs.iterator(); errIt.hasNext(); )
Plugin.log(IStatus.ERROR, errIt.next().toString());
display.syncExec(new Runnable() {
public void run() {
MessageDialog.openError(getSite().getShell(), "Error",
"Errors occurred initializing the Protege project. Refer to the error log for additional information.");
}
});
}
if (p.hasCompleteSources()) {
// Create the Swing-based canvas ...
pv = new ProjectView(p);
f.setLayout(new java.awt.BorderLayout());
f.add(pv, "Center");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
dispose();
}
});
// Fresh starting point for edit tracking ...
p.clearIsDirty();
} else {
throw new SwingInitException();
}
}
}
} catch (Exception e) {
if (!disposed) {
if (display != null)
display.syncExec(new Runnable() {
public void run() {
MessageDialog.openError(getSite().getShell(), "Error",
"Errors occurred initializing the Protege project. Refer to the error log for additional information.");
}
});
showLabelSync(MSG_OPENERR);
throw new SwingInitException(e);
}
}
}
public boolean isDisposed() {
return disposed;
}
}
/**
* Used to surface errors that occur during frame initialization.
*/
class SwingInitException extends Exception {
public SwingInitException() {
super();
}
public SwingInitException(String message) {
super(message);
}
public SwingInitException(Throwable cause) {
super(cause);
}
public SwingInitException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* Shows the Swing controls and handles interruption.
*/
class SwingInitThread extends Thread {
public AnimatedMsgThread animatedMsg = null;
public boolean canceled = false;
public SwingInitThread() {
super();
setPriority(Thread.MAX_PRIORITY);
setDaemon(true);
}
public void destroy() {
if (animatedMsg != null)
animatedMsg.end();
showLabelSync("");
}
public void interrupt() {
if (!canceled)
try {
canceled = true;
super.interrupt();
} finally {
destroy();
}
}
public synchronized void run() {
try {
showLabelSync("");
animatedMsg = new AnimatedMsgThread(MSG_OPENING);
animatedMsg.start();
// Reset the frame ...
Frame sf = null;
try {
sf = getSwingFrame();
} finally {
animatedMsg.end();
}
// Display the result ...
if (canceled || sf == null) {
showLabelSync("");
} else {
sf.setVisible(true);
showSwingSync();
}
} catch (Exception e) {
Plugin.log(IStatus.ERROR,
"An error occurred initializing the relation graph.", e);
}
}
}
/**
* Primary class ...
*/
static final private String MSG_OPENERR = "Unable to open the requested resource. Refer to the error log for additional information.";
static final private String MSG_OPENING = "Opening Protege 2000 ...";
static final private String MSG_NOMULTI = "A Protege editor is already active. Currently Protege restricts the number of concurrent edit sessions allowed within a single Java runtime. Please close the existing edit window before opening another Protege resource.";
private Display display;
private Composite displayArea, swtSwingContainer;
private SwingFrameAccess sfa;
private SwingInitThread siThread;
private Label label;
public LgProtegeEditor() {
}
protected void createLabel() {
label = new Label(displayArea, SWT.BORDER | SWT.WRAP);
}
protected void createLayout() {
displayArea.setLayout(new StackLayout());
}
protected void detachCurrentProjectTab() {
if (sfa != null && sfa.pv != null)
sfa.pv.detachCurrentTab();
}
public void dispose() {
disposeSwing();
if (label != null) label.dispose();
super.dispose();
}
protected void disposeSwing() {
disposeSwingThread();
if (sfa != null)
try { sfa.dispose(); }
finally { sfa = null; }
}
protected void disposeSwingThread() {
if (siThread != null)
siThread.interrupt();
siThread = null;
}
protected Composite getSWTSwingContainer() {
if (swtSwingContainer == null && display != null && !display.isDisposed())
display.syncExec(new Runnable() {
public void run() {
swtSwingContainer = new Composite(displayArea, SWT.EMBEDDED);
}
});
return swtSwingContainer;
}
protected Frame getSwingFrame() {
if (sfa == null || sfa.isDisposed() && display != null && !display.isDisposed()) {
sfa = new SwingFrameAccess();
try {
sfa.init();
} catch (SwingInitException e) {
Plugin.log(IStatus.ERROR,
"An error occurred initializing the Swing frame.", e);
sfa = null;
}
}
return sfa != null ? sfa.getFrame() : null;
}
protected synchronized Thread getSwingInitThread() {
if (!isSwingInitInProgress()) {
siThread = new SwingInitThread();
siThread.setName(getClass().getName());
}
return siThread;
}
protected boolean isSwingInitInProgress() {
return siThread != null && siThread.isAlive();
}
protected void logInfo(String msg) {
Plugin.log(IStatus.INFO, msg);
}
public void propertyChanged(Object source, int propId) {
}
protected void showSwing() {
if (!displayArea.isDisposed()) {
Composite swingContainer = getSWTSwingContainer();
((StackLayout) displayArea.getLayout())
.topControl = swingContainer;
// Note: The following appears to help avoid a sporatic
// repaint problem (controls are created but are
// not initially visible).
swingContainer.pack();
swingContainer.layout();
// Layout the controls ...
displayArea.layout();
readAndDispatch();
}
}
protected void showSwingSync() {
if (display != null && !display.isDisposed())
display.syncExec(new Runnable() {
public void run() {
showSwing();
}
});
}
protected void showLabel(final String labelText) {
if (!label.isDisposed()) {
label.setText(labelText);
((StackLayout) displayArea.getLayout()).topControl = label;
displayArea.layout();
readAndDispatch();
}
}
protected void showLabelSync(final String labelText) {
if (display != null && !display.isDisposed())
display.syncExec(new Runnable() {
public void run() {
showLabel(labelText);
}
});
}
protected void readAndDispatch() {
while (display != null && !display.isDisposed()
&& display.readAndDispatch());
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
displayArea = parent;
createLayout();
createLabel();
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
*/
public void doSave(IProgressMonitor monitor) {
if (sfa != null && sfa.p != null) {
Collection errs = new ArrayList();
sfa.p.save(errs);
if (errs.isEmpty()) {
sfa.p.clearIsDirty();
getSite().getWorkbenchWindow().setActivePage(getSite().getWorkbenchWindow().getActivePage());
} else {
for (Iterator errIt = errs.iterator(); errIt.hasNext(); )
Plugin.log(IStatus.ERROR, errIt.next().toString());
if (display != null)
display.syncExec(new Runnable() {
public void run() {
MessageDialog.openError(getSite().getShell(), "Error",
"An error occurred saving the Protege project. Refer to the error log for additional information.");
}
});
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#doSaveAs()
*/
public void doSaveAs() {
}
/* (non-Javadoc)
* @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
*/
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
display = site.getShell().getDisplay();
if (input instanceof IFileEditorInput) {
setSite(site);
setInput(input);
setPartName(((IFileEditorInput) input).getFile().getName());
setContentDescription(((IFileEditorInput) input).getFile().getFullPath().toString());
try {
getSwingInitThread().start();
} catch (IllegalThreadStateException e) {
}
} else {
throw new PartInitException("Invalid Input: Must be IFileEditorInput.");
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#isDirty()
*/
public boolean isDirty() {
return (sfa != null && sfa.p != null && sfa.p.isDirty());
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
*/
public boolean isSaveAsAllowed() {
return false;
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
*/
public void setFocus() {
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -