ListDataIntelliHints - Popup list shows only once

This is the forum for JIDE Common Layer which is open sourced at https://github.com/jidesoft/jide-oss. Please note, JIDE technical support doesn't monitor this forum as often as other forums. Please consider subscribe for technical support for JIDE Common Layer so that you can use customer only forum to get a timely response.

Moderator: JIDE Support

Forum rules
Community driven forum for open source JIDE Common Layer. JIDE technical support doesn't monitor this forum as often as other forums. If you only use JIDE Common Layer, please consider subscribing for technical support for JIDE Common Layer so that you can use customer only forum to get a timely response.

ListDataIntelliHints - Popup list shows only once

Postby lukasz.antoniak » Mon Dec 10, 2007 4:02 am

Hi,

I am trying to implement simple intelli-sense. In my case ListDataIntelliHints looks quite good - I do not need special cell renderer. I am trying to do some tests like:
Code: Select all
list.add("Paula");
list.add("Paulo");
list.add("Peru");
ListDataIntelliHints intelliHints = new ListDataIntelliHints(textPane, list);
where textPane is JTextPane.

This works but it shows intelli-hints only once at the beginning. How can I extend it on the whole document? Should I override some JTextPane action listeners?
lukasz.antoniak
 
Posts: 3
Joined: Fri Nov 30, 2007 12:49 pm

Postby JIDE Support » Mon Dec 10, 2007 11:00 am

Since IntelliHint is open sourced, you can look at the code and find out why it is not working. I guess that's because by default ListDataIntelliHints is for JTextField. You would need to customize it to make it working for JTextPane. Refer to FileIntelliHints for an example. The important method is updateHints. The return of this method will determine if the hints will be displayed.

Thanks,
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am

Postby lukasz.antoniak » Mon Jan 21, 2008 6:20 pm

I have found your advice very helpful. I have changed updateHints method to:
Code: Select all
    public boolean updateHints(Object context) {
        if (context == null) {
            return false;
        }
       
        String s = context.toString();
        s = s.substring(0, getTextComponent().getCaretPosition());
        int indexSpace = s.lastIndexOf(" ");
        int indexNewLine = s.lastIndexOf("\n");
        int indexTab = s.lastIndexOf("\t");
        int index = java.lang.Math.max(indexSpace, indexNewLine);
        index = java.lang.Math.max(index, indexTab);
        if (index != -1)
        {
           s = s.substring(index + "\n".length());
        }
        int substringLen = s.length();
        if (substringLen == 0) {
            return false;
        }

        List<String> possibleStrings = new ArrayList<String>();
        for (Object o : getCompletionList()) {
            String listEntry = (String) o;
            if (substringLen > listEntry.length())
                continue;

            if (!isCaseSensitive()) {
                if (s.equalsIgnoreCase(listEntry.substring(0, substringLen)))
                    possibleStrings.add(listEntry);
            }
            else if (listEntry.startsWith(s))
                possibleStrings.add(listEntry);
        }

        Object[] objects = possibleStrings.toArray();
        setListData(objects);
        return objects.length > 0;
    }
It works fine when I input data to my JTextField from keyboard.
When I want to read a file from a hard drive, I create new JTextField, active intellihints (like in manual) and read it line by line (for some reason).
Code: Select all
    try {
       FileInputStream fstream = new FileInputStream(filePath);
       DataInputStream in = new DataInputStream(fstream);
       BufferedReader br = new BufferedReader(new InputStreamReader(in));
       String strLine;
       int offset = 0;
       while ((strLine = br.readLine()) != null)
       {
          tabEl.getTextPane().getDocument().insertString(offset, strLine + "\n", null);
          offset += strLine.length() + 1;
       }
       in.close();
    } catch (Exception e) {
       System.out.println("Error while reading file.");
       e.printStackTrace();
    }
When I want to add some text (anywhere in the document), the "s" variable does not contain the appropriate value. It seams to me that getCaretPosition does not work correct.

What do you think could go wrong?

If you would like any screen-shots or more details please reply.
lukasz.antoniak
 
Posts: 3
Joined: Fri Nov 30, 2007 12:49 pm

Postby JIDE Support » Mon Jan 21, 2008 6:30 pm

