Using EditTextField as editor with autocomplete for table cell

Answered

I`m developing a plugin for intellij idea. As part of its functionality I need to implement a table in settings. One of table columns contains a class from project. Specifically, each cell of the column contains a class, which is input by user. When user editing the cell I want to support autocomplete. For this purpose I use EditTextField with custom TextFieldCompletionProvider (which offers only class names).

In short, it looks like this:

private class GenerateClassColumnInfo : ColumnInfo<Row, ClassName>(TYPE) {
...

override fun getRenderer(item: Row?): TableCellRenderer =
TableCellRenderer { table, value, isSelected, hasFocus, row, column ->
...
val text: String = ...
JBTextField(text)
}

override fun getEditor(item: Row?): TableCellEditor = ClassColumnInfoCellEditor()

...
}

private class ClassColumnInfoCellEditor : AbstractTableCellEditor() {
...

override fun getTableCellEditorComponent(
table: JTable, value: Any, isSelected: Boolean, row: Int, column: Int
): Component {
...
return EditorTextField(...).apply { setupCompletionProvider() }
}

private fun EditorTextField.setupCompletionProvider() {
object : TextFieldCompletionProvider() {

override fun addCompletionVariants(
text: String,
offset: Int,
prefix: String,
result: CompletionResultSet
) {
...
}
}.apply(this, text)
}
}

So when cell is being edited, I use EditTextField and when it is in view-mode, JBTextField is used.

The problem is, I cannot configure text alignment in EditTextField. In edit-mode text is aligned top-left, while in view-mode it is center-aligned. I want text to be center-aligned in both modes. How to configure EditTextField for that? Or is it in general not good idea to use EditTextField in such case?

3 comments
Comment actions Permalink

Why do you use custom JBTextField for rendering instead of default Table renderer? We use com.intellij.ui.TextFieldWithAutoCompletion in similar place with no problems AFAIR. You might need to adjust line height, e.g.

setRowHeight(new LanguageTextField().getPreferredSize().height * 2 + JBUIScale.scale(1));
0
Comment actions Permalink

1) Why do you use custom JBTextField for rendering instead of default Table renderer?

There is no particular strong reason to use custom implementation, but this is my first experience with swing tables, so the code is a little bit of mess, so I will get certain visual effects if to replace JBTextField with default table renderer. All in all, I feel fine with JBTextField. It looks ok.

2) We use com.intellij.ui.TextFieldWithAutoCompletion in similar place

I tried to use TextFieldWithAutoCompletion. It requires variants: List<String> as constructor parameter. Does it mean I have to create list and put literally all classes in it? Doesn`t it look like too much computation work?

In case it doesn`t: how to determine elements for such a list? My guess is:

JavaClassNameCompletionContributor.addAllClasses(
parameters,
filterByScope,
prefixMatcher,
consumer
)

In this example I have problems with instantiating parameters (CompletionParameters). It has parameter

private final CompletionProcess myProcess;

which in turn is subtle in terms of instantiating or getting reference to existing instance.

In case of EditTextField I get parameters from intellij framework, so there is no such problem. How to create the parameters by myself?

0
Comment actions Permalink

You can absolutely keep your existing solution with EditorTextField if it works for you, I was just giving sample of very similar approach.

Seems you might have to play around with wrapping JPanel to align/tweak layout.

0

Please sign in to leave a comment.