Get current class name in Intellij Idea plugin - intellij-idea

I want to press key combination and get the fully qualified class name where the caret is at right now. I have deleloped a plugin but it required me to move the caret on to the class name.
PsiElement element = (PsiElement) e.getDataContext().getData("psi.Element");
element instanceof PsiClass {
PsiClass className = element;
}
How do I get the class name when I press my key combination when the caret is in somewhere in the class ?

You can use PsiTreeUtil.getParentOfType to find the parent class like this:
PsiClass stmt = PsiTreeUtil.getParentOfType(element, PsiClass.class);
Where element is the PsiElement currently under the caret (it seems you already know how to find it).
See the source code of PsiTreeUtil for more info.

Related

Intellij disable new line before annotated field for Kotlin

IntelliJ autoformat keeps adding a blank lines between class field declarations having annotations.
Do you know how to disable it?
This happens for kotlin files since does not work like that for java files.
Example, between each var intellij adds a blank line each time I execute autoformat.
class Resign : UnitTest() {
#InjectMocks
private lateinit var resignService: ResignServiceImpl
#Mock
private lateinit var actionAccess: ActionAccess
#Mock
private lateinit var userReportConverter: UserReportConverter
....
}
The problem was fixed in KT-37891. The option to disable this behavior should be available in the next plugin version.
You may also consider voting for KT-32185: 'More code style options for minimum blank lines'
Go to Settings > Editor > Code style > Kotlin > Wrapping and Braces.
Change Property annotations to "Do not wrap" or "Wrap if long".
No answer properly points out the exact name of the configuration. Under the Kotlin code style, it can be found on the "Blank Lines" tab, with the name "Before declaration with comment or annotation".
For me, this defaulted to 1. Setting it to 0 let's me decide myself whether I want a new line or not.

Sealed class with existing classes?

I am implementing a custom keyboard and I am representing the keys 0-9 and the decimal separator as Button objects. Then I have one final key which is the backspace and is being represented as an ImageButton.
When I handle the click events I know that if the user clicked a Button they are adding an element to the text field and if they clicked an ImageButton they are removing the last element from the text field.
Since the keyboard only has two possible type of buttons I wanted to implement this logic with a when block without using an else branch. Is it possible? Looking at the sealed class documentation I don't think it might be but just asking to make sure.
I'd like to do something like this:
sealed class KeyboardButton {
class Button
class ImageButton
}
fun handleKeyPress(button: View) {
when(button) {
is KeyboardButton.Button -> // append element to text
is KeyboardButton.ImageButton -> // remove last element from text
}
}
You can't do this with a sealed class because you can't get the views to inherit from your sealed class. You can use an else branch that throws an exception:
fun handleKeyPress(button: View) {
when(button) {
is Button -> // append element to text
is ImageButton -> // remove last element from text
else -> error("unsupported view type")
}
}
You can wrap the existing types like this:
sealed class KeyboardButton {
class KButton(val x: Button)
class KImageButton(val x: ImageButton)
}
fun handleKeyPress(button: KeyboardButton) {
when(button) {
is KeyboardButton.KButton -> // use button.x to access the underlying Button
is KeyboardButton.KImageButton -> // similarly use button.x
}
}

Handling nested Properties in JavaFX / TornadoFX

I want to have a window which shows info about certain ViewModel
Suppose you have a simple Person:
class Person(name: String) {
val nameProperty = SimpleStringProperty(name)
}
and have instance of Person save in property:
val personProperty = SimpleObjectProperty(Person("John"))
what's the correct solution to show Person's name in label?
Using this:
label(personProperty.value.nameProperty)
Will not update when I update the property's person:
personProperty.value = Person("Joe")
(That's obvious because only the reference changes, not the value itself)
So is there any good way to do this or do I have to manually add listeners for personProperty and update which Person does label point to?
EDIT:
I also found this question: JavaFX binding and property change, but it doesn't contain anything new and useful that I didn't know about, is there any TornadoFX-specific way of doing this?
This is exactly what the ItemViewModel does for you. If you want to make a binding for the name property that updates automatically, outside of an ItemViewModel, you can use the TornadoFX feature select:
val nameProperty = personProperty.select { it.nameProperty }
A listener can be attached to the property:
personProperty.onChange {
it?.nameProperty.let(nameLabel.textProperty().bind)
}
This can be wrapped in extension function to simplify the task.

Button click to: TextView.text = "works" but EditText.text = "Doesnt work"

As title says:
I´d like to change the text inside an editText with a button click.
I can do it with TextViews by using this code:
TextView.text= "new text here"
but it doesnt work for EditText
I already tried something like this:
editText.setText("new text here")
Can some one please tell me the equivalent code for editTexts?
this is my code so far:
dialog.setOnClickListener {
var builder = AlertDialog.Builder(this)
var inflater: LayoutInflater = layoutInflater
var view : View = inflater.inflate(R.layout.dialog,null)
builder.setView(view)
builder.setTitle("categories")
builder.setPositiveButton("Ver", { dialogInterface: DialogInterface, i: Int ->
mainscreen.visibility = View.GONE
ListView.visibility = View.VISIBLE
listdogs.visibility=View.VISIBLE
listdogs.adapter = adapterdogs
editText?.setText("husky")
})
Regards
You need editText?.setText("new text here") or editText!!.setText("new text here") if you are sure that this EditText is not null.
This is happening because java getter setter ambiguous in case of EditText, To understand this scenario you first need to understand that how kotlin generate the properties from java class for kotlin.
Kotlin official
Methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set) are represented as properties in Kotlin. Boolean accessor methods (where the name of the getter starts with is and the name of the setter starts with set) are represented as properties which have the same name as the getter method.
But in case EditText, which inherits setter from TextView creating problem here.
When a setter comes into play, property generation process becomes ambiguous. The reason is that the getter and the setter may have different types. Moreover, the getter and/or the setter may be overridden in a subclass,
which exactly is the case of EditText in Android.
It means that you can get an Editable for an EditText and set an Editable to an EditText. Therefore, Kotlin reasonably creates a synthetic property text of type Editable. Considering that the String Class is not editable, I cannot assign a String instance to the text property of the EditText class.
Original source https://medium.com/cashify-engineering/how-does-kotlin-generated-property-from-java-getters-and-setters-undocumented-by-jetbrains-7e1ad88052b1

How to add class level variable declarations using javaparser?

class A{
int x = 10;
}
This is A.java
I want to get NewA.java
class NewA{
int x = 10;
Sting text = "B";
}
I want to add a variable using javaparser.
You need to do this:
Parse the code
Find the point where you want to add your element
Add the element you want
Dump back the code
The first point is trivial, just use the JavaParser.parse method. You will get a CompilationUnit. In the example you shown you are adding a field in a class declaration, so you need first to get that class declaration. Call getTypes and look into that list for the declaration you want or just call getClassByName.
Once you have your class declaration you can call addMember on it. In your example you are adding a field so you need to instantiate a FieldDeclaration.
Once you are done you take your CompilationUnit and call toString. You will get back the modified source code.
Source: I am a JavaParser committer