JBuilder中的代码补齐,可以自动弹出浮动在界面上的小窗口,方法或者变量的提示,还带着滚动条,请问用Swing怎么来做这个呢?有什么建议吗?

解决方案 »

  1.   

    Swing 估计有难度, 因为你很难让弹出提示保持在前面,而让输入光标焦点在后面的文本域里SWT 倒是可以
      

  2.   

    import java.awt.*;
    import java.awt.event.*;import javax.swing.*;
    import javax.swing.plaf.TextUI;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.JTextComponent;public class PopupHint {
    private static String[] choice = {
    "black", "white", "red", "blue",
    "green", "yellow", "orange", "cyan",
    "magenta", "gray"};

    private JWindow popupWindow = null;
    private JLabel titleLabel = new JLabel("Colors", JLabel.CENTER);
    private JList choiceList = new JList(new DefaultListModel());
    private JScrollPane scrollPane = new JScrollPane(choiceList);

    private JTextComponent textComponent = null; private String filterStr = ""; 

    public PopupHint(JTextComponent textComponent) {
    this.scrollPane.setBorder(null);
    this.titleLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.black)); this.textComponent = textComponent;
    this.textComponent.addKeyListener(new KeyHandler());
    this.textComponent.addFocusListener(new FocusHandler());
    this.choiceList.addMouseListener(new MouseHandler());
    }

    public void showPopup() {
    try {
    if (popupWindow == null) {
    createPopupWindow();
    } updateList(); choiceList.setSelectedIndex(0);
    choiceList.ensureIndexIsVisible(0); TextUI textui = textComponent.getUI();
    Rectangle rect = textui.modelToView(textComponent, textComponent.getCaretPosition());
    Point point = new Point(rect.x, rect.y + rect.height);
    SwingUtilities.convertPointToScreen(point, textComponent);
    popupWindow.setLocation(point);
    popupWindow.setVisible(true);
    } catch (BadLocationException e) {
    e.printStackTrace();
    }
    } private void updatePopupPosition()
    {
    try {
    TextUI textui = textComponent.getUI();
    Rectangle rect = textui.modelToView(textComponent, textComponent.getCaretPosition());
    Point point = new Point(rect.x, rect.y + rect.height);
    SwingUtilities.convertPointToScreen(point, textComponent);
    popupWindow.setLocation(point);
    } catch (BadLocationException e) {
    e.printStackTrace();
    }
    }

    private void createPopupWindow()
    {
    popupWindow = new JWindow(SwingUtilities.getWindowAncestor(this.textComponent)); popupWindow.getContentPane().add(titleLabel, BorderLayout.NORTH);
    popupWindow.getContentPane().add(scrollPane, BorderLayout.CENTER); popupWindow.setSize(100, 100);
    ((JComponent) popupWindow.getContentPane()).setBorder(
    BorderFactory.createLineBorder(Color.black)); choiceList.setFocusable(false);
    scrollPane.setFocusable(false);
    scrollPane.getVerticalScrollBar().setFocusable(false);
    scrollPane.getHorizontalScrollBar().setFocusable(false);
    } private void addFilterChar(char keyChar)
    {
    this.filterStr += keyChar;
    updateList();
    } private void backspace()
    {
    if (filterStr.length() > 0) {
    filterStr = filterStr.substring(0, filterStr.length() - 1);
    updateList();
    }
    else {
    closePopup();
    }
    } private void updateList()
    {
    DefaultListModel listModel = (DefaultListModel) choiceList.getModel();
    listModel.clear(); for (int i = 0; i < choice.length; i++) {
    if (filterStr.equals("") || choice[i].startsWith(filterStr)) {
    listModel.addElement(choice[i]);
    }
    }
    if (listModel.getSize() > 0) {
    choiceList.setSelectedIndex(0);
    }
    else {
    closePopup();
    }
    }  private void processKey(KeyEvent ke) {
       if (popupWindow == null || !popupWindow.isShowing()) {
       return;
       }    boolean flag = true;
        if (ke.getKeyCode() == KeyEvent.VK_LEFT || ke.getKeyCode() == KeyEvent.VK_RIGHT) {
         flag = true;
         closePopup();
        }
        else if (ke.getKeyCode() == KeyEvent.VK_UP || ke.getKeyCode() == KeyEvent.VK_DOWN) {
         flag = true;
         choiceList.dispatchEvent(ke);
        } 
        else if (ke.getKeyCode() == KeyEvent.VK_ESCAPE) {
         flag = true;
         closePopup();
        } else if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
         insertSelection();
         closePopup();
         flag = true;
        } else if (ke.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
         backspace();
        } else {
            flag = false;
        }
        if (flag) {
            ke.consume();
        }
      }  private void insertSelection()
    {
    String sel = (String) choiceList.getSelectedValue();
    if (sel != null) {
    try {
    textComponent.getDocument().insertString(textComponent.getCaretPosition(), 
    sel.substring(filterStr.length()), null);
    } catch (BadLocationException e) {
    e.printStackTrace();
    }
    }
    } private void closePopup()
    {
    if (popupWindow != null && popupWindow.isShowing()) {
    popupWindow.dispose();
    filterStr = "";
    }
    } private class KeyHandler extends KeyAdapter {
    public void keyTyped(KeyEvent e) {
    if (e.getKeyChar() == '.') {
    if (popupWindow == null || !popupWindow.isShowing()) {
    showPopup();
    }
    }
    else if (popupWindow != null && popupWindow.isShowing() && e.getKeyChar() != 8) {
    updatePopupPosition();
    addFilterChar(e.getKeyChar());
    }
    } public void keyPressed(KeyEvent e) {
    processKey(e);
    }
    }

    private class FocusHandler extends FocusAdapter {
    public void focusLost(FocusEvent e)
    {
          if (popupWindow != null && popupWindow.isShowing()) {
           Component curFocusOwner = e.getOppositeComponent();
           if (curFocusOwner != popupWindow && !popupWindow.isAncestorOf(curFocusOwner)) {
           closePopup();
           }
          }
    }
    }

    private class MouseHandler extends MouseAdapter {
    public void mousePressed(MouseEvent e)
    {
    if (e.getClickCount() == 2) {
    insertSelection();
    closePopup();
    }
    }
    }

    public static void main(String[] args)
    {
    JTextArea ta = new JTextArea(10, 20);
    JScrollPane scrollPane = new JScrollPane(ta);
    JPanel p = new JPanel();
    p.add(scrollPane);
    PopupHint hint = new PopupHint(ta);

    JFrame f = new JFrame("语法提示(试验)");
    f.getContentPane().setLayout(new BorderLayout(0, 5));
    f.getContentPane().add(p, BorderLayout.CENTER);
    f.getContentPane().add(new JLabel("用.来弹出提示窗口", JLabel.CENTER), BorderLayout.NORTH);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
    }
    }