Can you include a complete test case so that it is easy for me to run and see it?

Thanks,
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am

Postby cool_cool » Thu Jul 24, 2008 4:07 am

How can I show intellihints only when i pressed Ctrl+space in a JEditorPane?
cool_cool
 
Posts: 6
Joined: Thu Jul 24, 2008 3:27 am

Postby cool_cool » Thu Jul 24, 2008 4:36 am

Why the location of the popup menu is always in the beginning of each line. How can I set it to the cursor location?
Thank you very much.[/code]
cool_cool
 
Posts: 6
Joined: Thu Jul 24, 2008 3:27 am

Postby JIDE Support » Thu Jul 24, 2008 6:36 am

Override getShowHintsKeyStroke and only return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK).

setFollowCaret(true).

Thanks,
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am

Postby cool_cool » Thu Jul 24, 2008 8:12 am

Please help me for the Intellihints popup menu. I have modify it, but it doesn't work. I would like to develop a code completion like eclipse IDE. I can develop special render for JList, but the popup menu doesn't work with normal JList.
Requirement:
1. popup menu will appear anywhere in the text editor as long as Ctrl+Space is pressed.
2. if it is a blank space before the cusor, popup menu will appear and show all its content.

The following is my code:
Code: Select all
package xmleditor;

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.text.JTextComponent;

import com.jidesoft.hints.AbstractListIntelliHints;
import com.jidesoft.swing.SelectAllUtils;

public class Intellisense extends AbstractListIntelliHints {
  private List<String> cList;

  public Intellisense(JTextComponent comp) {
    super(comp);
  }

  public void setCompletionList(String[] array) {
    cList = new ArrayList<String>();
    for (String s : array) {
      cList.add(s);
    }
  }

  // *******************************************************************************//
  @Override
  protected JList createList() {
    String str[] = { "a", "ab", "abcd", "abcde", "abcedf", "Test str" };
    setCompletionList(str);
    JList listUI = new JList(str) {
      @Override
      public int getVisibleRowCount() {
        int size = getModel().getSize();
        return size < super.getVisibleRowCount() ? size : super.getVisibleRowCount();
      }

      @Override
      public Dimension getPreferredScrollableViewportSize() {
        if (getModel().getSize() == 0) {
          return new Dimension(0, 0);
        } else {
          return super.getPreferredScrollableViewportSize();
        }
      }
    };
    return listUI;
  }

  int lastEnterIndex = -1;

  public boolean updateHints(Object context) {
    if (context == null) {
      return false;
    }
    if (context.equals("")) {
      return updateHints1(context);
    }

    String contentText = context.toString();
    JTextComponent tc = getTextComponent();
    String editorText = tc.getText();

    int currentCaret = tc.getCaretPosition();
    lastEnterIndex = editorText.lastIndexOf('\n', currentCaret);
    int lineBeginCaret = 0;
    if (lastEnterIndex != -1) {
      int enterNum = getAppearNumber(editorText, '\n');
      lineBeginCaret = lastEnterIndex - (enterNum - 1);
    }

    int index = currentCaret - lineBeginCaret - 1;
    boolean found = false;

    while ((index > -1) && (!found)) {
      char current = contentText.charAt(index);
      if (current == ' ') {
        found = true;
        if (index == currentCaret - 1) {
          return false; // blank space - nothing happens
        }
      } else {
        index--;
      }
    }

    if (index == -1)
      index = 0;

    if (found) {
      String sub = contentText.substring(index + 1, contentText.length());
      return updateHints1(sub);
    } else {
      return updateHints1(context);
    }
  }

  public boolean updateHints1(Object context) {
    if (context == null) {
      return false;
    }
    String s = context.toString();
    int substringLen = s.length();
    List<String> possibleStrings = new ArrayList<String>();
    for (String listEntry : cList) {
      if (s.length() == 0) {
        // if "", add all
        possibleStrings.add(listEntry);
      } else {
        if (substringLen > listEntry.length())
          continue;
        String tmp = listEntry.substring(0, substringLen);
        if (s.equalsIgnoreCase(tmp)) {
          possibleStrings.add(listEntry);
        }
      }
    }

    setListData(possibleStrings.toArray());
    return possibleStrings.size() > 0;
  }

