📄 cityinputmethod.java
字号:
} return result; } String findAlias(String lookupName) { lookupName = lookupName.toUpperCase(); return cityAliases.getProperty(lookupName, lookupName); } void convertFirstTime() { numSegs = rawText.length() / 3; rawTextSegs = new String[numSegs]; convertedSegs = new String[numSegs]; for (int i = 0; i < numSegs; ++i) { rawTextSegs[i] = rawText.substring(i * 3, (i + 1) *3); String alias = findAlias(rawTextSegs[i]); String result = lookup(alias, cityNames); if (result != null) { convertedSegs[i] = result; } else { convertedSegs[i] = rawText.substring(i * 3, (i + 1) * 3); } } converted = true; sendText(false); } void convertAgain() { String lookupName; lookupName = rawTextSegs[selectedSeg]; // if converted string is same as original, it's not in word list. We skip // further conversion. if (!lookupName.equals(convertedSegs[selectedSeg])) { lookupName = findAlias(lookupName); lookupCandidates = new String[LOOKUP_LOCALES.length]; lookupLocales = new Locale[LOOKUP_LOCALES.length]; lookupCandidateCount = 0; lookupSelection = 0; for (int i = 0; i < LOOKUP_LOCALES.length; i++) { Locale iLocale = LOOKUP_LOCALES[i]; String localeLookupName = lookupName + '_' + iLocale; String localeConvertedText = (String) cityNames.get(localeLookupName); if (localeConvertedText != null) { lookupCandidates[lookupCandidateCount] = localeConvertedText; lookupLocales[lookupCandidateCount] = iLocale; lookupCandidateCount++; } else if (iLocale.equals(Locale.ENGLISH)) { localeConvertedText = (String) cityNames.get(lookupName); if (localeConvertedText != null) { lookupCandidates[lookupCandidateCount] = localeConvertedText; lookupLocales[lookupCandidateCount] = iLocale; lookupCandidateCount++; } } if (convertedSegs[selectedSeg].equals(localeConvertedText)) { lookupSelection = lookupCandidateCount - 1; } } openLookupWindow(); } else { Toolkit.getDefaultToolkit().beep(); } } /* commits all chunks up to the specified index */ private void commit(int index) { if (index >= (numSegs - 1)) { // if this is the last segment, commit all commitAll(); } else { committedSeg = index; selectedSeg = committedSeg + 1; sendText(true); } } /* commits all chunks */ void commitAll() { committedSeg = numSegs - 1; sendText(true); // once composed text is committed, reinitialize all variables rawText.setLength(0); convertedText = null; converted = false; rawTextSegs = null; convertedSegs = null; fmt = null; fieldPos = null; segPos = null; selectedSeg = 0; insertionPoint = rawText.length(); numSegs = 0; committedSeg = -1; previouslyCommittedCharacterCount = 0; } void parseFormat() { Vector vec = new Vector(); int[] elem = null; for(int i = 0; i < fmt.length(); i++) { if (fmt.charAt(i) == '{') { elem = new int[2]; elem[0] = i; } else if (fmt.charAt(i) == '}') { elem[1] = i; vec.add(elem); } } if (vec.size() != 0) { fieldPos = new int[vec.size()][]; vec.toArray(fieldPos); } } void formatOutput() { if (fmt == null) { String key = "Template" + Integer.toString(numSegs); fmt = lookup(key, templates); parseFormat(); } convertedText = MessageFormat.format(fmt, (Object [])convertedSegs); // Figure out converted segment position int errors = 0; segPos = new int[fieldPos.length][2]; for (int i = 0; i < fieldPos.length; i++) { int optLen = (fieldPos[i][1] - fieldPos[i][0]) + 1; int diffs = convertedSegs[i].length() - optLen; segPos[i][0] = fieldPos[i][0] + errors; segPos[i][1] = segPos[i][0] + convertedSegs[i].length(); errors += diffs; } } void sendText(boolean committed) { AttributedString as = null; TextHitInfo caret = null; int committedCharacterCount = 0; int newTotalCommittedCharacterCount = previouslyCommittedCharacterCount; if (converted) { formatOutput(); if (committed) { if (committedSeg == (numSegs - 1)) { newTotalCommittedCharacterCount = convertedText.length(); } else { newTotalCommittedCharacterCount = segPos[committedSeg + 1][0]; } committedCharacterCount = newTotalCommittedCharacterCount - previouslyCommittedCharacterCount; } as = new AttributedString(convertedText.substring(previouslyCommittedCharacterCount)); for(int i = committedSeg + 1; i < numSegs; i++) { InputMethodHighlight highlight; if (i == selectedSeg) { highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT; } else { highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT; } as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, highlight, segPos[i][0] - previouslyCommittedCharacterCount, segPos[i][1] - previouslyCommittedCharacterCount); } previouslyCommittedCharacterCount = newTotalCommittedCharacterCount; } else { as = new AttributedString(rawText.toString()); if (committed) { committedCharacterCount = rawText.length(); } else if (rawText.length() != 0) { as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT); caret = TextHitInfo.leading(insertionPoint); } } inputMethodContext.dispatchInputMethodEvent( InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, as.getIterator(), committedCharacterCount, caret, null); } void selectCandidate(int candidate) { lookupSelection = candidate; lookupList.selectCandidate(lookupSelection); convertedSegs[selectedSeg] = lookupCandidates[lookupSelection]; sendText(false); } int getSelectedSegmentOffset() { return segPos[selectedSeg][0] - previouslyCommittedCharacterCount; } void openLookupWindow() { lookupList = new LookupList(this, inputMethodContext, lookupCandidates, lookupLocales, lookupCandidateCount); lookupList.selectCandidate(lookupSelection); } void closeLookupWindow() { if (lookupList != null) { lookupList.setVisible(false); lookupList = null; } }}class LookupList extends JPanel { CityInputMethod inputMethod; InputMethodContext context; Window lookupWindow; String[] candidates; Locale[] locales; int candidateCount; int selected; final int INSIDE_INSET = 4; final int LINE_SPACING = 18; LookupList(CityInputMethod inputMethod, InputMethodContext context, String[] candidates, Locale[] locales, int candidateCount) { this.inputMethod = inputMethod; this.context = context; this.candidates = candidates; this.locales = locales; this.candidateCount = candidateCount; if (inputMethod.methodCreateInputMethodJFrame != null) { try { Object[] params = new Object[2]; params[0] = inputMethod.lookupWindowTitle; params[1] = Boolean.TRUE; lookupWindow = (Window)inputMethod.methodCreateInputMethodJFrame.invoke(context, params); } catch (Exception e) { lookupWindow = context.createInputMethodWindow(inputMethod.lookupWindowTitle, true); } } else { lookupWindow = context.createInputMethodWindow(inputMethod.lookupWindowTitle, true); } setFont(new Font("Dialog", Font.PLAIN, 12)); setPreferredSize(new Dimension(200, candidateCount * LINE_SPACING + 2 * INSIDE_INSET)); setOpaque(true); setForeground(Color.black); setBackground(Color.white); enableEvents(AWTEvent.KEY_EVENT_MASK); enableEvents(AWTEvent.MOUSE_EVENT_MASK); if (lookupWindow instanceof JFrame) { ((JFrame)lookupWindow).getContentPane().add(this); } else { lookupWindow.add(this); } lookupWindow.pack(); updateWindowLocation(); lookupWindow.setVisible(true); } /** * Positions the lookup window near (usually below) the * insertion point in the component where composition occurs. */ private void updateWindowLocation() { Point windowLocation = new Point(); int textOffset = inputMethod.getSelectedSegmentOffset(); Rectangle caretRect = context.getTextLocation(TextHitInfo.leading(textOffset)); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension windowSize = lookupWindow.getSize(); final int SPACING = 2; if (caretRect.x + windowSize.width > screenSize.width) { windowLocation.x = screenSize.width - windowSize.width; } else { windowLocation.x = caretRect.x; } if (caretRect.y + caretRect.height + SPACING + windowSize.height > screenSize.height) { windowLocation.y = caretRect.y - SPACING - windowSize.height; } else { windowLocation.y = caretRect.y + caretRect.height + SPACING; } lookupWindow.setLocation(windowLocation); } void selectCandidate(int candidate) { selected = candidate; repaint(); } public void paint(Graphics g) { super.paint(g); FontMetrics metrics = g.getFontMetrics(); int descent = metrics.getDescent(); int ascent = metrics.getAscent(); for (int i = 0; i < candidateCount; i++) { g.drawString((i + 1) + " " + candidates[i] + " (" + locales[i].getDisplayName() + ")", INSIDE_INSET, LINE_SPACING * (i + 1) + INSIDE_INSET - descent); } Dimension size = getSize(); g.drawRect(INSIDE_INSET / 2, LINE_SPACING * ( selected + 1) + INSIDE_INSET - (descent + ascent + 1), size.width - INSIDE_INSET, descent + ascent + 2); g.drawRect(0, 0, size.width - 1, size.height - 1); } public void setVisible(boolean visible) { if (!visible) { lookupWindow.setVisible(false); lookupWindow.dispose(); lookupWindow = null; } super.setVisible(visible); } protected void processKeyEvent(KeyEvent event) { inputMethod.dispatchEvent(event); } protected void processMouseEvent(MouseEvent event) { if (event.getID() == MouseEvent.MOUSE_PRESSED) { int y = event.getY(); if (y >= INSIDE_INSET && y < INSIDE_INSET + candidateCount * LINE_SPACING) { inputMethod.selectCandidate((y - INSIDE_INSET) / LINE_SPACING); inputMethod.closeLookupWindow(); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -