You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ctakes.apache.org by se...@apache.org on 2017/04/06 02:12:06 UTC
svn commit: r1790337 - in /ctakes/trunk:
ctakes-core/src/main/java/org/apache/ctakes/core/pipeline/
ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/
ctakes-gui/src/main/java/org/apache/ctakes/gui/component/
ctakes-gui/src/main/jav...
Author: seanfinan
Date: Thu Apr 6 02:12:06 2017
New Revision: 1790337
URL: http://svn.apache.org/viewvc?rev=1790337&view=rev
Log:
ctakes-424 : improved markup
ctakes-424 : added load and package buttons
ctakes-424 : changed validate icon
ctakes-424 : added header comment
Added:
ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/Folder_Blue.png (with props)
ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/RunReady.png (with props)
ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/TextLineNumber.java
Removed:
ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/piper/PiperValidator.java
Modified:
ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/pipeline/PiperFileReader.java
ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/PositionedSplitPane.java
ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/MainPanel2.java
ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/piper/PiperTextFilter.java
Modified: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/pipeline/PiperFileReader.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/pipeline/PiperFileReader.java?rev=1790337&r1=1790336&r2=1790337&view=diff
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/pipeline/PiperFileReader.java (original)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/pipeline/PiperFileReader.java Thu Apr 6 02:12:06 2017
@@ -151,15 +151,15 @@ final public class PiperFileReader {
}
}
- public void parsePipelineLine( final String line ) throws UIMAException {
+ public boolean parsePipelineLine( final String line ) throws UIMAException {
if ( line.isEmpty() || line.startsWith( "//" ) || line.startsWith( "#" ) || line.startsWith( "!" ) ) {
- return;
+ return true;
}
final int spaceIndex = line.indexOf( ' ' );
if ( spaceIndex < 0 ) {
- addToPipeline( line, "" );
+ return addToPipeline( line, "" );
} else {
- addToPipeline( line.substring( 0, spaceIndex ), line.substring( spaceIndex + 1 ).trim() );
+ return addToPipeline( line.substring( 0, spaceIndex ), line.substring( spaceIndex + 1 ).trim() );
}
}
@@ -175,20 +175,20 @@ final public class PiperFileReader {
* @param parameter specified by second word in the file line
* @throws UIMAException if the command could not be executed
*/
- private void addToPipeline( final String command, final String parameter ) throws UIMAException {
+ private boolean addToPipeline( final String command, final String parameter ) throws UIMAException {
switch ( command ) {
case "load":
loadPipelineFile( parameter );
- break;
+ return true;
case "package":
_userPackages.add( parameter );
- break;
+ return true;
case "set":
_builder.set( splitParameters( parameter ) );
- break;
+ return true;
case "cli":
_builder.set( getCliParameters( parameter ) );
- break;
+ return true;
case "reader":
if ( hasParameters( parameter ) ) {
final String[] component_parameters = splitFromParameters( parameter );
@@ -198,14 +198,14 @@ final public class PiperFileReader {
} else {
_builder.reader( getReaderClass( parameter ) );
}
- break;
+ return true;
case "readFiles":
if ( parameter.isEmpty() ) {
_builder.readFiles();
} else {
_builder.readFiles( parameter );
}
- break;
+ return true;
case "add":
if ( hasParameters( parameter ) ) {
final String[] component_parameters = splitFromParameters( parameter );
@@ -215,7 +215,7 @@ final public class PiperFileReader {
} else {
_builder.add( getComponentClass( parameter ) );
}
- break;
+ return true;
case "addLogged":
if ( hasParameters( parameter ) ) {
final String[] component_parameters = splitFromParameters( parameter );
@@ -225,7 +225,7 @@ final public class PiperFileReader {
} else {
_builder.addLogged( getComponentClass( parameter ) );
}
- break;
+ return true;
case "addDescription":
if ( hasParameters( parameter ) ) {
final String[] descriptor_parameters = splitFromParameters( parameter );
@@ -237,7 +237,7 @@ final public class PiperFileReader {
final AnalysisEngineDescription description = createDescription( parameter );
_builder.addDescription( description );
}
- break;
+ return true;
case "addLast":
if ( hasParameters( parameter ) ) {
final String[] component_parameters = splitFromParameters( parameter );
@@ -247,22 +247,23 @@ final public class PiperFileReader {
} else {
_builder.addLast( getComponentClass( parameter ) );
}
- break;
+ return true;
case "collectCuis":
_builder.collectCuis();
- break;
+ return true;
case "collectEntities":
_builder.collectEntities();
- break;
+ return true;
case "writeXmis":
if ( parameter.isEmpty() ) {
_builder.writeXMIs();
} else {
_builder.writeXMIs( parameter );
}
- break;
+ return true;
default:
- LOGGER.error( "Unknown Command: " + command );
+ LOGGER.error( "Unknown Piper Command: " + command );
+ return false;
}
}
Added: ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/Folder_Blue.png
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/Folder_Blue.png?rev=1790337&view=auto
==============================================================================
Binary file - no diff available.
Propchange: ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/Folder_Blue.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/RunReady.png
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/RunReady.png?rev=1790337&view=auto
==============================================================================
Binary file - no diff available.
Propchange: ctakes/trunk/ctakes-gui-res/src/main/resources/org/apache/ctakes/gui/pipeline/icon/RunReady.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/PositionedSplitPane.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/PositionedSplitPane.java?rev=1790337&r1=1790336&r2=1790337&view=diff
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/PositionedSplitPane.java (original)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/PositionedSplitPane.java Thu Apr 6 02:12:06 2017
@@ -13,6 +13,7 @@ final public class PositionedSplitPane e
static private final Logger LOGGER = Logger.getLogger( "PositionedSplitPane" );
+ private final Object LOCKER = new Object();
private boolean _isLocationSet;
private int _pixelLocation = -1;
private double _proportionalLocation = -1d;
@@ -82,15 +83,17 @@ final public class PositionedSplitPane e
*/
@Override
public void paint( final Graphics g ) {
- if ( !_isLocationSet || getDividerLocation() < 0 ) {
- if ( _pixelLocation > 0 ) {
- super.setDividerLocation( _pixelLocation );
- } else if ( _proportionalLocation > 0 ) {
- super.setDividerLocation( _proportionalLocation );
+ synchronized ( LOCKER ) {
+ if ( !_isLocationSet ) {
+ if ( _pixelLocation > 0 ) {
+ super.setDividerLocation( _pixelLocation );
+ } else if ( _proportionalLocation > 0 ) {
+ super.setDividerLocation( _proportionalLocation );
+ }
+ _isLocationSet = true;
}
- _isLocationSet = true;
+ super.paint( g );
}
- super.paint( g );
}
}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/TextLineNumber.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/TextLineNumber.java?rev=1790337&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/TextLineNumber.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/component/TextLineNumber.java Thu Apr 6 02:12:06 2017
@@ -0,0 +1,435 @@
+package org.apache.ctakes.gui.component;
+
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.MatteBorder;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.*;
+import java.awt.*;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 4/5/2017
+ */
+public class TextLineNumber extends JPanel
+ implements CaretListener, DocumentListener, PropertyChangeListener {
+
+ public final static float LEFT = 0.0f;
+ public final static float CENTER = 0.5f;
+ public final static float RIGHT = 1.0f;
+
+ private final static Border OUTER = new MatteBorder( 0, 0, 0, 2, Color.GRAY );
+
+ private final static int HEIGHT = Integer.MAX_VALUE - 1000000;
+
+ // Text component this TextTextLineNumber component is in sync with
+
+ private JTextComponent component;
+
+ // Properties that can be changed
+
+ private boolean updateFont;
+ private int borderGap;
+ private Color currentLineForeground;
+ private float digitAlignment;
+ private int minimumDisplayDigits;
+
+ // Keep history information to reduce the number of times the component
+ // needs to be repainted
+
+ private int lastDigits;
+ private int lastHeight;
+ private int lastLine;
+
+ private Map<String, FontMetrics> fonts;
+
+ /**
+ * Create a line number component for a text component. This minimum
+ * display width will be based on 3 digits.
+ *
+ * @param component the related text component
+ */
+ public TextLineNumber( JTextComponent component ) {
+ this( component, 3 );
+ }
+
+ /**
+ * Create a line number component for a text component.
+ *
+ * @param component the related text component
+ * @param minimumDisplayDigits the number of digits used to calculate
+ * the minimum width of the component
+ */
+ public TextLineNumber( JTextComponent component, int minimumDisplayDigits ) {
+ this.component = component;
+
+ setFont( component.getFont() );
+ setForeground( Color.DARK_GRAY );
+
+ setBorderGap( 5 );
+ setCurrentLineForeground( Color.MAGENTA );
+ setDigitAlignment( RIGHT );
+ setMinimumDisplayDigits( minimumDisplayDigits );
+
+ component.getDocument().addDocumentListener( this );
+ component.addCaretListener( this );
+ component.addPropertyChangeListener( "font", this );
+ }
+
+ /**
+ * Gets the update font property
+ *
+ * @return the update font property
+ */
+ public boolean getUpdateFont() {
+ return updateFont;
+ }
+
+ /**
+ * Set the update font property. Indicates whether this Font should be
+ * updated automatically when the Font of the related text component
+ * is changed.
+ *
+ * @param updateFont when true update the Font and repaint the line
+ * numbers, otherwise just repaint the line numbers.
+ */
+ public void setUpdateFont( boolean updateFont ) {
+ this.updateFont = updateFont;
+ }
+
+ /**
+ * Gets the border gap
+ *
+ * @return the border gap in pixels
+ */
+ public int getBorderGap() {
+ return borderGap;
+ }
+
+ /**
+ * The border gap is used in calculating the left and right insets of the
+ * border. Default value is 5.
+ *
+ * @param borderGap the gap in pixels
+ */
+ public void setBorderGap( int borderGap ) {
+ this.borderGap = borderGap;
+ Border inner = new EmptyBorder( 0, borderGap, 0, borderGap );
+ setBorder( new CompoundBorder( OUTER, inner ) );
+ lastDigits = 0;
+ setPreferredWidth();
+ }
+
+ /**
+ * Gets the current line rendering Color
+ *
+ * @return the Color used to render the current line number
+ */
+ public Color getCurrentLineForeground() {
+ return currentLineForeground == null ? getForeground() : currentLineForeground;
+ }
+
+ /**
+ * The Color used to render the current line digits. Default is Coolor.RED.
+ *
+ * @param currentLineForeground the Color used to render the current line
+ */
+ public void setCurrentLineForeground( Color currentLineForeground ) {
+ this.currentLineForeground = currentLineForeground;
+ }
+
+ /**
+ * Gets the digit alignment
+ *
+ * @return the alignment of the painted digits
+ */
+ public float getDigitAlignment() {
+ return digitAlignment;
+ }
+
+ /**
+ * Specify the horizontal alignment of the digits within the component.
+ * Common values would be:
+ * <ul>
+ * <li>TextLineNumber.LEFT
+ * <li>TextLineNumber.CENTER
+ * <li>TextLineNumber.RIGHT (default)
+ * </ul>
+ *
+ * @param digitAlignment LEFT, CENTER, of RIGHT
+ */
+ public void setDigitAlignment( float digitAlignment ) {
+ this.digitAlignment =
+ digitAlignment > 1.0f ? 1.0f : digitAlignment < 0.0f ? -1.0f : digitAlignment;
+ }
+
+ /**
+ * Gets the minimum display digits
+ *
+ * @return the minimum display digits
+ */
+ public int getMinimumDisplayDigits() {
+ return minimumDisplayDigits;
+ }
+
+ /**
+ * Specify the mimimum number of digits used to calculate the preferred
+ * width of the component. Default is 3.
+ *
+ * @param minimumDisplayDigits the number digits used in the preferred
+ * width calculation
+ */
+ public void setMinimumDisplayDigits( int minimumDisplayDigits ) {
+ this.minimumDisplayDigits = minimumDisplayDigits;
+ setPreferredWidth();
+ }
+
+ /**
+ * Calculate the width needed to display the maximum line number
+ */
+ private void setPreferredWidth() {
+ Element root = component.getDocument().getDefaultRootElement();
+ int lines = root.getElementCount();
+ int digits = Math.max( String.valueOf( lines ).length(), minimumDisplayDigits );
+
+ // Update sizes when number of digits in the line number changes
+
+ if ( lastDigits != digits ) {
+ lastDigits = digits;
+ FontMetrics fontMetrics = getFontMetrics( getFont() );
+ int width = fontMetrics.charWidth( '0' ) * digits;
+ Insets insets = getInsets();
+ int preferredWidth = insets.left + insets.right + width;
+
+ Dimension d = getPreferredSize();
+ d.setSize( preferredWidth, HEIGHT );
+ setPreferredSize( d );
+ setSize( d );
+ }
+ }
+
+ /**
+ * Draw the line numbers
+ */
+ @Override
+ public void paintComponent( Graphics g ) {
+ super.paintComponent( g );
+
+ // Determine the width of the space available to draw the line number
+
+ FontMetrics fontMetrics = component.getFontMetrics( component.getFont() );
+ Insets insets = getInsets();
+ int availableWidth = getSize().width - insets.left - insets.right;
+
+ // Determine the rows to draw within the clipped bounds.
+
+ Rectangle clip = g.getClipBounds();
+ int rowStartOffset = component.viewToModel( new Point( 0, clip.y ) );
+ int endOffset = component.viewToModel( new Point( 0, clip.y + clip.height ) );
+
+ while ( rowStartOffset <= endOffset ) {
+ try {
+ if ( isCurrentLine( rowStartOffset ) ) {
+ g.setColor( getCurrentLineForeground() );
+ } else {
+ g.setColor( getForeground() );
+ }
+
+ // Get the line number as a string and then determine the
+ // "X" and "Y" offsets for drawing the string.
+
+ String lineNumber = getTextLineNumber( rowStartOffset );
+ int stringWidth = fontMetrics.stringWidth( lineNumber );
+ int x = getOffsetX( availableWidth, stringWidth ) + insets.left;
+ int y = getOffsetY( rowStartOffset, fontMetrics );
+ g.drawString( lineNumber, x, y );
+
+ // Move to the next row
+
+ rowStartOffset = Utilities.getRowEnd( component, rowStartOffset ) + 1;
+ } catch ( Exception e ) {
+ break;
+ }
+ }
+ }
+
+ /*
+ * We need to know if the caret is currently positioned on the line we
+ * are about to paint so the line number can be highlighted.
+ */
+ private boolean isCurrentLine( int rowStartOffset ) {
+ int caretPosition = component.getCaretPosition();
+ Element root = component.getDocument().getDefaultRootElement();
+
+ if ( root.getElementIndex( rowStartOffset ) == root.getElementIndex( caretPosition ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * Get the line number to be drawn. The empty string will be returned
+ * when a line of text has wrapped.
+ */
+ protected String getTextLineNumber( int rowStartOffset ) {
+ Element root = component.getDocument().getDefaultRootElement();
+ int index = root.getElementIndex( rowStartOffset );
+ Element line = root.getElement( index );
+
+ if ( line.getStartOffset() == rowStartOffset ) {
+ return String.valueOf( index + 1 );
+ } else {
+ return "";
+ }
+ }
+
+ /*
+ * Determine the X offset to properly align the line number when drawn
+ */
+ private int getOffsetX( int availableWidth, int stringWidth ) {
+ return (int)((availableWidth - stringWidth) * digitAlignment);
+ }
+
+ /*
+ * Determine the Y offset for the current row
+ */
+ private int getOffsetY( int rowStartOffset, FontMetrics fontMetrics )
+ throws BadLocationException {
+ // Get the bounding rectangle of the row
+
+ Rectangle r = component.modelToView( rowStartOffset );
+ int lineHeight = fontMetrics.getHeight();
+ int y = r.y + r.height;
+ int descent = 0;
+
+ // The text needs to be positioned above the bottom of the bounding
+ // rectangle based on the descent of the font(s) contained on the row.
+
+ if ( r.height == lineHeight ) // default font is being used
+ {
+ descent = fontMetrics.getDescent();
+ } else // We need to check all the attributes for font changes
+ {
+ if ( fonts == null ) {
+ fonts = new HashMap<String, FontMetrics>();
+ }
+
+ Element root = component.getDocument().getDefaultRootElement();
+ int index = root.getElementIndex( rowStartOffset );
+ Element line = root.getElement( index );
+
+ for ( int i = 0; i < line.getElementCount(); i++ ) {
+ Element child = line.getElement( i );
+ AttributeSet as = child.getAttributes();
+ String fontFamily = (String)as.getAttribute( StyleConstants.FontFamily );
+ Integer fontSize = (Integer)as.getAttribute( StyleConstants.FontSize );
+ String key = fontFamily + fontSize;
+
+ FontMetrics fm = fonts.get( key );
+
+ if ( fm == null ) {
+ Font font = new Font( fontFamily, Font.PLAIN, fontSize );
+ fm = component.getFontMetrics( font );
+ fonts.put( key, fm );
+ }
+
+ descent = Math.max( descent, fm.getDescent() );
+ }
+ }
+
+ return y - descent;
+ }
+
+ //
+// Implement CaretListener interface
+//
+ @Override
+ public void caretUpdate( CaretEvent e ) {
+ // Get the line the caret is positioned on
+
+ int caretPosition = component.getCaretPosition();
+ Element root = component.getDocument().getDefaultRootElement();
+ int currentLine = root.getElementIndex( caretPosition );
+
+ // Need to repaint so the correct line number can be highlighted
+
+ if ( lastLine != currentLine ) {
+ repaint();
+ lastLine = currentLine;
+ }
+ }
+
+ //
+// Implement DocumentListener interface
+//
+ @Override
+ public void changedUpdate( DocumentEvent e ) {
+ documentChanged();
+ }
+
+ @Override
+ public void insertUpdate( DocumentEvent e ) {
+ documentChanged();
+ }
+
+ @Override
+ public void removeUpdate( DocumentEvent e ) {
+ documentChanged();
+ }
+
+ /*
+ * A document change may affect the number of displayed lines of text.
+ * Therefore the lines numbers will also change.
+ */
+ private void documentChanged() {
+ // View of the component has not been updated at the time
+ // the DocumentEvent is fired
+
+ SwingUtilities.invokeLater( new Runnable() {
+ @Override
+ public void run() {
+ try {
+ int endPos = component.getDocument().getLength();
+ Rectangle rect = component.modelToView( endPos );
+
+ if ( rect != null && rect.y != lastHeight ) {
+ setPreferredWidth();
+ repaint();
+ lastHeight = rect.y;
+ }
+ } catch ( BadLocationException ex ) { /* nothing to do */ }
+ }
+ } );
+ }
+
+ //
+// Implement PropertyChangeListener interface
+//
+ @Override
+ public void propertyChange( PropertyChangeEvent evt ) {
+ if ( evt.getNewValue() instanceof Font ) {
+ if ( updateFont ) {
+ Font newFont = (Font)evt.getNewValue();
+ setFont( newFont );
+ lastDigits = 0;
+ setPreferredWidth();
+ } else {
+ repaint();
+ }
+ }
+ }
+
+
+}
Modified: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/MainPanel2.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/MainPanel2.java?rev=1790337&r1=1790336&r2=1790337&view=diff
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/MainPanel2.java (original)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/MainPanel2.java Thu Apr 6 02:12:06 2017
@@ -1,10 +1,7 @@
package org.apache.ctakes.gui.pipeline;
import org.apache.ctakes.core.pipeline.PipeBitInfo;
-import org.apache.ctakes.gui.component.DisablerPane;
-import org.apache.ctakes.gui.component.LoggerPanel;
-import org.apache.ctakes.gui.component.PositionedSplitPane;
-import org.apache.ctakes.gui.component.SmoothTipList;
+import org.apache.ctakes.gui.component.*;
import org.apache.ctakes.gui.pipeline.bit.PipeBitFinder;
import org.apache.ctakes.gui.pipeline.bit.available.AvailablesListModel;
import org.apache.ctakes.gui.pipeline.bit.info.*;
@@ -29,9 +26,12 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.function.Function;
import java.util.stream.Collectors;
import static javax.swing.JOptionPane.PLAIN_MESSAGE;
@@ -61,8 +61,12 @@ final class MainPanel2 extends JPanel {
private JButton _runButton;
private JButton _helpButton;
- private JButton _setButton;
+ private JTextPane _textPane;
+
private JButton _addButton;
+ private JButton _setButton;
+ private JButton _loadButton;
+ private JButton _packageButton;
MainPanel2() {
@@ -81,6 +85,7 @@ final class MainPanel2 extends JPanel {
_chooser.setFileFilter( new FileNameExtensionFilter( "Pipeline Definition (Piper) File", "piper" ) );
_chooser.setFileView( new PiperFileView() );
+ createNewPiper();
}
@@ -120,8 +125,11 @@ final class MainPanel2 extends JPanel {
private JComponent createEastPanel() {
_piperDocument = new DefaultStyledDocument();
_piperTextFilter = new PiperTextFilter( _piperDocument );
- final JTextPane _textPane = new JTextPane( _piperDocument );
+ _textPane = new JTextPane( _piperDocument );
+ _textPane.putClientProperty( "caretWidth", 2 );
final JScrollPane scroll = new JScrollPane( _textPane );
+ final TextLineNumber lineNumber = new TextLineNumber( _textPane, 2 );
+ scroll.setRowHeaderView( lineNumber );
scroll.setMinimumSize( new Dimension( 100, 10 ) );
return scroll;
}
@@ -203,10 +211,7 @@ final class MainPanel2 extends JPanel {
final JToolBar toolBar = new JToolBar( SwingConstants.VERTICAL );
toolBar.setFloatable( false );
toolBar.setRollover( true );
-
- _setButton = addVerticalButton( toolBar, "Set Global Parameter" );
- _setButton.addActionListener( new SetAction() );
-
+ toolBar.addSeparator( new Dimension( 0, 30 ) );
final AddAction addAction = new AddAction();
final ParameterTableModel parameterModel = _infoPanel.getParameterModel();
@@ -214,15 +219,59 @@ final class MainPanel2 extends JPanel {
_addButton = addVerticalButton( toolBar, "Add selected Pipe Bit" );
_addButton.addActionListener( addAction );
_addButton.setEnabled( false );
+ toolBar.addSeparator( new Dimension( 0, 60 ) );
+ _setButton = addVerticalButton( toolBar, "Set Global Parameter" );
+ _setButton.addActionListener( new SetAction() );
+
+ toolBar.add( Box.createVerticalGlue() );
+ _loadButton = addVerticalButton( toolBar, "Load SubPiper" );
+ _loadButton.addActionListener( new LoadAction() );
+
+ _packageButton = addVerticalButton( toolBar, "Add Package" );
+ _packageButton.addActionListener( new PackageAction() );
SwingUtilities.invokeLater( new CommandIconLoader() );
return toolBar;
}
+ private void createNewPiper() {
+ final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern( "MMMM dd, yyyy" );
+ final LocalDate date = LocalDate.now();
+ final String text = "// *** Piper File ***\n" +
+ "// Created by " + System.getProperty( "user.name" ) + "\n" +
+ "// on " + date.format( dateFormatter ) + "\n\n";
+ try {
+ _piperDocument.remove( 0, _piperDocument.getLength() );
+ _piperDocument.insertString( 0, text, null );
+ _textPane.setCaretPosition( _piperDocument.getLength() );
+ } catch ( BadLocationException blE ) {
+ LOGGER.warn( blE.getMessage() );
+ }
+ _runButton.setEnabled( false );
+ }
-
+ private int getInsertCaret() throws BadLocationException {
+ int caret = _textPane.getCaretPosition();
+ if ( caret > 1 && _piperDocument.getText( caret - 1, 1 ).charAt( 0 ) == '\n' ) {
+ return caret;
+ }
+ final int length = _piperDocument.getLength() - caret;
+ final String docText = _piperDocument.getText( caret, length );
+ boolean careted = false;
+ for ( int i = 0; i < length - 1; i++ ) {
+ if ( docText.charAt( i ) == '\n' ) {
+ caret += i + 1;
+ careted = true;
+ break;
+ }
+ }
+ if ( !careted ) {
+ caret = _piperDocument.getLength();
+ }
+ return caret;
+ }
@@ -255,7 +304,7 @@ final class MainPanel2 extends JPanel {
final String newPng = "NewPiper.png";
final String openPng = "OpenPiper.png";
final String savePng = "SavePiper.png";
- final String validatePng = "CheckRun.png";
+ final String validatePng = "RunReady.png";
final String runPng = "RunPiper.png";
final String helpPng = "Help_32.png";
final Icon newIcon = IconLoader.loadIcon( dir + newPng );
@@ -276,11 +325,7 @@ final class MainPanel2 extends JPanel {
private final class NewPiperAction implements ActionListener {
@Override
public void actionPerformed( final ActionEvent event ) {
- try {
- _piperDocument.remove( 0, _piperDocument.getLength() );
- } catch ( BadLocationException blE ) {
- LOGGER.warn( blE.getMessage() );
- }
+ createNewPiper();
}
}
@@ -305,6 +350,7 @@ final class MainPanel2 extends JPanel {
} catch ( BadLocationException blE ) {
LOGGER.warn( blE.getMessage() );
}
+ _runButton.setEnabled( false );
}
}
@@ -326,8 +372,6 @@ final class MainPanel2 extends JPanel {
}
final String text = _piperDocument.getText( 0, _piperDocument.getLength() );
Files.write( Paths.get( path ), text.getBytes() );
- _piperDocument.remove( 0, _piperDocument.getLength() );
- _piperDocument.insertString( 0, text, null );
} catch ( BadLocationException | IOException multE ) {
LOGGER.warn( multE.getMessage() );
}
@@ -350,11 +394,12 @@ final class MainPanel2 extends JPanel {
private final class ValidateAction implements ActionListener {
@Override
public void actionPerformed( final ActionEvent event ) {
- if ( _piperTextFilter == null || _addButton == null ) {
+ if ( _piperTextFilter == null || _runButton == null ) {
return;
}
+ LOGGER.info( "Validating Piper File ..." );
final boolean valid = _piperTextFilter.validateText();
- _addButton.setEnabled( valid );
+ _runButton.setEnabled( valid );
}
}
@@ -400,13 +445,18 @@ final class MainPanel2 extends JPanel {
@Override
public void run() {
final String dir = "org/apache/ctakes/gui/pipeline/icon/";
-// final String arrow = "BlueRightArrow.png";
- final String setPng = "Parameters.png";
final String addPng = "PlusMark.png";
- final Icon setIcon = IconLoader.loadIcon( dir + setPng );
+ final String setPng = "Parameters.png";
+ final String loadPng = "BlueGearYellowGear.png";
+ final String packagePng = "Folder_Blue.png";
final Icon addIcon = IconLoader.loadIcon( dir + addPng );
- _setButton.setIcon( setIcon );
+ final Icon setIcon = IconLoader.loadIcon( dir + setPng );
+ final Icon loadIcon = IconLoader.loadIcon( dir + loadPng );
+ final Icon packageIcon = IconLoader.loadIcon( dir + packagePng );
_addButton.setIcon( addIcon );
+ _setButton.setIcon( setIcon );
+ _loadButton.setIcon( loadIcon );
+ _packageButton.setIcon( packageIcon );
}
}
@@ -419,13 +469,43 @@ final class MainPanel2 extends JPanel {
// Would require tracking. Or maybe a constant parse and track of variables set when the formatting is done.
// Then the "add" button would need to be enabled accordingly ...
// and the parameter table could display the mapped value.
- _piperDocument.insertString( _piperDocument.getLength(), "set ", null );
+ final int caret = getInsertCaret();
+ _piperDocument.insertString( caret, "\n// Set a global value\nset ", null );
} catch ( BadLocationException blE ) {
LOGGER.error( blE.getMessage() );
}
+ _runButton.setEnabled( false );
}
}
+ private final class LoadAction implements ActionListener {
+ @Override
+ public void actionPerformed( final ActionEvent event ) {
+ try {
+ final int caret = getInsertCaret();
+ _piperDocument.insertString( caret, "\n// Load a Piper file containing a partial Pipeline\nload ", null );
+ } catch ( BadLocationException blE ) {
+ LOGGER.error( blE.getMessage() );
+ }
+ _runButton.setEnabled( false );
+ }
+ }
+
+ private final class PackageAction implements ActionListener {
+ @Override
+ public void actionPerformed( final ActionEvent event ) {
+ try {
+ final int caret = getInsertCaret();
+ _piperDocument
+ .insertString( caret, "\n// Add a Package that contains Pipe Bits or Piper files\npackage ", null );
+ } catch ( BadLocationException blE ) {
+ LOGGER.error( blE.getMessage() );
+ }
+ _runButton.setEnabled( false );
+ }
+ }
+
+ static private final Function<String, String> maybeQuote = t -> t.contains( " " ) ? "\"" + t + "\"" : t;
private final class AddAction implements ActionListener, TableModelListener {
@Override
@@ -453,20 +533,26 @@ final class MainPanel2 extends JPanel {
!Arrays.equals( value, holder.getParameter( i ).defaultValue() ) ) {
helpSb.append( "# " ).append( holder.getParameterName( i ) )
.append( " " ).append( holder.getParameterDescription( i ) ).append( "\n" );
- final String valueText = Arrays.stream( value ).collect( Collectors.joining( "," ) );
+ final String valueText = Arrays.stream( value ).map( maybeQuote ).collect( Collectors.joining( "," ) );
parmSb.append( " " ).append( holder.getParameterName( i ) ).append( "=" ).append( valueText );
}
}
sb.append( helpSb.toString() );
- sb.append( "add " ).append( _infoPanel.getPipeBitClass().getName() );
+ final PipeBitInfo info = _infoPanel.getPipeBitInfo();
+ if ( info.role() == PipeBitInfo.Role.READER ) {
+ sb.append( "reader " );
+ } else {
+ sb.append( "add " );
+ }
+ sb.append( _infoPanel.getPipeBitClass().getName() );
sb.append( parmSb.toString() ).append( "\n" );
try {
-// _piperDocument.insertString( _textPane.getCaretPosition(), sb.toString(), null );
- // tODO publicize textpane
- _piperDocument.insertString( _piperDocument.getLength(), sb.toString(), null );
+ final int caret = getInsertCaret();
+ _piperDocument.insertString( caret, sb.toString(), null );
} catch ( BadLocationException blE ) {
LOGGER.error( blE.getMessage() );
}
+ _runButton.setEnabled( false );
}
@Override
Modified: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/piper/PiperTextFilter.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/piper/PiperTextFilter.java?rev=1790337&r1=1790336&r2=1790337&view=diff
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/piper/PiperTextFilter.java (original)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/piper/PiperTextFilter.java Thu Apr 6 02:12:06 2017
@@ -49,6 +49,9 @@ final public class PiperTextFilter exten
public void insertString( final FilterBypass fb, final int begin, final String text, final AttributeSet attr )
throws BadLocationException {
super.insertString( fb, begin, text, attr );
+// if ( shouldValidate( fb.getDocument(), begin, text.length() ) ) {
+// validateText();
+// } else
if ( shouldReformat( fb.getDocument(), begin, text.length() ) ) {
formatText( fb.getDocument() );
}
@@ -62,6 +65,9 @@ final public class PiperTextFilter exten
final AttributeSet attrs )
throws BadLocationException {
super.replace( fb, begin, length, text, attrs );
+// if ( shouldValidate( fb.getDocument(), begin, length ) ) {
+// validateText();
+// } else
if ( shouldReformat( fb.getDocument(), begin, length ) ) {
formatText( fb.getDocument() );
}
@@ -80,6 +86,13 @@ final public class PiperTextFilter exten
}
}
+ static private boolean shouldValidate( final Document document, final int begin, final int length )
+ throws BadLocationException {
+ final int testLength = Math.min( length + 2, document.getLength() - begin );
+ final String deltaText = document.getText( begin, testLength );
+ return deltaText.contains( "\n" );
+ }
+
public boolean validateText() {
final ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Boolean> valid = executor.submit( (Callable<Boolean>)_textValidator );
@@ -124,51 +137,79 @@ final public class PiperTextFilter exten
}
private void createStyles() {
- createStyle( "PLAIN", Color.BLACK, "PLAIN" );
- createStyle( "COMMENT", Color.GRAY, "COMMENT" );
- final Style error = createStyle( "ERROR", Color.RED, "ERROR" );
- StyleConstants.setStrikeThrough( error, true );
+ createStyle( "PLAIN", Color.BLACK, false, "PLAIN" );
+ final Style comment = createStyle( "COMMENT", Color.GRAY, false, "COMMENT" );
+ StyleConstants.setItalic( comment, true );
+ final Style error = createStyle( "ERROR", Color.RED, false, "ERROR" );
+ StyleConstants.setUnderline( error, true );
+ createStyle( "PIPE_BIT", Color.BLUE, false, "PIPE_BIT" );
+ createStyle( "BOLD_PIPE_BIT", Color.BLUE, "BOLD_PIPE_BIT" );
createStyle( "PARAMETER", Color.YELLOW, "PARAMETER" );
createStyle( "LOAD", Color.MAGENTA, "load" );
createStyle( "PACKAGE", Color.YELLOW.darker(), "package" );
createStyle( "SET", Color.ORANGE.darker(), "set", "cli" );
createStyle( "READER", Color.GREEN.darker().darker(), "reader", "readFiles" );
createStyle( "ADD", Color.CYAN.darker().darker(), "add", "addLogged", "addDescription", "addLast" );
- createStyle( "WRITE_XMI", Color.BLUE, "writeXmis", "collectCuis", "collectEntities" );
+ createStyle( "WRITE_XMI", Color.BLUE.darker(), "writeXmis", "collectCuis", "collectEntities" );
}
private Style createStyle( final String name, final Color color, final String... keys ) {
+ return createStyle( name, color, true, keys );
+ }
+
+ private Style createStyle( final String name, final Color color, final boolean bold, final String... keys ) {
final Style style = _document.addStyle( name, null );
StyleConstants.setForeground( style, color );
+ if ( bold ) {
+ StyleConstants.setBold( style, true );
+ }
Arrays.stream( keys ).forEach( k -> _styles.put( k, style ) );
return style;
}
- void formatLine( final int begin, final int end ) throws BadLocationException {
+ boolean formatLine( final int begin, final int end ) throws BadLocationException {
final int length = end - begin;
if ( length <= 0 ) {
- return;
+ return true;
}
final String text = _document.getText( begin, length );
if ( text.startsWith( "#" ) || text.startsWith( "//" ) || text.startsWith( "!" ) ) {
_document.setCharacterAttributes( begin, length, _styles.get( "COMMENT" ), true );
- return;
+ return true;
}
int commandEnd = text.indexOf( ' ' );
if ( commandEnd < 0 ) {
commandEnd = length;
}
- final Style commandStyle = getCommandStyle( text.substring( 0, commandEnd ) );
+ final String command = text.substring( 0, commandEnd );
+ final Style commandStyle = getCommandStyle( command );
_document.setCharacterAttributes( begin, commandEnd, commandStyle, true );
if ( length > commandEnd ) {
- _document.setCharacterAttributes( begin + commandEnd, length - commandEnd, _styles.get( "PLAIN" ), true );
+ int styleEnd = commandEnd + 1;
+ if ( command.equals( "reader" ) || command.startsWith( "add" ) ) {
+ final int bitStart = commandEnd + 1;
+ int bitEnd = text.indexOf( ' ', bitStart );
+ if ( bitEnd < 0 ) {
+ bitEnd = length;
+ }
+ int bitBold = bitStart;
+ final String pipeBitText = text.substring( bitStart, bitEnd );
+ final int dotIndex = pipeBitText.lastIndexOf( '.' );
+ if ( dotIndex > 0 ) {
+ bitBold = bitStart + dotIndex + 1;
+ _document.setCharacterAttributes(
+ begin + bitStart, bitBold - bitStart, _styles.get( "PIPE_BIT" ), true );
+ }
+ _document
+ .setCharacterAttributes( begin + bitBold, bitEnd - bitBold, _styles.get( "BOLD_PIPE_BIT" ), true );
+ styleEnd = bitEnd;
+ }
+ _document.setCharacterAttributes( begin + styleEnd, length - styleEnd, _styles.get( "PLAIN" ), true );
}
-// int nextSpace = text.indexOf( ' ', commandEnd );
-// while ( nextSpace > 0 ) {
-//
-//
-// nextSpace = text.indexOf( ' ', nextSpace + 1 );
-// }
+ if ( commandStyle.equals( _styles.get( "ERROR" ) ) ) {
+ return false;
+ }
+ return true;
}
private Style getCommandStyle( final String command ) {
@@ -178,7 +219,8 @@ final public class PiperTextFilter exten
}
return style;
}
-// private Style getParameterStyle( final String parameter ) {
+
+ // private Style getParameterStyle( final String parameter ) {
// final Style style = _styles.get( command );
// if ( style == null ) {
// return _styles.get( "ERROR" );
@@ -190,6 +232,7 @@ final public class PiperTextFilter exten
static private final class TextValidator extends TextFormatter implements Callable<Boolean> {
final private PiperFileReader _reader;
+ private boolean _haveReader;
private TextValidator( final StyledDocument document ) {
super( document );
@@ -198,6 +241,7 @@ final public class PiperTextFilter exten
@Override
public Boolean call() {
+ _haveReader = false;
boolean valid = true;
try {
final String text = _document.getText( 0, _document.getLength() );
@@ -208,6 +252,8 @@ final public class PiperTextFilter exten
if ( text.charAt( i ) == '\n' ) {
if ( validateLine( lineBegin, i ) ) {
formatLine( lineBegin, i );
+ } else {
+ valid = false;
}
lineBegin = i + 1;
lineEnded = true;
@@ -223,25 +269,36 @@ final public class PiperTextFilter exten
}
_document.setCharacterAttributes( _document.getLength(), _document.getLength(), _styles.get( "PLAIN" ), true );
_reader.getBuilder().clear();
+ if ( !_haveReader ) {
+ LOGGER.warn( "No Reader specified" );
+ return false;
+ }
return valid;
}
private boolean validateLine( final int begin, final int end ) throws BadLocationException {
final int length = end - begin;
if ( length <= 0 ) {
- return false;
+ return true;
}
final String text = _document.getText( begin, length );
if ( text.startsWith( "#" ) || text.startsWith( "//" ) || text.startsWith( "!" ) ) {
return true;
+ } else if ( text.startsWith( "readFiles " ) || text.startsWith( "reader " ) ) {
+ if ( _haveReader ) {
+ LOGGER.warn( "More than one Reader specified" );
+ _document.setCharacterAttributes( begin, end, _styles.get( "ERROR" ), true );
+ return false;
+ }
+ _haveReader = true;
}
try {
- _reader.parsePipelineLine( text );
+ return _reader.parsePipelineLine( text );
} catch ( UIMAException uE ) {
+ LOGGER.warn( uE.getMessage() );
_document.setCharacterAttributes( begin, end, _styles.get( "ERROR" ), true );
return false;
}
- return true;
}
}