Package cli_fmw.utils.intelliwriter

Source Code of cli_fmw.utils.intelliwriter.IntelliWriter$DocListener

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package cli_fmw.utils.intelliwriter;

import cli_fmw.delegate.directory.complex.DirectoryIntelliWriter;
import cli_fmw.delegate.directory.complex.DirectoryLocator;
import cli_fmw.delegate.directory.simple.DirectorySimpleItem;
import cli_fmw.delegate.directory.simple.iwtype.DirectoryIWTypeItemAbstract;
import cli_fmw.main.ClipsException;
import cli_fmw.utils.MessageBox;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowStateListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;

/**
* Объект, управляющий текстовым контролом, списком контекстного меню и окном
* контекстного меню.
* Посылает в контекстное меню список строк меню,
* команды для его отображения и скрытия меню,
* клавиши нажатые в контроле (стрелки, энтер, эскейп и тд)
* @author axe
*/
public class IntelliWriter implements TextController {
    private static final HashSet<Character> SEPARATORS;

    static {
        SEPARATORS = new HashSet<Character>();
        SEPARATORS.add('.');
        SEPARATORS.add('\n');
        SEPARATORS.add(';');
    }
   
    private Set<String> rows;
    private WordMenuWindow contextHelper;
    private JTextComponent component;
    private Window owner;
    private DocListener dl;

    /**
     * конструктор
     * @param type тип справочника вспомогательный текстов
     * @param owner окно, являющееся родительским по отношению к всплывающему списку
     * @param textComponent компонент, ввод которго контролирует intelliwriter
     * @throws ClipsException
     */
    public IntelliWriter(DirectoryIWTypeItemAbstract type, JFrame owner, JTextComponent textComponent)
            throws ClipsException {
        this(DirectoryLocator.getDirectory(DirectoryIntelliWriter.class, false).getItems(type),
                owner, textComponent);
    }
   
    /**
     * конструктор
     * @param strings набор строк
     * @param owner окно, являющееся родительским по отношению к всплывающему списку
     * @param textComponent компонент, ввод которго контролирует intelliwriter
     */
    public IntelliWriter(Set<String> strings, JFrame owner, JTextComponent textComponent) {
        this.owner = owner;
        component = textComponent;
        contextHelper = new WordMenuWindow(owner, this);
        this.rows = strings;
        dl= new DocListener();

        setEventManagement();
    }
   
