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/03/27 14:37:46 UTC
svn commit: r1788936 [6/7] - in /ctakes/trunk: ctakes-gui-res/
ctakes-gui-res/src/ ctakes-gui-res/src/main/
ctakes-gui-res/src/main/resources/ ctakes-gui-res/src/main/resources/org/
ctakes-gui-res/src/main/resources/org/apache/ ctakes-gui-res/src/main/...
Added: 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=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/MainPanel2.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/MainPanel2.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,266 @@
+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.pipeline.bit.PipeBitFinder;
+import org.apache.ctakes.gui.pipeline.bit.available.AvailablesListModel;
+import org.apache.ctakes.gui.pipeline.bit.info.*;
+import org.apache.ctakes.gui.pipeline.piper.PiperTextFilter;
+import org.apache.ctakes.gui.util.IconLoader;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import javax.swing.table.JTableHeader;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultStyledDocument;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+
+import static javax.swing.JOptionPane.PLAIN_MESSAGE;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/20/2016
+ */
+final class MainPanel2 extends JPanel {
+
+ static private final Logger LOGGER = Logger.getLogger( "MainPanel" );
+
+ private final JFileChooser _chooser = new JFileChooser();
+
+ private final AvailablesListModel _availablesListModel = new AvailablesListModel();
+ private JList<PipeBitInfo> _availablesList;
+
+ private DefaultStyledDocument _piperDocument;
+
+ private JButton _newButton;
+ private JButton _openButton;
+ private JButton _saveButton;
+ private JButton _runButton;
+ private JButton _helpButton;
+
+
+ MainPanel2() {
+ super( new BorderLayout() );
+
+ final JSplitPane logSplit = new PositionedSplitPane( JSplitPane.VERTICAL_SPLIT );
+ logSplit.setTopComponent( createMainPanel() );
+ logSplit.setBottomComponent( LoggerPanel.createLoggerPanel() );
+ logSplit.setDividerLocation( 0.6d );
+
+ add( createToolBar(), BorderLayout.NORTH );
+
+ add( logSplit, BorderLayout.CENTER );
+ SwingUtilities.invokeLater( new ButtonIconLoader() );
+ }
+
+
+ private JComponent createWestPanel() {
+ final JTable fakeTable = new JTable();
+ final JTableHeader fakeHeader = fakeTable.getTableHeader();
+ final Component header = fakeHeader.getDefaultRenderer().getTableCellRendererComponent( null,
+ "Available Pipe Bits", false, false, -1, -1 );
+ ((JLabel)header).setHorizontalAlignment( SwingConstants.CENTER );
+
+ _availablesList = createPipeBitList( _availablesListModel );
+ final JScrollPane scroll = new JScrollPane( _availablesList );
+ scroll.setColumnHeaderView( header );
+ final JList<PipeBitInfo> rowHeaders = new JList<>( _availablesListModel );
+ rowHeaders.setFixedCellHeight( 20 );
+ rowHeaders.setCellRenderer( new RoleRenderer() );
+ scroll.setRowHeaderView( rowHeaders );
+ scroll.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
+
+ final JSplitPane split = new PositionedSplitPane();
+ split.setLeftComponent( scroll );
+ split.setRightComponent( createBitInfoPanel( _availablesList ) );
+ split.setDividerLocation( 0.3d );
+ return split;
+ }
+
+
+ private JComponent createEastPanel() {
+ _piperDocument = new DefaultStyledDocument();
+ new PiperTextFilter( _piperDocument );
+ final JTextPane textPane = new JTextPane( _piperDocument );
+ return new JScrollPane( textPane );
+ }
+
+
+ private JComponent createMainPanel() {
+ final JComponent westPanel = createWestPanel();
+ final JComponent eastPanel = createEastPanel();
+ return new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, westPanel, eastPanel );
+ }
+
+ private JToolBar createToolBar() {
+ final JToolBar toolBar = new JToolBar();
+ toolBar.setFloatable( false );
+ toolBar.setRollover( true );
+ _newButton = addButton( toolBar, "Create New Piper File" );
+ _newButton.addActionListener( new NewPiperAction() );
+ _openButton = addButton( toolBar, "Open Existing Piper File" );
+ _openButton.addActionListener( new OpenPiperAction() );
+ _saveButton = addButton( toolBar, "Save Current Piper File" );
+ _saveButton.addActionListener( new SavePiperAction() );
+ toolBar.addSeparator( new Dimension( 20, 0 ) );
+ _helpButton = addButton( toolBar, "Help" );
+ _helpButton.addActionListener( new HelpAction() );
+ toolBar.add( Box.createHorizontalGlue() );
+ _runButton = addButton( toolBar, "Run Current Piper File" );
+ toolBar.addSeparator( new Dimension( 10, 0 ) );
+ return toolBar;
+ }
+
+ static private JButton addButton( final JToolBar toolBar, final String toolTip ) {
+ toolBar.addSeparator( new Dimension( 10, 0 ) );
+ final JButton button = new JButton();
+ button.setFocusPainted( false );
+ // prevents first button from having a painted border
+ button.setFocusable( false );
+ button.setToolTipText( toolTip );
+ toolBar.add( button );
+ return button;
+ }
+
+ static private JList<PipeBitInfo> createPipeBitList( final ListModel<PipeBitInfo> model ) {
+ final JList<PipeBitInfo> bitList = new SmoothTipList<>( model );
+ bitList.setCellRenderer( new PipeBitInfoRenderer() );
+ bitList.setFixedCellHeight( 20 );
+ return bitList;
+ }
+
+ static private PipeBitInfoPanel createBitInfoPanel( final JList<PipeBitInfo> list ) {
+ final PipeBitInfoPanel pipeBitInfoPanel = new PipeBitInfoPanel();
+ pipeBitInfoPanel.setPipeBitInfoList( list );
+ pipeBitInfoPanel.setBorder( UIManager.getBorder( "ScrollPane.border" ) );
+ return pipeBitInfoPanel;
+ }
+
+ void findPipeBits() {
+ final ExecutorService executor = Executors.newSingleThreadExecutor();
+ executor.execute( new PiperBitParser() );
+ }
+
+ private class PiperBitParser implements Runnable {
+ @Override
+ public void run() {
+ final JFrame frame = (JFrame)SwingUtilities.getRoot( MainPanel2.this );
+ frame.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) );
+ DisablerPane.getInstance().setVisible( true );
+ PipeBitFinder.getInstance().scan();
+ _availablesListModel.setPipeBits( PipeBitFinder.getInstance().getPipeBits() );
+ DisablerPane.getInstance().setVisible( false );
+ frame.setCursor( Cursor.getDefaultCursor() );
+ }
+ }
+
+
+ /**
+ * Simple Runnable that loads an icon
+ */
+ private final class ButtonIconLoader implements Runnable {
+ @Override
+ public void run() {
+ final String dir = "org/apache/ctakes/gui/pipeline/icon/";
+ final String newFile = "NewPiper.png";
+ final String openFile = "OpenPiper.png";
+ final String saveFile = "SavePiper.png";
+ final String runFile = "RunPiper.png";
+ final String helpFile = "Help_32.png";
+ final Icon newIcon = IconLoader.loadIcon( dir + newFile );
+ final Icon openIcon = IconLoader.loadIcon( dir + openFile );
+ final Icon saveIcon = IconLoader.loadIcon( dir + saveFile );
+ final Icon runIcon = IconLoader.loadIcon( dir + runFile );
+ final Icon helpIcon = IconLoader.loadIcon( dir + helpFile );
+ _newButton.setIcon( newIcon );
+ _openButton.setIcon( openIcon );
+ _saveButton.setIcon( saveIcon );
+ _runButton.setIcon( runIcon );
+ _helpButton.setIcon( helpIcon );
+ }
+ }
+
+ 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() );
+ }
+ }
+ }
+
+ private final class OpenPiperAction implements ActionListener {
+ @Override
+ public void actionPerformed( final ActionEvent event ) {
+ final int option = _chooser.showOpenDialog( null );
+ if ( option != JFileChooser.APPROVE_OPTION ) {
+ return;
+ }
+ String text = "";
+ final File file = _chooser.getSelectedFile();
+ try {
+ text = Files.lines( Paths.get( file.getPath() ) ).collect( Collectors.joining() );
+ } catch ( IOException ioE ) {
+ LOGGER.error( ioE.getMessage() );
+ return;
+ }
+ try {
+ _piperDocument.remove( 0, _piperDocument.getLength() );
+ _piperDocument.insertString( 0, text, null );
+ } catch ( BadLocationException blE ) {
+ LOGGER.warn( blE.getMessage() );
+ }
+ }
+ }
+
+ private final class SavePiperAction implements ActionListener {
+ @Override
+ public void actionPerformed( final ActionEvent event ) {
+ if ( _piperDocument.getLength() == 0 ) {
+ return;
+ }
+ final int option = _chooser.showSaveDialog( null );
+ if ( option != JFileChooser.APPROVE_OPTION ) {
+ return;
+ }
+ final File file = _chooser.getSelectedFile();
+ try {
+ final String text = _piperDocument.getText( 0, _piperDocument.getLength() );
+ Files.write( Paths.get( file.getPath() ), text.getBytes() );
+ _piperDocument.remove( 0, _piperDocument.getLength() );
+ _piperDocument.insertString( 0, text, null );
+ } catch ( BadLocationException | IOException multE ) {
+ LOGGER.warn( multE.getMessage() );
+ }
+ }
+ }
+
+ static private final class HelpAction implements ActionListener {
+ @Override
+ public void actionPerformed( final ActionEvent event ) {
+ final JPanel panel = new JPanel( new BorderLayout() );
+ panel.add( new JLabel( "Dependency and Product Types." ), BorderLayout.NORTH );
+ final JList<PipeBitInfo.TypeProduct> list = new JList<>( new TypeProductListModel() );
+ list.setCellRenderer( new TypeProductRenderer() );
+ panel.add( list, BorderLayout.CENTER );
+ panel.add( new JLabel( "Types are associated with Pipe Bits." ), BorderLayout.SOUTH );
+ JOptionPane.showMessageDialog( null, panel, "Type Products Help", PLAIN_MESSAGE, null );
+ }
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperCreator.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperCreator.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperCreator.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,84 @@
+package org.apache.ctakes.gui.pipeline;
+
+import org.apache.ctakes.gui.component.DisablerPane;
+import org.apache.ctakes.gui.pipeline.bit.PipeBitPainter;
+import org.apache.ctakes.gui.util.IconLoader;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/20/2016
+ */
+final public class PiperCreator {
+
+ static private final Logger LOGGER = Logger.getLogger( "PiperCreator" );
+
+ private PiperCreator() {
+ }
+
+ static private JFrame createFrame() {
+ final JFrame frame = new JFrame( "cTAKES Simple Pipeline Fabricator" );
+ frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
+ // Use 1024 x 768 as the minimum required resolution (XGA)
+ // iPhone 3 : 480 x 320 (3:2, HVGA)
+ // iPhone 4 : 960 x 640 (3:2, unique to Apple)
+ // iPhone 5 : 1136 x 640 (under 16:9, unique to Apple)
+ // iPad 3&4 : 2048 x 1536 (4:3, QXGA)
+ // iPad Mini: 1024 x 768 (4:3, XGA)
+ final Dimension size = new Dimension( 800, 600 );
+ frame.setSize( size );
+ frame.setMinimumSize( size );
+ final JMenuBar menuBar = new JMenuBar();
+// final JMenu fileMenu = new JMenu( "File" );
+// menuBar.add( fileMenu );
+
+ frame.setJMenuBar( menuBar );
+ System.setProperty( "apple.laf.useScreenMenuBar", "true" );
+ return frame;
+ }
+
+ static private MainPanel2 createMainPanel() {
+ return new MainPanel2();
+ }
+
+ public static void main( final String... args ) {
+ try {
+ UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
+ UIManager.getDefaults().put( "SplitPane.border", BorderFactory.createEmptyBorder() );
+ } catch ( ClassNotFoundException | InstantiationException
+ | IllegalAccessException | UnsupportedLookAndFeelException multE ) {
+ LOGGER.error( multE.getLocalizedMessage() );
+ }
+ final JFrame frame = createFrame();
+ final MainPanel2 mainPanel = createMainPanel();
+ frame.add( mainPanel );
+ frame.pack();
+ frame.setVisible( true );
+ DisablerPane.getInstance().initialize( frame );
+ PipeBitPainter.getInstance().loadIcons();
+ LOGGER.info( "1. Select your Apache cTAKES root directory." );
+ LOGGER.info( " It can be a pre-built binary installation or a developer sandbox." );
+ LOGGER.info( "2. Select your Unified Medical Language System (UMLS) root directory." );
+ LOGGER.info( " Once selected, your UMLS database will be parsed for available content." );
+ LOGGER.info( "3. Select your desired Vocabulary sources in the left table." );
+ LOGGER.info( " Recommended Vocabulary sources are pre-selected." );
+ LOGGER.info( "4. Select your desired Semantic Types in the right table." );
+ LOGGER.info( " Recommended Semantic types are pre-selected." );
+ LOGGER.info( "5. Type a name for your dictionary." );
+ LOGGER.info( "6. Click \'Build Dictionary\'" );
+ LOGGER.info( "- You can resize this log panel by clicking the top and dragging up or down." );
+
+ final Object[] options = { "Scan" };
+ final Icon scanIcon = IconLoader.loadIcon( "org/apache/ctakes/gui/pipeline/icon/" + "FindOnPc_48.png" );
+ JOptionPane.showOptionDialog( frame, "A Scan must be performed to find available Pipe Bits.\n" +
+ "Pipe Bits are used to assemble a cTAKES Pipeline.",
+ "Find Pipe Bits", JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, scanIcon, options, options[ 0 ] );
+ mainPanel.findPipeBits();
+
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperDisplayModel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperDisplayModel.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperDisplayModel.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/PiperDisplayModel.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,13 @@
+package org.apache.ctakes.gui.pipeline;
+
+import java.util.logging.Logger;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/13/2017
+ */
+public class PiperDisplayModel {
+
+ static private final Logger LOGGER = Logger.getLogger( "PiperDisplayModel" );
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitCellRenderer.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitCellRenderer.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitCellRenderer.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitCellRenderer.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,34 @@
+package org.apache.ctakes.gui.pipeline.bit;
+
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.logging.Logger;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/13/2017
+ */
+final public class BitCellRenderer implements ListCellRenderer<Object> {
+
+ static private final Logger LOGGER = Logger.getLogger( "BitCellRenderer" );
+
+
+ private final ListCellRenderer<Object> _delegate = new DefaultListCellRenderer();
+
+ @Override
+ public Component getListCellRendererComponent(
+ final JList<?> list,
+ final Object value,
+ final int index,
+ final boolean isSelected,
+ final boolean cellHasFocus ) {
+ final Component renderer = _delegate.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
+
+ PipeBitPainter.getInstance().paintObject( renderer, value, isSelected );
+
+ return renderer;
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitInfoPanel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitInfoPanel.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitInfoPanel.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/BitInfoPanel.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,120 @@
+package org.apache.ctakes.gui.pipeline.bit;
+
+import org.apache.ctakes.gui.component.SmoothTipTable;
+import org.apache.ctakes.gui.pipeline.bit.parameter.ParameterCellRenderer;
+import org.apache.ctakes.gui.pipeline.bit.parameter.ParameterInfoPanel;
+import org.apache.ctakes.gui.pipeline.bit.parameter.ParameterTableModel;
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/19/2017
+ */
+abstract public class BitInfoPanel extends JPanel {
+
+ static private final Logger LOGGER = Logger.getLogger( "BitInfoPanel" );
+
+ protected JComponent _name;
+ protected JLabel _description;
+ protected JLabel _dependencies;
+ protected JLabel _usables;
+ protected JLabel _outputs;
+
+ protected ParameterTableModel _parameterTableModel;
+ protected ParameterInfoPanel _parameterInfoPanel;
+
+ public BitInfoPanel() {
+ super( new BorderLayout( 5, 5 ) );
+
+ add( createMainPanel(), BorderLayout.NORTH );
+
+ _parameterTableModel = new ParameterTableModel();
+ final JTable parameterTable = createParameterTable( _parameterTableModel );
+ add( new JScrollPane( parameterTable ), BorderLayout.CENTER );
+
+ _parameterInfoPanel = createParameterInfoPanel();
+ _parameterInfoPanel.setParameterTable( parameterTable );
+ add( _parameterInfoPanel, BorderLayout.SOUTH );
+ }
+
+ abstract protected String getNameLabelPrefix();
+
+ abstract protected JComponent createNameEditor();
+
+ abstract protected void setBitName( final String text );
+
+ abstract protected ParameterInfoPanel createParameterInfoPanel();
+
+ protected void clear() {
+ setBitName( "" );
+ _description.setText( "" );
+ _dependencies.setText( "" );
+ _usables.setText( "" );
+ _outputs.setText( "" );
+ _parameterTableModel.setParameterHolder( null );
+ _parameterInfoPanel.setParameterHolder( null );
+ }
+
+ private JComponent createMainPanel() {
+ _name = createNameEditor();
+ final JComponent namePanel = createNamePanel( getNameLabelPrefix() + " Bit Name:", _name );
+ _description = new JLabel();
+ final JComponent descPanel = createNamePanel( "Description:", _description );
+ _dependencies = new JLabel();
+ final JComponent inPanel = createNamePanel( "Dependencies:", _dependencies );
+ _usables = new JLabel();
+ final JComponent usablePanel = createNamePanel( "Usable:", _usables );
+ _outputs = new JLabel();
+ final JComponent outPanel = createNamePanel( "Products:", _outputs );
+
+ final JPanel panel = new JPanel( new GridLayout( 5, 1 ) );
+ panel.add( namePanel );
+ panel.add( descPanel );
+ panel.add( inPanel );
+ panel.add( usablePanel );
+ panel.add( outPanel );
+ return panel;
+ }
+
+ static private JTable createParameterTable( final TableModel model ) {
+ final JTable table = new SmoothTipTable( model );
+ table.setRowHeight( 20 );
+ table.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN );
+ table.getColumnModel().getColumn( 0 ).setPreferredWidth( 100 );
+ final TableRowSorter<TableModel> sorter = new TableRowSorter<>( model );
+ table.setAutoCreateRowSorter( true );
+ table.setRowSorter( sorter );
+ table.setRowSelectionAllowed( true );
+ table.setCellSelectionEnabled( true );
+ table.setDefaultRenderer( ConfigurationParameter.class, new ParameterCellRenderer() );
+ ListSelectionModel selectionModel = table.getSelectionModel();
+ selectionModel.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
+ return table;
+ }
+
+ static private JComponent createNamePanel( final String name, final JComponent nameLabel ) {
+ final JPanel panel = new JPanel( new BorderLayout( 10, 10 ) );
+ panel.setBorder( new EmptyBorder( 2, 10, 2, 10 ) );
+ final JLabel label = new JLabel( name );
+ label.setPreferredSize( new Dimension( 90, 20 ) );
+ label.setHorizontalAlignment( SwingConstants.TRAILING );
+ final Border emptyBorder = new EmptyBorder( 0, 10, 0, 0 );
+ final Border border
+ = new CompoundBorder( UIManager.getLookAndFeelDefaults().getBorder( "TextField.border" ), emptyBorder );
+ nameLabel.setBorder( border );
+ panel.add( label, BorderLayout.WEST );
+ panel.add( nameLabel, BorderLayout.CENTER );
+ return panel;
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitFinder.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitFinder.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitFinder.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitFinder.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,95 @@
+package org.apache.ctakes.gui.pipeline.bit;
+
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.ScanInterruptedException;
+import io.github.lukehutch.fastclasspathscanner.matchprocessor.SubclassMatchProcessor;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+import org.apache.log4j.Logger;
+import org.apache.uima.analysis_component.Annotator_ImplBase;
+import org.apache.uima.analysis_component.JCasAnnotator_ImplBase;
+import org.apache.uima.collection.CasConsumer_ImplBase;
+import org.apache.uima.collection.CollectionReader_ImplBase;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Finds Collection Readers, Annotators, Cas Consumers (Writers), and their metadata
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/22/2016
+ */
+public enum PipeBitFinder {
+ INSTANCE;
+
+ static public PipeBitFinder getInstance() {
+ return INSTANCE;
+ }
+
+ private final Logger LOGGER = Logger.getLogger( "PipeBitFinder" );
+
+ private final Collection<Class<?>> _pipeBits = new ArrayList<>();
+ private boolean _didScan = false;
+
+ synchronized public void reset() {
+ _pipeBits.clear();
+ _didScan = false;
+ }
+
+ synchronized public Collection<Class<?>> getPipeBits() {
+ scan();
+ return _pipeBits;
+ }
+
+ static private boolean isPipeBit( final Class<?> clazz ) {
+ final String className = clazz.getName();
+ return !className.startsWith( "org.apache.uima.tutorial" )
+ && !className.startsWith( "org.apache.uima.examples" )
+ && !Modifier.isAbstract( clazz.getModifiers() );
+ }
+
+ synchronized public void scan() {
+ if ( _didScan ) {
+ return;
+ }
+ final SubclassMatchProcessor<CollectionReader_ImplBase> readerAdder = r -> {
+ if ( isPipeBit( r ) ) {
+ _pipeBits.add( r );
+ }
+ };
+ final SubclassMatchProcessor<Annotator_ImplBase> annotatorAdder = a -> {
+ if ( isPipeBit( a ) ) {
+ _pipeBits.add( a );
+ }
+ };
+ final SubclassMatchProcessor<CasConsumer_ImplBase> writerAdder = w -> {
+ if ( isPipeBit( w ) ) {
+ _pipeBits.add( w );
+ }
+ };
+ // Don't want super-primitive cleartk or uima classes
+ final FastClasspathScanner scanner = new FastClasspathScanner();
+ LOGGER.info( "Starting Scan for Pipeline Bits" );
+ try {
+ scanner.matchSubclassesOf( CollectionReader_ImplBase.class, readerAdder )
+ .matchSubclassesOf( Annotator_ImplBase.class, annotatorAdder )
+ .matchSubclassesOf( CasConsumer_ImplBase.class, writerAdder );
+ final ScanResult result = scanner.scan();
+ } catch ( ScanInterruptedException siE ) {
+ LOGGER.error( siE.getMessage() );
+ }
+ // Get rid of the abstract classes
+ _pipeBits.remove( CollectionReader_ImplBase.class );
+ _pipeBits.remove( JCasAnnotator_ImplBase.class );
+ _pipeBits.remove( CasConsumer_ImplBase.class );
+ // FastClassPathScanner blacklisting doesn't work, so we need to remove unwanted packages manually
+ _pipeBits.removeIf( c -> c.getPackage().getName().startsWith( "org.cleartk" )
+ || c.getPackage().getName().startsWith( "org.apache.uima" ) );
+ LOGGER.info( "Scan Finished" );
+ _didScan = true;
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitPainter.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitPainter.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitPainter.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/PipeBitPainter.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,145 @@
+package org.apache.ctakes.gui.pipeline.bit;
+
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.gui.util.IconLoader;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/13/2017
+ */
+public enum PipeBitPainter {
+ INSTANCE;
+
+ static public PipeBitPainter getInstance() {
+ return INSTANCE;
+ }
+
+ static private final Logger LOGGER = Logger.getLogger( "PipeBitPainter" );
+
+ static private final Color READER_COLOR = Color.GREEN.darker().darker();
+ static private final Color ANNOTATOR_COLOR = Color.CYAN.darker().darker();
+ static private final Color WRITER_COLOR = Color.BLUE;
+ static private final Color SPECIAL_COLOR = Color.MAGENTA.darker();
+ static private final String READER_ICON_FILE = "GreenArrowIn.png";
+ static private final String ANNOTATOR_ICON_FILE = "BlueGear.png";
+ static private final String WRITER_ICON_FILE = "BlueArrowOut.png";
+ static private final String SPECIAL_ICON_FILE = "Utilities.png";
+
+ static private final Border EMPTY_BORDER = new EmptyBorder( 0, 5, 0, 0 );
+
+
+ private Icon READER_ICON = null;
+ private Icon ANNOTATOR_ICON = null;
+ private Icon WRITER_ICON = null;
+ private Icon SPECIAL_ICON = null;
+ private boolean _iconLoadAttempted;
+
+
+ synchronized public void loadIcons() {
+ if ( _iconLoadAttempted ) {
+ return;
+ }
+ _iconLoadAttempted = true;
+ SwingUtilities.invokeLater( new PipeBitIconLoader() );
+ }
+
+ public void paintObject( final Component renderer, final Object value, final boolean isSelected ) {
+ if ( PipeBitInfo.class.isInstance( value ) ) {
+ paintPipeBitInfo( renderer, (PipeBitInfo)value, isSelected );
+ } else {
+ LOGGER.error( value.getClass().getName() + " is not a PipeBitInfo" );
+ renderer.setBackground( Color.DARK_GRAY );
+ setText( renderer, "Invalid" );
+ setToolTipText( renderer, "Invalid Information" );
+ }
+ }
+
+ public void paintPipeBitInfo( final Component renderer, final PipeBitInfo info, final boolean isSelected ) {
+ if ( !isSelected ) {
+ switch ( info.role() ) {
+ case READER:
+ renderer.setForeground( READER_COLOR );
+ break;
+ case ANNOTATOR:
+ renderer.setForeground( ANNOTATOR_COLOR );
+ break;
+ case WRITER:
+ renderer.setForeground( WRITER_COLOR );
+ break;
+ case SPECIAL:
+ renderer.setForeground( SPECIAL_COLOR );
+ break;
+ }
+ }
+ setIcon( renderer, info );
+ setText( renderer, info.name() );
+ setToolTipText( renderer, info.description() );
+ }
+
+ private void setIcon( final Component renderer, final PipeBitInfo info ) {
+ if ( !JLabel.class.isInstance( renderer ) ) {
+ return;
+ }
+ ((JLabel)renderer).setBorder( EMPTY_BORDER );
+ switch ( info.role() ) {
+ case READER:
+ ((JLabel)renderer).setIcon( READER_ICON );
+ break;
+ case ANNOTATOR:
+ ((JLabel)renderer).setIcon( ANNOTATOR_ICON );
+ break;
+ case WRITER:
+ ((JLabel)renderer).setIcon( WRITER_ICON );
+ break;
+ case SPECIAL:
+ ((JLabel)renderer).setIcon( SPECIAL_ICON );
+ break;
+ }
+ }
+
+ static private void setText( final Component renderer, final String text ) {
+ if ( !JLabel.class.isInstance( renderer ) ) {
+ LOGGER.error( "Renderer " + renderer.getClass().getName() + " is not a JLabel" );
+ return;
+ }
+ ((JLabel)renderer).setText( text );
+ }
+
+ static private void setToolTipText( final Component renderer, final String text ) {
+ if ( !JComponent.class.isInstance( renderer ) ) {
+ LOGGER.error( "Renderer " + renderer.getClass().getName() + " is not a JComponent" );
+ return;
+ }
+ ((JComponent)renderer).setToolTipText( text );
+ }
+
+
+ /**
+ * Simple Callable that loads and resizes an icon
+ */
+ private final class PipeBitIconLoader implements Runnable {
+ static private final int ICON_SIZE = 16;
+ static private final String ICON_DIR = "org/apache/ctakes/gui/pipeline/icon/";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ READER_ICON = IconLoader.loadIcon( ICON_DIR + READER_ICON_FILE, ICON_SIZE );
+ ANNOTATOR_ICON = IconLoader.loadIcon( ICON_DIR + ANNOTATOR_ICON_FILE, ICON_SIZE );
+ WRITER_ICON = IconLoader.loadIcon( ICON_DIR + WRITER_ICON_FILE, ICON_SIZE );
+ SPECIAL_ICON = IconLoader.loadIcon( ICON_DIR + SPECIAL_ICON_FILE, ICON_SIZE );
+ }
+ }
+
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesListModel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesListModel.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesListModel.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesListModel.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,76 @@
+package org.apache.ctakes.gui.pipeline.bit.available;
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.core.pipeline.PipeBitInfoUtil;
+import org.apache.ctakes.gui.pipeline.bit.info.PipeBitInfoComparator;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import java.util.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/13/2017
+ */
+final public class AvailablesListModel extends AbstractListModel<PipeBitInfo> {
+
+ static private final Logger LOGGER = Logger.getLogger( "AvailablesListModel" );
+
+
+ private final List<PipeBitInfo> _pipeBitInfos = new ArrayList<>();
+
+ private final Map<PipeBitInfo, Class<?>> _pipeBitMap = new HashMap<>();
+
+ /**
+ * Populate the list
+ *
+ * @param bits -
+ */
+ public void setPipeBits( final Collection<Class<?>> bits ) {
+ final int oldSize = _pipeBitInfos.size();
+ if ( oldSize > 0 ) {
+ _pipeBitInfos.clear();
+ _pipeBitMap.clear();
+ }
+ if ( bits == null || bits.isEmpty() ) {
+ if ( oldSize > 0 ) {
+ fireIntervalRemoved( this, 0, oldSize - 1 );
+ }
+ return;
+ }
+ for ( Class<?> bit : bits ) {
+ final PipeBitInfo info = PipeBitInfoUtil.getInfo( bit );
+ _pipeBitInfos.add( info );
+ _pipeBitMap.put( info, bit );
+ }
+ _pipeBitInfos.sort( PipeBitInfoComparator.getInstance() );
+ fireContentsChanged( this, 0, _pipeBitInfos.size() );
+ }
+
+ /**
+ * @param pipeBitInfo -
+ * @return the actual pipeline bit class
+ */
+ public Class<?> getPipeBit( final PipeBitInfo pipeBitInfo ) {
+ return _pipeBitMap.get( pipeBitInfo );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getSize() {
+ return _pipeBitInfos.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public PipeBitInfo getElementAt( final int index ) {
+ return _pipeBitInfos.get( index );
+ }
+
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesRenderer.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesRenderer.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesRenderer.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/available/AvailablesRenderer.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,84 @@
+package org.apache.ctakes.gui.pipeline.bit.available;
+
+import org.apache.ctakes.gui.component.CellRendererPanel;
+import org.apache.ctakes.gui.pipeline.bit.PipeBitPainter;
+import org.apache.ctakes.gui.util.IconLoader;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+import java.awt.*;
+import java.util.logging.Logger;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/23/2017
+ */
+final public class AvailablesRenderer implements ListCellRenderer<Object> {
+
+ static private final Logger LOGGER = Logger.getLogger( "AvailablesRenderer" );
+
+ static private final Border SELECTED_BORDER = new LineBorder( Color.DARK_GRAY, 1, true );
+ static private final Border UNSELECTED_BORDER = new EmptyBorder( 0, 0, 0, 5 );
+
+ private final ListCellRenderer<Object> _delegate = new DefaultListCellRenderer();
+ private JLabel _arrowLabel;
+
+ private final JPanel _focusRenderer;
+
+
+ public AvailablesRenderer() {
+ _focusRenderer = new CellRendererPanel( new BorderLayout() );
+ _focusRenderer.setBorder( new EmptyBorder( 0, 0, 0, 5 ) );
+ _arrowLabel = new JLabel();
+ _focusRenderer.add( _arrowLabel, BorderLayout.EAST );
+ SwingUtilities.invokeLater( new RightArrowIconLoader() );
+ }
+
+ @Override
+ public Component getListCellRendererComponent(
+ final JList<?> list,
+ final Object value,
+ final int index,
+ final boolean isSelected,
+ final boolean cellHasFocus ) {
+ final Component renderer = _delegate.getListCellRendererComponent( list, value, index, false, false );
+
+ PipeBitPainter.getInstance().paintObject( renderer, value, false );
+
+ final Point p = list.getMousePosition();
+ if ( p != null ) {
+ final int hoverIndex = list.locationToIndex( p );
+ if ( hoverIndex == index ) {
+ _focusRenderer.add( renderer, BorderLayout.CENTER );
+ if ( isSelected ) {
+ _focusRenderer.setBorder( SELECTED_BORDER );
+ } else {
+ _focusRenderer.setBorder( UNSELECTED_BORDER );
+ }
+ return _focusRenderer;
+ }
+ }
+ if ( isSelected && renderer instanceof JComponent ) {
+ ((JComponent)renderer).setBorder( SELECTED_BORDER );
+ }
+ return renderer;
+ }
+
+
+ /**
+ * Simple Runnable that loads an icon
+ */
+ private final class RightArrowIconLoader implements Runnable {
+ @Override
+ public void run() {
+ final String dir = "org/apache/ctakes/gui/pipeline/icon/";
+ final String file = "BlueRightArrow.png";
+ final Icon icon = IconLoader.loadIcon( dir + file );
+ _arrowLabel.setIcon( icon );
+ }
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoComparator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoComparator.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoComparator.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoComparator.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,98 @@
+package org.apache.ctakes.gui.pipeline.bit.info;
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.EnumMap;
+import java.util.Map;
+
+import static org.apache.ctakes.core.pipeline.PipeBitInfo.Role.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/23/2016
+ */
+public enum PipeBitInfoComparator implements Comparator<PipeBitInfo> {
+ INSTANCE;
+
+ static public PipeBitInfoComparator getInstance() {
+ return INSTANCE;
+ }
+
+ static private final Map<PipeBitInfo.Role, Integer> ROLE_ORDER = new EnumMap<>( PipeBitInfo.Role.class );
+
+ static {
+ ROLE_ORDER.put( READER, 1 );
+ ROLE_ORDER.put( ANNOTATOR, 2 );
+ ROLE_ORDER.put( WRITER, 3 );
+ ROLE_ORDER.put( SPECIAL, 4 );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int compare( final PipeBitInfo info1, final PipeBitInfo info2 ) {
+ if ( info1.role() != info2.role() ) {
+ return compareByRole( info1, info2 );
+ }
+ final int depends = compareByDependency( info1, info2 );
+ if ( depends != 0 ) {
+ return depends;
+ }
+ final int usable = compareByMax( info1.usables(), info2.usables() );
+ if ( usable != 0 ) {
+ return usable;
+ }
+ return info1.name().compareTo( info2.name() );
+ }
+
+ static private int compareByRole( final PipeBitInfo info1, final PipeBitInfo info2 ) {
+ return ROLE_ORDER.get( info1.role() ) - ROLE_ORDER.get( info2.role() );
+ }
+
+ static private int compareByMax( final PipeBitInfo.TypeProduct[] types1, final PipeBitInfo.TypeProduct[] types2 ) {
+ final int max1 = Arrays.stream( types1 ).mapToInt( Enum::ordinal ).max().orElse( 0 );
+ final int max2 = Arrays.stream( types2 ).mapToInt( Enum::ordinal ).max().orElse( 0 );
+ return max1 - max2;
+ }
+
+ static private int compareBySum( final PipeBitInfo.TypeProduct[] types1, final PipeBitInfo.TypeProduct[] types2 ) {
+ final int sum1 = Arrays.stream( types1 ).mapToInt( Enum::ordinal ).sum();
+ final int sum2 = Arrays.stream( types2 ).mapToInt( Enum::ordinal ).sum();
+ return sum1 - sum2;
+ }
+
+ static private int compareByDependency( final PipeBitInfo info1, final PipeBitInfo info2 ) {
+ // The info with the lower dependency should go first
+ final int dependMax = compareByMax( info1.dependencies(), info2.dependencies() );
+ if ( dependMax != 0 ) {
+ return dependMax;
+ }
+ // The info with the lower production should go first
+ final int produceMax = compareByMax( info1.products(), info2.products() );
+ if ( produceMax != 0 ) {
+ return produceMax;
+ }
+ // The info with the lowest sum dependencies should go first
+ final int dependSum = compareBySum( info1.dependencies(), info2.dependencies() );
+ if ( dependSum != 0 ) {
+ return dependSum;
+ }
+ // The info with the lowest sum products should go first
+ final int produceSum = compareBySum( info1.products(), info2.products() );
+ if ( produceSum != 0 ) {
+ return produceSum;
+ }
+ // The info with the lower number of dependencies should go first
+ if ( info1.dependencies().length != info2.dependencies().length ) {
+ return info1.dependencies().length - info2.dependencies().length;
+ }
+ // The info with the lower number of products should go first
+ return info1.products().length - info2.products().length;
+ }
+
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoPanel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoPanel.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoPanel.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoPanel.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,90 @@
+package org.apache.ctakes.gui.pipeline.bit.info;
+
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.gui.pipeline.bit.BitInfoPanel;
+import org.apache.ctakes.gui.pipeline.bit.available.AvailablesListModel;
+import org.apache.ctakes.gui.pipeline.bit.parameter.DefaultParameterHolder;
+import org.apache.ctakes.gui.pipeline.bit.parameter.ParameterHolder;
+import org.apache.ctakes.gui.pipeline.bit.parameter.ParameterInfoPanel;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/5/2017
+ */
+final public class PipeBitInfoPanel extends BitInfoPanel {
+
+ static private final Logger LOGGER = Logger.getLogger( "PipeBitInfoPanel" );
+
+ public void setPipeBitInfoList( final JList<PipeBitInfo> pipeBitList ) {
+ pipeBitList.getSelectionModel().addListSelectionListener( new PipeBitListListener( pipeBitList ) );
+ }
+
+ @Override
+ protected String getNameLabelPrefix() {
+ return "Pipe";
+ }
+
+ @Override
+ protected JComponent createNameEditor() {
+ return new JLabel();
+ }
+
+ @Override
+ protected void setBitName( final String text ) {
+ ((JLabel)_name).setText( text );
+ }
+
+ @Override
+ protected ParameterInfoPanel createParameterInfoPanel() {
+ return new ParameterInfoPanel();
+ }
+
+
+ private void setPipeBit( final PipeBitInfo info, final Class<?> pipeBitClass ) {
+ if ( info == null ) {
+ clear();
+ return;
+ }
+ setBitName( info.name() );
+ _description.setText( info.description() );
+ _dependencies.setText( Arrays.stream( info.dependencies() )
+ .map( PipeBitInfo.TypeProduct::toString )
+ .collect( Collectors.joining( ", " ) ) );
+ _usables.setText( Arrays.stream( info.usables() )
+ .map( PipeBitInfo.TypeProduct::toString )
+ .collect( Collectors.joining( ", " ) ) );
+ _outputs.setText( Arrays.stream( info.products() )
+ .map( PipeBitInfo.TypeProduct::toString )
+ .collect( Collectors.joining( ", " ) ) );
+ final ParameterHolder holder = new DefaultParameterHolder( pipeBitClass );
+ _parameterTableModel.setParameterHolder( holder );
+ _parameterInfoPanel.setParameterHolder( holder );
+ }
+
+ private class PipeBitListListener implements ListSelectionListener {
+ private final JList<PipeBitInfo> __pipeBitList;
+
+ private PipeBitListListener( final JList<PipeBitInfo> pipeBitList ) {
+ __pipeBitList = pipeBitList;
+ }
+
+ @Override
+ public void valueChanged( final ListSelectionEvent event ) {
+ if ( event.getValueIsAdjusting() ) {
+ return;
+ }
+ final PipeBitInfo pipeBitInfo = __pipeBitList.getSelectedValue();
+ setPipeBit( pipeBitInfo, ((AvailablesListModel)__pipeBitList.getModel()).getPipeBit( pipeBitInfo ) );
+ }
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoRenderer.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoRenderer.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoRenderer.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/PipeBitInfoRenderer.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,109 @@
+package org.apache.ctakes.gui.pipeline.bit.info;
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.gui.component.CellRendererLabel;
+import org.apache.ctakes.gui.component.CellRendererPanel;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Arrays;
+import java.util.Objects;
+
+import static org.apache.ctakes.core.pipeline.PipeBitInfo.TypeProduct;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/24/2017
+ */
+final public class PipeBitInfoRenderer implements ListCellRenderer<Object> {
+
+ static private final Logger LOGGER = Logger.getLogger( "PipeBitInfoRenderer" );
+
+ static private final Color READER_COLOR = Color.GREEN.darker().darker();
+ static private final Color ANNOTATOR_COLOR = Color.CYAN.darker().darker();
+ static private final Color WRITER_COLOR = Color.BLUE;
+ static private final Color SPECIAL_COLOR = Color.MAGENTA.darker();
+
+ static private final LayoutManager EMPTY_LAYOUT = new GridLayout( 1, 1 );
+
+ private final JPanel _renderer = new CellRendererPanel( new BorderLayout( 5, 0 ) );
+ private final JPanel _dependencies = new CellRendererPanel( EMPTY_LAYOUT );
+ private final JLabel _textLabel = new CellRendererLabel();
+ private final JPanel _products = new CellRendererPanel( EMPTY_LAYOUT );
+
+
+ public PipeBitInfoRenderer() {
+ _dependencies.setBackground( null );
+ _textLabel.setBackground( null );
+ _products.setBackground( null );
+ _renderer.add( _dependencies, BorderLayout.WEST );
+ _renderer.add( _textLabel, BorderLayout.CENTER );
+ _renderer.add( _products, BorderLayout.EAST );
+ }
+
+ @Override
+ public Component getListCellRendererComponent(
+ final JList<?> list,
+ final Object value,
+ final int index,
+ final boolean isSelected,
+ final boolean cellHasFocus ) {
+ _dependencies.removeAll();
+ _products.removeAll();
+
+ if ( isSelected ) {
+ _renderer.setBackground( list.getSelectionBackground() );
+ _textLabel.setForeground( list.getSelectionForeground() );
+ } else {
+ _renderer.setBackground( list.getBackground() );
+ }
+ if ( !PipeBitInfo.class.isInstance( value ) ) {
+ LOGGER.error( value.getClass().getName() + " is not a PipeBitInfo" );
+ _dependencies.setLayout( EMPTY_LAYOUT );
+ _products.setLayout( EMPTY_LAYOUT );
+ _textLabel.setText( "Invalid" );
+ _renderer.setBackground( Color.DARK_GRAY );
+ _renderer.setToolTipText( "Invalid Information" );
+ return _renderer;
+ }
+ final PipeBitInfo info = (PipeBitInfo)value;
+
+ if ( !isSelected ) {
+ final Color color = getColor( info.role() );
+ _textLabel.setForeground( color );
+ }
+ _textLabel.setText( info.name() );
+
+ createTypeIcons( _dependencies, info.dependencies() );
+ createTypeIcons( _products, info.products() );
+
+ return _renderer;
+ }
+
+ static private Color getColor( final PipeBitInfo.Role role ) {
+ switch ( role ) {
+ case READER:
+ return READER_COLOR;
+ case ANNOTATOR:
+ return ANNOTATOR_COLOR;
+ case WRITER:
+ return WRITER_COLOR;
+ case SPECIAL:
+ return SPECIAL_COLOR;
+ }
+ return Color.GRAY;
+ }
+
+ static private void createTypeIcons( final JPanel panel, final TypeProduct... types ) {
+ panel.setLayout( new GridLayout( 1, types.length ) );
+ Arrays.stream( types )
+ .map( ProductIconFactory.getInstance()::getIcon )
+ .filter( Objects::nonNull )
+ .map( CellRendererLabel::new )
+ .forEach( panel::add );
+ }
+
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/ProductIconFactory.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/ProductIconFactory.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/ProductIconFactory.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/ProductIconFactory.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,79 @@
+package org.apache.ctakes.gui.pipeline.bit.info;
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.gui.util.ColorFactory;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.geom.GeneralPath;
+import java.awt.image.BufferedImage;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.Map;
+
+import static org.apache.ctakes.core.pipeline.PipeBitInfo.TypeProduct;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/25/2017
+ */
+public enum ProductIconFactory {
+ INSTANCE;
+
+ public static ProductIconFactory getInstance() {
+ return INSTANCE;
+ }
+
+
+ private final Map<TypeProduct, Icon> _typeProductIcons = new EnumMap<>( TypeProduct.class );
+
+ ProductIconFactory() {
+// SwingUtilities.invokeLater( new ProductIconMaker() );
+ new ProductIconMaker().run();
+ }
+
+ public Icon getIcon( final TypeProduct typeProduct ) {
+ return _typeProductIcons.get( typeProduct );
+ }
+
+ private final class ProductIconMaker implements Runnable {
+ private final Stroke LINE_STROKE = new BasicStroke( 4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND );
+ private final Font HINT_FONT = new Font( "Dialog", Font.BOLD, 12 );
+
+ @Override
+ public void run() {
+ Arrays.stream( PipeBitInfo.TypeProduct.values() )
+ .forEach( tp -> _typeProductIcons.put( tp, createIcon( tp ) ) );
+ }
+
+ private Icon createIcon( final PipeBitInfo.TypeProduct typeProduct ) {
+ final Image image = new BufferedImage( 20, 20, BufferedImage.TYPE_3BYTE_BGR );
+ final Graphics2D g2 = (Graphics2D)image.getGraphics();
+ g2.setColor( UIManager.getColor( "List.background" ) );
+ g2.fillRect( 0, 0, 20, 20 );
+
+ g2.setColor( Color.LIGHT_GRAY );
+ g2.drawOval( 2, 2, 17, 17 );
+
+ final String name = typeProduct.name();
+ final Color color = ColorFactory.getColor( name );
+ g2.setColor( ColorFactory.addTransparency( color, 159 ) );
+ g2.setFont( HINT_FONT );
+ g2.drawString( typeProduct.name().charAt( 0 ) + "", 4, 15 );
+
+ final GeneralPath linePath = new GeneralPath( GeneralPath.WIND_EVEN_ODD, 3 );
+ final int[] xArray = { 11, 17, 11 };
+ final int[] yArray = { 3, 9, 17 };
+ linePath.moveTo( xArray[ 0 ], yArray[ 0 ] );
+ for ( int i = 1; i < xArray.length; i++ ) {
+ linePath.lineTo( xArray[ i ], yArray[ i ] );
+ }
+ g2.setStroke( LINE_STROKE );
+ g2.draw( linePath );
+
+ return new ImageIcon( image );
+ }
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/RoleRenderer.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/RoleRenderer.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/RoleRenderer.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/RoleRenderer.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,97 @@
+package org.apache.ctakes.gui.pipeline.bit.info;
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.gui.component.CellRendererLabel;
+import org.apache.ctakes.gui.util.IconLoader;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/24/2017
+ */
+final public class RoleRenderer implements ListCellRenderer<Object> {
+
+ static private final Logger LOGGER = Logger.getLogger( "RoleRenderer" );
+
+ static private final String READER_ICON_FILE = "GreenArrowIn.png";
+ static private final String ANNOTATOR_ICON_FILE = "BlueGear.png";
+ static private final String WRITER_ICON_FILE = "BlueArrowOut.png";
+ static private final String SPECIAL_ICON_FILE = "Utilities.png";
+
+ private final JLabel _reader = new CellRendererLabel();
+ private final JLabel _annotator = new CellRendererLabel();
+ private final JLabel _writer = new CellRendererLabel();
+ private final JLabel _special = new CellRendererLabel();
+
+ public RoleRenderer() {
+ decorate( _reader );
+ decorate( _annotator );
+ decorate( _writer );
+ decorate( _special );
+ SwingUtilities.invokeLater( new RoleIconLoader() );
+ }
+
+ static private void decorate( final JLabel renderer ) {
+ final Color background = UIManager.getColor( "List.background" );
+ renderer.setBackground( background );
+ renderer.setBorder( new EmptyBorder( 0, 2, 0, 2 ) );
+ }
+
+ @Override
+ public Component getListCellRendererComponent(
+ final JList<?> list,
+ final Object value,
+ final int index,
+ final boolean isSelected,
+ final boolean cellHasFocus ) {
+ if ( !PipeBitInfo.class.isInstance( value ) ) {
+ LOGGER.error( value.getClass().getName() + " is not a PipeBitInfo" );
+ final JLabel renderer = new JLabel( "Invalid" );
+ renderer.setBackground( Color.DARK_GRAY );
+ renderer.setToolTipText( "Invalid Information" );
+ return renderer;
+ }
+ final PipeBitInfo info = (PipeBitInfo)value;
+ switch ( info.role() ) {
+ case READER:
+ return _reader;
+ case ANNOTATOR:
+ return _annotator;
+ case WRITER:
+ return _writer;
+ case SPECIAL:
+ return _special;
+ }
+ return new JLabel();
+ }
+
+ /**
+ * Simple Callable that loads and resizes an icon
+ */
+ private final class RoleIconLoader implements Runnable {
+ static private final int ICON_SIZE = 16;
+ static private final String ICON_DIR = "org/apache/ctakes/gui/pipeline/icon/";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ final Icon reader = IconLoader.loadIcon( ICON_DIR + READER_ICON_FILE, ICON_SIZE );
+ _reader.setIcon( reader );
+ final Icon annotator = IconLoader.loadIcon( ICON_DIR + ANNOTATOR_ICON_FILE, ICON_SIZE );
+ _annotator.setIcon( annotator );
+ final Icon writer = IconLoader.loadIcon( ICON_DIR + WRITER_ICON_FILE, ICON_SIZE );
+ _writer.setIcon( writer );
+ final Icon special = IconLoader.loadIcon( ICON_DIR + SPECIAL_ICON_FILE, ICON_SIZE );
+ _special.setIcon( special );
+ }
+ }
+
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductListModel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductListModel.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductListModel.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductListModel.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,65 @@
+package org.apache.ctakes.gui.pipeline.bit.info;
+
+import javax.swing.*;
+import javax.swing.event.ListDataListener;
+import java.util.logging.Logger;
+
+import static org.apache.ctakes.core.pipeline.PipeBitInfo.TypeProduct;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/25/2017
+ */
+final public class TypeProductListModel implements ListModel<TypeProduct> {
+
+ static private final Logger LOGGER = Logger.getLogger( "TypeProductListModel" );
+
+ private final TypeProduct[] _typeProducts;
+
+ public TypeProductListModel() {
+ _typeProducts = new TypeProduct[ TypeProduct.values().length - 1 ];
+ int i = 0;
+ for ( TypeProduct typeProduct : TypeProduct.values() ) {
+ if ( typeProduct != TypeProduct.TOP ) {
+ _typeProducts[ i ] = typeProduct;
+ i++;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getSize() {
+ return _typeProducts.length;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public TypeProduct getElementAt( final int index ) {
+ return _typeProducts[ index ];
+ }
+
+ /**
+ * does nothing.
+ *
+ * @param l -
+ */
+ @Override
+ public void addListDataListener( final ListDataListener l ) {
+ }
+
+ /**
+ * does nothing.
+ *
+ * @param l -
+ */
+ @Override
+ public void removeListDataListener( final ListDataListener l ) {
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductRenderer.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductRenderer.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductRenderer.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/info/TypeProductRenderer.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,54 @@
+package org.apache.ctakes.gui.pipeline.bit.info;
+
+
+import org.apache.ctakes.gui.component.CellRendererLabel;
+import org.apache.ctakes.gui.util.ColorFactory;
+import org.apache.log4j.Logger;
+
+import javax.swing.*;
+import java.awt.*;
+
+import static org.apache.ctakes.core.pipeline.PipeBitInfo.TypeProduct;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/25/2017
+ */
+final public class TypeProductRenderer implements ListCellRenderer<Object> {
+
+ static private final Logger LOGGER = Logger.getLogger( "TypeProductRenderer" );
+
+ private final JLabel _delegate = new CellRendererLabel();
+
+ public TypeProductRenderer() {
+ _delegate.setBackground( UIManager.getColor( "List.background" ) );
+ }
+
+ @Override
+ public Component getListCellRendererComponent(
+ final JList<?> list,
+ final Object value,
+ final int index,
+ final boolean isSelected,
+ final boolean cellHasFocus ) {
+ if ( !TypeProduct.class.isInstance( value ) ) {
+ LOGGER.error( value.getClass().getName() + " is not a TypeProduct" );
+ _delegate.setIcon( null );
+ _delegate.setText( "Invalid" );
+ _delegate.setToolTipText( "Invalid Information" );
+ return _delegate;
+ }
+
+ final TypeProduct typeProduct = (TypeProduct)value;
+ final Icon icon = ProductIconFactory.getInstance().getIcon( typeProduct );
+ _delegate.setIcon( icon );
+ final String name = typeProduct.name();
+ final Color color = ColorFactory.getColor( name );
+ _delegate.setForeground( color );
+ final String prettyName = name.charAt( 0 ) + name.substring( 1, name.length() );
+ _delegate.setText( prettyName );
+ return _delegate;
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/DefaultParameterHolder.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/DefaultParameterHolder.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/DefaultParameterHolder.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/DefaultParameterHolder.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,90 @@
+package org.apache.ctakes.gui.pipeline.bit.parameter;
+
+
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+import javax.annotation.concurrent.Immutable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/20/2017
+ */
+@Immutable
+final public class DefaultParameterHolder implements ParameterHolder {
+
+ static private final Logger LOGGER = Logger.getLogger( "DefaultParameterHolder" );
+
+ private final List<ConfigurationParameter> _parameters;
+ private final Map<ConfigurationParameter, String> _typeMap;
+
+ /**
+ * @param pipeBitClass -
+ */
+ public DefaultParameterHolder( final Class<?> pipeBitClass ) {
+ _typeMap = ParameterMapper.createParameterTypeMap( pipeBitClass );
+ _parameters = new ArrayList<>( _typeMap.keySet() );
+ _parameters.sort( ( p1, p2 ) -> p1.name().compareToIgnoreCase( p2.name() ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getParameterCount() {
+ return _parameters.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ConfigurationParameter getParameter( final int index ) {
+ return _parameters.get( index );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getParameterClass( final int index ) {
+ return _typeMap.get( getParameter( index ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getParameterName( final int index ) {
+ return _parameters.get( index ).name();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getParameterDescription( final int index ) {
+ return _parameters.get( index ).description();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isParameterMandatory( final int index ) {
+ return _parameters.get( index ).mandatory();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String[] getParameterValue( final int index ) {
+ return _parameters.get( index ).defaultValue();
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterCellRenderer.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterCellRenderer.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterCellRenderer.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterCellRenderer.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,33 @@
+package org.apache.ctakes.gui.pipeline.bit.parameter;
+
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+import javax.swing.*;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/20/2017
+ */
+final public class ParameterCellRenderer implements TableCellRenderer {
+
+ static private final Logger LOGGER = Logger.getLogger( "ParameterCellRenderer" );
+
+ private final TableCellRenderer _delegate = new DefaultTableCellRenderer();
+
+ public Component getTableCellRendererComponent( final JTable table, final Object value,
+ final boolean isSelected, final boolean hasFocus,
+ final int row, final int column ) {
+ final Component renderer = _delegate
+ .getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
+ if ( renderer instanceof JLabel && value instanceof ConfigurationParameter ) {
+ ((JLabel)renderer).setText( ((ConfigurationParameter)value).name() );
+ }
+ return renderer;
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterHolder.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterHolder.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterHolder.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterHolder.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,27 @@
+package org.apache.ctakes.gui.pipeline.bit.parameter;
+
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/20/2017
+ */
+public interface ParameterHolder {
+
+ int getParameterCount();
+
+ ConfigurationParameter getParameter( int index );
+
+ String getParameterClass( int index );
+
+ String getParameterName( int index );
+
+ String getParameterDescription( int index );
+
+ boolean isParameterMandatory( int index );
+
+ String[] getParameterValue( int index );
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterInfoPanel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterInfoPanel.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterInfoPanel.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterInfoPanel.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,137 @@
+package org.apache.ctakes.gui.pipeline.bit.parameter;
+
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/20/2017
+ */
+public class ParameterInfoPanel extends JPanel {
+
+ static private final Logger LOGGER = Logger.getLogger( "ParameterInfoPanel" );
+
+
+ private JLabel _name;
+ private JLabel _type;
+ private JLabel _description;
+ private JLabel _mandatory;
+ protected JComponent _values;
+
+ private ParameterHolder _holder;
+
+ public ParameterInfoPanel() {
+ super( new GridLayout( 5, 1 ) );
+
+ _name = new JLabel();
+ final JComponent namePanel = createNamePanel( "Parameter Name:", _name );
+ _type = new JLabel();
+ final JComponent typePanel = createNamePanel( "Parameter Type:", _type );
+ _description = new JLabel();
+ final JComponent descPanel = createNamePanel( "Description:", _description );
+ _mandatory = new JLabel();
+ final JComponent mandatoryPanel = createNamePanel( "Mandatory:", _mandatory );
+ _values = createValuesEditor();
+ final JComponent valuesPanel = createNamePanel( getValueLabelPrefix() + " Values:", _values );
+
+ add( namePanel );
+ add( typePanel );
+ add( descPanel );
+ add( mandatoryPanel );
+ add( valuesPanel );
+ }
+
+ protected String getValueLabelPrefix() {
+ return "Default";
+ }
+
+ protected JComponent createValuesEditor() {
+ return new JLabel();
+ }
+
+ protected void setParameterValues( final String values ) {
+ ((JLabel)_values).setText( values );
+ }
+
+ private JComponent createNamePanel( final String name, final JComponent namedLabel ) {
+ final JPanel panel = new JPanel( new BorderLayout( 10, 10 ) );
+ panel.setBorder( new EmptyBorder( 2, 10, 2, 10 ) );
+ final JLabel label = new JLabel( name );
+ label.setPreferredSize( new Dimension( 90, 20 ) );
+ label.setHorizontalAlignment( SwingConstants.TRAILING );
+ final Border emptyBorder = new EmptyBorder( 0, 10, 0, 0 );
+ final Border border
+ = new CompoundBorder( UIManager.getLookAndFeelDefaults().getBorder( "TextField.border" ), emptyBorder );
+ namedLabel.setBorder( border );
+ panel.add( label, BorderLayout.WEST );
+ panel.add( namedLabel, BorderLayout.CENTER );
+ return panel;
+ }
+
+ private void clear() {
+ _name.setText( "" );
+ _type.setText( "" );
+ _description.setText( "" );
+ _mandatory.setText( "" );
+ setParameterValues( "" );
+ }
+
+ public void setParameterHolder( final ParameterHolder holder ) {
+ _holder = holder;
+ clear();
+ }
+
+ private void setParameterIndex( final int index ) {
+ if ( index < 0 || _holder == null ) {
+ clear();
+ return;
+ }
+ _name.setText( _holder.getParameterName( index ) );
+ _type.setText( _holder.getParameterClass( index ) );
+ _description.setText( _holder.getParameterDescription( index ) );
+ _mandatory.setText( Boolean.toString( _holder.isParameterMandatory( index ) ) );
+ final String values = Arrays.stream( _holder.getParameterValue( index ) )
+ .filter( v -> !ConfigurationParameter.NO_DEFAULT_VALUE.equals( v ) )
+ .collect( Collectors.joining( " , " ) );
+ setParameterValues( values );
+ }
+
+ public void setParameterTable( final JTable parameterTable ) {
+ ListSelectionModel selectionModel = parameterTable.getSelectionModel();
+ selectionModel.addListSelectionListener( new ParameterTableListener( parameterTable ) );
+ }
+
+ private class ParameterTableListener implements ListSelectionListener {
+ private final JTable __parameterTable;
+
+ private ParameterTableListener( final JTable parameterTable ) {
+ __parameterTable = parameterTable;
+ }
+
+ @Override
+ public void valueChanged( final ListSelectionEvent event ) {
+ if ( event.getValueIsAdjusting() ) {
+ return;
+ }
+ final int[] selectedRows = __parameterTable.getSelectedRows();
+ if ( selectedRows.length == 0 ) {
+ setParameterIndex( -1 );
+ } else {
+ setParameterIndex( selectedRows[ 0 ] );
+ }
+ }
+ }
+
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterMapper.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterMapper.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterMapper.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterMapper.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,69 @@
+package org.apache.ctakes.gui.pipeline.bit.parameter;
+
+
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/19/2017
+ */
+final public class ParameterMapper {
+
+ static private final Logger LOGGER = Logger.getLogger( "ParameterMapper" );
+
+ private ParameterMapper() {
+ }
+
+ /**
+ * @param pipeBitClass -
+ * @return Configuration Parameters and Field class types for the Pipe Bit and all of its parent classes
+ */
+ static public Map<ConfigurationParameter, String> createParameterTypeMap( final Class<?> pipeBitClass ) {
+ final Map<ConfigurationParameter, String> parameterMap = new HashMap<>();
+ final Collection<Class<?>> inheritables = new ArrayList<>();
+ final Class<?>[] interfaces = pipeBitClass.getInterfaces();
+ if ( interfaces != null && interfaces.length > 0 ) {
+ inheritables.addAll( Arrays.asList( interfaces ) );
+ }
+ if ( pipeBitClass.getSuperclass() != null ) {
+ inheritables.add( pipeBitClass.getSuperclass() );
+ }
+ inheritables.stream().map( ParameterMapper::createParameterTypeMap ).forEach( parameterMap::putAll );
+ final Field[] fields = pipeBitClass.getDeclaredFields();
+ Arrays.stream( fields )
+ .filter( f -> f.getAnnotation( ConfigurationParameter.class ) != null )
+ .forEach( f -> parameterMap
+ .put( f.getAnnotation( ConfigurationParameter.class ), f.getType().getSimpleName() ) );
+ return parameterMap;
+ }
+
+
+ /**
+ * @param pipeBitClass -
+ * @return Configuration Parameters and default values for the Pipe Bit and all of its parent classes
+ */
+ static public Map<ConfigurationParameter, String[]> createParameterDefaultsMap( final Class<?> pipeBitClass ) {
+ final Map<ConfigurationParameter, String[]> parameterMap = new HashMap<>();
+ final Collection<Class<?>> inheritables = new ArrayList<>();
+ final Class<?>[] interfaces = pipeBitClass.getInterfaces();
+ if ( interfaces != null && interfaces.length > 0 ) {
+ inheritables.addAll( Arrays.asList( interfaces ) );
+ }
+ if ( pipeBitClass.getSuperclass() != null ) {
+ inheritables.add( pipeBitClass.getSuperclass() );
+ }
+ inheritables.stream().map( ParameterMapper::createParameterDefaultsMap ).forEach( parameterMap::putAll );
+ final Field[] fields = pipeBitClass.getDeclaredFields();
+ Arrays.stream( fields )
+ .map( f -> f.getAnnotation( ConfigurationParameter.class ) )
+ .filter( Objects::nonNull )
+ .forEach( cp -> parameterMap.put( cp, cp.defaultValue() ) );
+ return parameterMap;
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterTableModel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterTableModel.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterTableModel.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/parameter/ParameterTableModel.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,157 @@
+package org.apache.ctakes.gui.pipeline.bit.parameter;
+
+
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+import javax.swing.event.EventListenerList;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.TableModel;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/5/2017
+ */
+final public class ParameterTableModel implements TableModel {
+
+ static private final Logger LOGGER = Logger.getLogger( "ParameterTableModel" );
+
+ static private final String[] COLUMN_NAMES = { "Parameter Name", "Value" };
+ static private final Class<?>[] COLUMN_CLASSES = { ConfigurationParameter.class, String[].class };
+
+ private final EventListenerList _listenerList = new EventListenerList();
+
+ private ParameterHolder _parameterHolder;
+
+ /**
+ * Populate the list
+ *
+ * @param holder - holder with all parameter information
+ */
+ public void setParameterHolder( final ParameterHolder holder ) {
+ final int oldSize = _parameterHolder == null ? 0 : _parameterHolder.getParameterCount();
+ _parameterHolder = holder;
+ if ( holder == null ) {
+ if ( oldSize > 0 ) {
+ fireTableChanged(
+ new TableModelEvent( this, 0, oldSize - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE ) );
+ }
+ return;
+ }
+ if ( holder.getParameterCount() > 0 ) {
+ fireTableChanged( new TableModelEvent( this ) );
+ } else if ( oldSize > 0 ) {
+ fireTableChanged(
+ new TableModelEvent( this, 0, oldSize - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE ) );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getRowCount() {
+ if ( _parameterHolder == null ) {
+ return 0;
+ }
+ return _parameterHolder.getParameterCount();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getColumnCount() {
+ return COLUMN_NAMES.length;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getColumnName( final int columnIndex ) {
+ return COLUMN_NAMES[ columnIndex ];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class<?> getColumnClass( final int columnIndex ) {
+ return COLUMN_CLASSES[ columnIndex ];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isCellEditable( final int rowIndex, final int columnIndex ) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValueAt( final int rowIndex, final int columnIndex ) {
+ switch ( columnIndex ) {
+ case 0:
+ return _parameterHolder.getParameter( rowIndex );
+ case 1:
+ return Arrays.stream( _parameterHolder.getParameterValue( rowIndex ) )
+ .filter( v -> !ConfigurationParameter.NO_DEFAULT_VALUE.equals( v ) )
+ .collect( Collectors.joining( " , " ) );
+ }
+ return "ERROR";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValueAt( final Object aValue, final int rowIndex, final int columnIndex ) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addTableModelListener( final TableModelListener listener ) {
+ _listenerList.add( TableModelListener.class, listener );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeTableModelListener( final TableModelListener listener ) {
+ _listenerList.remove( TableModelListener.class, listener );
+ }
+
+ /**
+ * Forwards the given notification event to all
+ * <code>TableModelListeners</code> that registered
+ * themselves as listeners for this table model.
+ *
+ * @param event the event to be forwarded
+ * @see #addTableModelListener
+ * @see TableModelEvent
+ * @see EventListenerList
+ */
+ private void fireTableChanged( final TableModelEvent event ) {
+ // Guaranteed to return a non-null array
+ Object[] listeners = _listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for ( int i = listeners.length - 2; i >= 0; i -= 2 ) {
+ if ( listeners[ i ] == TableModelListener.class ) {
+ ((TableModelListener)listeners[ i + 1 ]).tableChanged( event );
+ }
+ }
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/DefaultUserBit.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/DefaultUserBit.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/DefaultUserBit.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/DefaultUserBit.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,137 @@
+package org.apache.ctakes.gui.pipeline.bit.user;
+
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.gui.pipeline.bit.parameter.ParameterMapper;
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/19/2017
+ */
+final public class DefaultUserBit implements UserBit {
+
+ static private final Logger LOGGER = Logger.getLogger( "DefaultUserBit" );
+
+ private final PipeBitInfo _pipeBitInfo;
+ private final Class<?> _pipeBitClass;
+ private String _name;
+ private final List<ConfigurationParameter> _parameters;
+ private final Map<ConfigurationParameter, String> _typeMap;
+ private final Map<ConfigurationParameter, String[]> _parameterValues;
+
+ public DefaultUserBit( final PipeBitInfo pipeBitInfo, final Class<?> pipeBitClass ) {
+ _pipeBitInfo = pipeBitInfo;
+ _pipeBitClass = pipeBitClass;
+ _typeMap = ParameterMapper.createParameterTypeMap( pipeBitClass );
+ _parameterValues = ParameterMapper.createParameterDefaultsMap( pipeBitClass );
+ _parameters = new ArrayList<>( _typeMap.keySet() );
+ _parameters.sort( ( p1, p2 ) -> p1.name().compareToIgnoreCase( p2.name() ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getBitName() {
+ if ( _name == null || _name.isEmpty() ) {
+ return _pipeBitInfo.name();
+ }
+ return _name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setBitName( final String name ) {
+ _name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public PipeBitInfo getPipeBitInfo() {
+ return _pipeBitInfo;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class<?> getPipeBitClass() {
+ return _pipeBitClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getParameterCount() {
+ return _parameters.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ConfigurationParameter getParameter( final int index ) {
+ return _parameters.get( index );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getParameterClass( final int index ) {
+ return _typeMap.get( getParameter( index ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getParameterName( final int index ) {
+ return _parameters.get( index ).name();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getParameterDescription( final int index ) {
+ return _parameters.get( index ).description();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isParameterMandatory( final int index ) {
+ return _parameters.get( index ).mandatory();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String[] getParameterValue( final int index ) {
+ return _parameterValues.get( getParameter( index ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setParameterValue( final int index, final String... values ) {
+ _parameterValues.put( getParameter( index ), values );
+ }
+
+}
Added: ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/UserBit.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/UserBit.java?rev=1788936&view=auto
==============================================================================
--- ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/UserBit.java (added)
+++ ctakes/trunk/ctakes-gui/src/main/java/org/apache/ctakes/gui/pipeline/bit/user/UserBit.java Mon Mar 27 14:37:44 2017
@@ -0,0 +1,39 @@
+package org.apache.ctakes.gui.pipeline.bit.user;
+
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.gui.pipeline.bit.parameter.ParameterHolder;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/20/2017
+ */
+public interface UserBit extends ParameterHolder {
+
+ /**
+ * @return Human-readable name of the Reader, Annotator, or Writer
+ */
+ String getBitName();
+
+ /**
+ * @param name Human-readable name of the Reader, Annotator, or Writer
+ */
+ void setBitName( String name );
+
+ /**
+ * @return PipeBitInfo associated with this UserBit
+ */
+ PipeBitInfo getPipeBitInfo();
+
+ /**
+ * @return Reader, AE, Writer associated with this UserBit
+ */
+ Class<?> getPipeBitClass();
+
+ /**
+ * @param index -
+ * @param values User Values for Configuration parameter at index
+ */
+ void setParameterValue( int index, String... values );
+
+}