  public int getAppearNumber(String s, char c) {
    int i = 0;

    int index;
    while ((index = s.indexOf(c)) != -1) {
      i++;
      s = s.substring(index + 1, s.length());
    }
    return i;
  }

  protected KeyStroke getShowHintsKeyStroke() {
    return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK);
  }

  public static void main(String[] args) throws Exception {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    final JFrame frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JEditorPane textArea = new JEditorPane();
    SelectAllUtils.install(textArea);

    @SuppressWarnings("unused")
    Intellisense intellihints = new Intellisense(textArea);
    frame.setContentPane(textArea);
    frame.setSize(500, 500);
    frame.setVisible(true);

  }
}
Last edited by cool_cool on Thu Jul 24, 2008 8:17 am, edited 2 times in total.
cool_cool
 
Posts: 6
Joined: Thu Jul 24, 2008 3:27 am

Postby cool_cool » Thu Jul 24, 2008 8:13 am

where to write function: setFollowCaret(true)?
Thank you very much
cool_cool
 
Posts: 6
Joined: Thu Jul 24, 2008 3:27 am

Postby JIDE Support » Thu Jul 24, 2008 8:20 am

Constructor should be a good place to put that.
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am

Postby JIDE Support » Thu Jul 24, 2008 3:56 pm

The reason not working is because you have StringIndexOutOfBoundsException in your code at updateHints. If you fix, it will work.

Code: Select all
Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 6
   at java.lang.String.charAt(String.java:687)
   at Intellisense.updateHints(Intellisense.java:76)
   at com.jidesoft.hints.AbstractIntelliHints.showHints(AbstractIntelliHints.java:202)
   at com.jidesoft.hints.AbstractIntelliHints.showHintsPopup(AbstractIntelliHints.java:193)
   at com.jidesoft.hints.AbstractIntelliHints$6.delegateActionPerformed(AbstractIntelliHints.java:459)
   at com.jidesoft.swing.DelegateAction.actionPerformed(DelegateAction.java:53)
   at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
..


Thanks,
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am

Postby cool_cool » Fri Jul 25, 2008 1:18 am

Sorry, I cannot fix it, because this exception comes from updateHints(), and this function doesn't for the popup menu in the whole document, it works only for JTextfield. I will appreciate it that you can help me to get it. Or I can pay for it.
cool_cool
 
Posts: 6
Joined: Thu Jul 24, 2008 3:27 am

Postby JIDE Support » Fri Jul 25, 2008 10:14 am

The exception is really in your code (updateHints is your code now as you wrote it) so you should be able to fix it yourself. If you really don't want to bother with it, you may buy some consulting hours from us so that we can troubleshooting it for you.

Thanks,
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am

Postby cool_cool » Mon Jul 28, 2008 11:07 am

how to buy consulting hourse? how much is it?
cool_cool
 
Posts: 6
Joined: Thu Jul 24, 2008 3:27 am

Postby JIDE Support » Mon Jul 28, 2008 11:48 am

Please email sales at jidesoft.com and ask for consulting service pricing.

Thanks,
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am

Postby JIDE Support » Tue Jul 29, 2008 5:39 pm

I took a look at your code just now as I had a few spare minutes. As I anticipated, it is an obvious logic error in your own code. See my fix below. I hope you could spend more time debugging yourself instead of blaming IntelliHint not support JEditorPane.

Just replace

Code: Select all
    if (lastEnterIndex != -1) {
      int enterNum = getAppearNumber(editorText, '\n');
      lineBeginCaret = lastEnterIndex - (enterNum - 1);
    }

with

Code: Select all
     if (lastEnterIndex != -1) {
         lineBeginCaret = lastEnterIndex + 1;
    }


We do provide consulting services but our customers usually use it for component design idea or new feature etc. We don't really want to fix small bugs for you as you are supposed to do it yourself.

Thanks,
JIDE Software Technical Support Team
JIDE Support
Site Admin
 
Posts: 37219
Joined: Sun Sep 14, 2003 10:49 am


Return to JIDE Common Layer Open Source Project Discussion (Community Driven)

Who is online

Users browsing this forum: No registered users and 54 guests