    /**
     *
     */
    private void setEventManagement() {
        /*
         component.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                component.requestFocus();
            }
        });*/
       
        component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, InputEvent.CTRL_MASK), "home");
        component.getActionMap().put("home", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(contextHelper.isVisible()) {
                    contextHelper.moveStart();
                }
            }
        });

        component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_END, InputEvent.CTRL_MASK), "end");
        component.getActionMap().put("end", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(contextHelper.isVisible()) {
                    contextHelper.moveEnd();
                }
            }
        });

        component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), "controlEspace");
        component.getActionMap().put("controlEspace", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showMenu(component.getDocument(), component.getCaretPosition());
            }
        });
       
        component.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.isConsumed()) {
                    return;
                }
                if (contextHelper.isVisible()) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        contextHelper.forceSelect();
                        contextHelper.clearRollbackHistory();
                        System.err.println("VK_ENTER");
                        e.consume();
                    } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                        contextHelper.setVisible(false);
                        contextHelper.clearRollbackHistory();
                        System.err.println("VK_ESCAPE");
                        e.consume();
                    } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                        contextHelper.moveDown();
                        System.err.println("VK_DOWN");
                        e.consume();
                    } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                        contextHelper.moveUp();
                        System.err.println("VK_UP");
                        e.consume();
                    } else if (e.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
                        contextHelper.movePageDown();
                        System.err.println("VK_PAGE_DOWN");
                        e.consume();
                    } else if (e.getKeyCode() == KeyEvent.VK_PAGE_UP) {
                        contextHelper.movePageUp();
                        System.err.println("VK_PAGE_UP");
                        e.consume();
                    else if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        contextHelper.wordCommit();
                        e.consume();
                    else if(e.getKeyCode() == KeyEvent.VK_LEFT) {
                        contextHelper.wordRollback();
                        e.consume();
                    }
                }
            }
           
        });

        component.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                hideMenu();
            }
        });

       
        component.getDocument().addDocumentListener(dl);       
       
        if(owner != null) {
            owner.addComponentListener(new ComponentAdapter() {
                @Override
                public void componentHidden(ComponentEvent e) {
                    hideMenu();
                }
                @Override
                public void componentMoved(ComponentEvent e) {
                    if (contextHelper.isVisible()) {
                        Point point = getMenuPosition();
                        if(point != null) {
                            contextHelper.onMove(point);
                        } else {
                            hideMenu();
                        }
                    }
                }
            });
           
            owner.addWindowFocusListener(new WindowFocusListener() {

                @Override
                public void windowGainedFocus(WindowEvent e) {
                    //do nothing
                }

                @Override
                public void windowLostFocus(WindowEvent e) {
                    hideMenu();
                }
            });
        }

        component.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) {
                //do nothing
            }

            public void focusLost(FocusEvent e) {
                hideMenu();
            }
        });
    }

    class DocListener implements DocumentListener {
        @Override
        public void insertUpdate(DocumentEvent e) {
            showMenu(e.getDocument(), e.getOffset() + e.getLength());
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            showMenu(e.getDocument(), e.getOffset());
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
        }
    }

    /**
     *
     * @param mask
     * @return
     */
    private List<String> getMatchSentences(String mask) {
        //sentence = sentence.toLowerCase();
        ArrayList<String> returnSet = new ArrayList<String>();
        Iterator<String> iterator = rows.iterator();
        while(iterator.hasNext()) {
            String string = iterator.next();
            if (string.length() != mask.length()
                    && string.startsWith(mask)
                    ) {
                returnSet.add(string.substring(mask.length()));
            }
        }
        return returnSet;
    }

    private static boolean isSentenceSeparator(char aChar) {
        return SEPARATORS.contains(aChar);
    }

  
    public void hideMenu() {
        if(contextHelper.isVisible()) {
            contextHelper.setVisible(false);
            contextHelper.clearRollbackHistory();
        }           
    }

    /**
     * Displays menu
     * @param currentSentence
     */
    private void showMenu(Document doc, int pos) {
        try {
            String txt = doc.getText(0, pos);
            String currentSentence = getCurrentSentence(txt);
            if (contextHelper.isVisible()) {
                hideMenu();
            }
            List<String> words = getMatchSentences(currentSentence);
            if (words.size() > 0) {
                contextHelper.setWords(words);
                Point point = getMenuPosition();
                if (point == null) {
                    return;
                }
                contextHelper.display(point);
                component.requestFocus();
            } else {
              hideMenu();
            }
        } catch (Exception ex) {
            hideMenu();
            ex.printStackTrace();
        }
    }

    /**
     *
     * @return preferred position for drop-down menu
     * (much close as possible to caret)
     */
    private Point getMenuPosition() {
        int index = component.getCaretPosition();
        Rectangle rect = null;
        try {
            rect = component.getUI().modelToView(component, index);
        } catch (BadLocationException e) {
        }
        if (rect == null) {
            return null;
        }

        Point origin = component.getLocationOnScreen();
        origin.x += rect.x;
        origin.y += rect.y + rect.height;
       
        Dimension ss = Toolkit.getDefaultToolkit().getScreenSize();
        if(origin.x + contextHelper.getWidth() > ss.getWidth()) {
            origin.x = (int) (ss.getWidth() - contextHelper.getWidth());
        }
        if(origin.y + contextHelper.getHeight() > ss.getHeight()) {
            origin.y = (int) (ss.getHeight() - contextHelper.getHeight());
        }

        if(origin.x < 0) {
            origin.x = 0;
        }
        if(origin.y < 0) {
            origin.y = 0;
        }


        return origin;
    }

    private String getCurrentSentence(String txt) {
        int index = txt.length()-1;
        if(index < 0) {
            return new String();
        }

        boolean found = false;
        while ((index > 0) && (!found)) {
            char current = txt.charAt(index);
           
            if (isSentenceSeparator(current)) {
                found = true;
                index++;
            } else {
                index--;
            }
        }
        String sen = txt.substring(index);
        sen = sen.replaceAll(" +", " ");
       
        return sen;
    }

    public void insertString(String str) {
        component.getDocument().removeDocumentListener(dl);
        try {
            hideMenu();
            int pos = component.getCaretPosition();
            Document doc = component.getDocument();
            doc.insertString(pos, str, null);
            showMenu(doc, pos + str.length());
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }       
        component.getDocument().addDocumentListener(dl);
    }

    public void removeCharacters(int count) {
        component.getDocument().removeDocumentListener(dl);
        try {
            hideMenu();
            int pos = component.getCaretPosition() - count;
            Document doc = component.getDocument();
            doc.remove(pos, count);
            showMenu(doc, pos);
        } catch (BadLocationException ex) {
            MessageBox.showException(ex);
        }
        component.getDocument().addDocumentListener(dl);
    }
}
TOP

Related Classes of cli_fmw.utils.intelliwriter.IntelliWriter$DocListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.