我想要一个具有标准自动完成行为的TextCellEditor,这是当前任何用户在输入单元格中键入建议字符串列表时所期望的。关于我所追求的一个很好的工作示例,在Javascript中,请参阅此jQuery autocomplete widget。
我找不到一个好例子。 我只发现了(除了一些微小的变化)TextCellEditorWithContentProposal snippet。但这还有很多不足之处:
我觉得这样一个标准且有用的组件是不可用的。或者也许它可用?有人能指出我更合适的片段或例子吗?
答案 0 :(得分:3)
您要链接的示例是一个代码段,旨在展示API并指导您根据自己的喜好自定义控件。
您的某些投诉无效或可以使用公共API轻松修复。
让我们详细介绍一下。
请注意,在代码段中使用了org.eclipse.jface.fieldassist.SimpleContentProposalProvider
:
IContentProposalProvider contentProposalProvider = new SimpleContentProposalProvider(new String[] { "red",
"green", "blue" });
cellEditor = new TextCellEditorWithContentProposal(viewer.getTable(), contentProposalProvider, null, null);
正如其javadoc中所建议的那样:
旨在将字符串的静态列表映射到内容提案
要启用对代码段内容的简单过滤,您可以致电:contentProposalProvider.setFiltering(true);
对于任何更复杂的内容,您必须将其替换为您自己的org.eclipse.jface.fieldassist.IContentProposalProvider
实现。
内容提案行为在org.eclipse.jface.fieldassist.ContentProposalAdapter
中定义。再次,对org.eclipse.jface.fieldassist.ContentProposalAdapter.setProposalAcceptanceStyle(int)
的简单方法调用将实现您的目标行为:
contentProposalAdapter = new ContentProposalAdapter(text, new TextContentAdapter(), contentProposalProvider, keyStroke, autoActivationCharacters);
contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
仅仅使用API很难做到,因为ContentProposalAdapter
只会将关键笔划传播到打开的ContentProposalPopup
而不存储它们。
您必须继承ContentProposalAdapter
,才能访问ContentProposalAdapter.ContentProposalPopup.filterText
。
此片段中包含合理默认值的大多数功能也可以通过org.eclipse.jface.fieldassist.AutoCompleteField
以更简单的方式获得。
答案 1 :(得分:0)
以下是向您展示一个简单实现的代码段。您必须对其进行自定义,但它可以为您提供方法。
注意,这不是文档的一般副本/粘贴内容,也不是有关文档的说明。
String[] contentProposals = {"text", "test", "generated"};
// simple content provider based on string array
SimpleContentProposalProvider provider = new SimpleContentProposalProvider(contentProposals);
// enable filtering or disabled it if you are using your own implementation
provider.setFiltering(false);
// content adapter with no keywords and caracters filtering
ContentProposalAdapter adapter = new ContentProposalAdapter(yourcontrolswt, new TextContentAdapter(), provider, null, null);
// you should not replace text content, you will to it bellow
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_IGNORE);
// now just put your implementation
adapter.addContentProposalListener(new IContentProposalListener() {
@Override
public void proposalAccepted(IContentProposal proposal) {
if(proposal != null && StringUtils.isNotBlank(proposal.getContent())){
// you need filter with blank spaces
String contentTextField = getFilterControl().getText();
String[] currentWords = getFilterControl().getText().split(" ");
StringBuilder textToDisplay = new StringBuilder();
if(currentWords.length > 1) {
// delete and replace last word
String lastWord = currentWords[currentWords.length-1];
textToDisplay.append(contentTextField.substring(0, contentTextField.length()-1-lastWord.length()));
textToDisplay.append(" ");
}
// add current proposal to control text content
textToDisplay.append(proposal.getContent());
yourcontrolswt.setText(textToDisplay.toString());
}
}
});
如果需要更多内容,还可以拥有自己的内容提议提供者。如果需要特定的对象而不是字符串或类似的东西。
public class SubstringMatchContentProposalProvider implements IContentProposalProvider {
private List<String> proposals = Collections.emptyList();
@Override
public IContentProposal[] getProposals(String contents, int position) {
if (position == 0) {
return null;
}
String[] allWords = contents.split(" ");
// no words available
if(allWords.length == 0 || StringUtils.isBlank(allWords[allWords.length-1]))
return null;
// auto completion on last word found
String lastWordFound = allWords[allWords.length-1];
Pattern pattern = Pattern.compile(lastWordFound,
Pattern.LITERAL | Pattern.CASE_INSENSITIVE /*| Pattern.UNICODE_CASE*/); // this should be not used for better performances
IContentProposal[] filteredProposals = proposals.stream()
.filter(proposal -> proposal.length() >= lastWordFound.length() && pattern.matcher(proposal).find())
.map(ContentProposal::new).toArray(IContentProposal[]::new);
// no result
return filteredProposals.length == 0 ? null : filteredProposals;
}
public void setProposals(List<String> proposals) {
this.proposals = proposals;
}
}