Android Studio - IntelliJ new java class wizard - android-studio

After last Android Studio update, there's the following new java class wizard right after picking the name:
Couldn't find any guide on how to use it because it doesn't auto-completes anything.
Is there a way to return to the old wizard?

You can disable this dialog by reset your class template to default in Settings -> Editor -> File and Code Templates:
This dialog shown when template has variables which can not be provided automatically. I think studio installer forgot update templates from previous setup where new class dialog had more options.

Couldn't find any guide on how to use it because it doesn't auto-completes anything.
From the Android Studio Documentation:
Android Studio replaces file template variables with values in the generated Java file. You enter the values in the Create New Class dialog. The template has the following variables that you can use:
IMPORT_BLOCK - A newline-delimited list of Java import statements
necessary to support any superclass or interfaces, or an empty string
(""). For example, If you only implement the Runnable interface and
extend nothing, this variable will be import java.lang.Runnable;\n.
If you implement the Runnable interface and extend the Activity
class, it will be import android.app.Activity;\nimportjava.lang.Runnable;\n.
VISIBILITY -
Whether the class will have public access or not. It can have a value
of PUBLIC or PACKAGE_PRIVATE.
SUPERCLASS - A single class name, or
empty. If present, there will be an extends ${SUPERCLASS} clause
after the new class name.
INTERFACES - A comma-separated list of
interfaces, or empty. If present, there will be an implements
${INTERFACES} clause after the superclass, or after the class name if
there’s no superclass. For interfaces and annotation types, the
interfaces have the extends keyword.
ABSTRACT - Whether the class
should be abstract or not. It can have a value of TRUE or FALSE.
FINAL - Whether the class should be final or not. It can have a value
of TRUE or FALSE.
Is there a way to return to the old wizard?
NO. you cannot revert back to old style new class dialog.

You can use something like this for the class template:
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#if (${IMPORT_BLOCK} != "")${IMPORT_BLOCK}
#end
#parse("File Header.java")
#if (${VISIBILITY} != "pr" || ${VISIBILITY} == "")public #end
#if (${ABSTRACT} == "y" || ${ABSTRACT} == "true")abstract #end
#if (${FINAL} == "y" || ${FINAL} == "true")final #end
class ${NAME} #if (${SUPERCLASS} != "")extends ${SUPERCLASS} #end
#if (${INTERFACES} != "")implements ${INTERFACES} #end {
}
define the template in Settings -> Editor -> File and Code Templates

Related

IntelliJ Live Template for dart named constructor: lists class' fields

I want to generate a custom named constructor in Dart.
I have many dto class to implement and each should provide a named constructor like: ClassName.fromMap().
For example for this class:
class Student {
final String name;
final int age;
}
The generated constructor should be:
Student.fromMap(Map<String, dynamic> map) :
name = map['name'],
age = map['age'];
How can I retrieve the list of the field of my current class as strings? Is that even possibile?
Of course I can have a variable number of fields.
My template looks like:
$CLASS$.fromMap(Map<String, dynamic> map) :
$INITIALIZATION_LIST$
binding $CLASS$ to dartClassName().
Now I'd like to bind $INITIALIZATION_LIST$ to something like:
getClassFieldList().forEach((fieldName) => "$fieldName = map['$fieldName']")
Can I achieve something like that?
There is no way to retrieve a list of Dart class fields using predefined live template functions. You can try developing your own template macro for this. See https://intellij-support.jetbrains.com/hc/en-us/community/posts/206201699-create-a-new-expression-for-a-live-template-for-actionscript for some hints.
Existing live template functions implementations can be found at https://github.com/JetBrains/intellij-community/tree/master/platform/lang-impl/src/com/intellij/codeInsight/template/macro.
You can also try using Structural Search and Replace instead of live template

How to programmatically update .rgs files to reflect changes made in IDL files?

Is there any tool to update .rgs files to reflect change made in the IDL ?
rgs files are created by the ATL control wizzard but I can't find a way to refresh thoses files.
When we change the uuid of an interface (within the .IDL file), we are forced to changed by hand the "hard copy" values in those .rgs files. This is quiet prone to error.
I found this interesting project that intend to fill this gap but, accordingly the last comments, it didn't works any more since VC2005.
ATL CAtlModule implementation offers virtual CAtlModule::AddCommonRGSReplacements which you can override and add substitutions to remove hardcoded RGS values.
For example, my typical ATL code looks like this:
class CFooModule :
public CAtlDllModuleT<CFooModule>
{
[...]
// CAtlModule
HRESULT AddCommonRGSReplacements(IRegistrarBase* pRegistrar)
{
// Error handling omitted for code brevity
__super::AddCommonRGSReplacements(pRegistrar);
ATLASSERT(m_libid != GUID_NULL);
pRegistrar->AddReplacement(L"LIBID", _PersistHelper::StringFromIdentifier(m_libid));
pRegistrar->AddReplacement(L"FILENAME", CStringW(PathFindFileName(GetModulePath())));
pRegistrar->AddReplacement(L"DESCRIPTION", CStringW(AtlLoadString(IDS_PROJNAME)));
return S_OK;
}
In COM classes I override UpdateRegistry method to add tokens with third parameter of standard call _pAtlModule->UpdateRegistryFromResource.
As a result, many .RGS are shared between COM classes because hardcoded values are replaced with tokens. Specifically, there are no GUIDs in RGS files, e.g.:
HKCR
{
NoRemove CLSID
{
ForceRemove %CLSID% = s '%DESCRIPTION%'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
val AppID = s '%APPID%'
TypeLib = s '%LIBID%'
}
}
}
I'm not able to understand how %CLSID% is replaced with the COM class CLSID in roman-r's answer. There seem to be something missing in the answer.
Alternative solution from CodeProject: Registry Map for RGS files.
This solution introduces a custom registrymap.hpp header with a DECLARE_REGISTRY_RESOURCEID_EX extension that allows you to add RGS substitution macros to your COM classes. Example:
BEGIN_REGISTRY_MAP(CClassName)
REGMAP_ENTRY("PROGID", "MyLibrary.ClassName")
REGMAP_ENTRY("VERSION", "1")
REGMAP_ENTRY("DESCRIPTION", "ClassName Class")
REGMAP_UUID ("CLSID", CLSID_ClassName)
REGMAP_UUID ("LIBID", LIBID_MyLibraryLib)
REGMAP_ENTRY("THREADING", "Apartment")
END_REGISTRY_MAP()

WPFExtendedToolkit PropertyGrid Standard Values

I'm trying to display XmlElement's attributes in Xceed PropertyGrid. For that purpose I defined custom wrapper class. It wraps XmlElement, iterates over XmlAttributes and creates custom PropertyDescriptor for each XmlAttribute. All "virtual" properties' type is String. All works fine.
Now I want to have drop-down list of possible attribute values for every attribute that has restricted set of values. In Xceed's PropertyGrid, there is ItemsSourceAttribute for that. But it has to be applied as follows:
ItemsSourceAttribute(typeof(MyCustomItemsSource))
And here is the problem - I can not provide proper argument for MyCustomItemsSource constructor. What can I do about this?
It seems that there is another possibility - to define a TypeConverter, override GetStandardValues, and supply this converter to "virtual" property. But PropertyGrid just ignores this attribute.
How this simple task can be done with Xceed PropertyGrid?
Solved. I implemented custom editor
public class AttributeValuesEditor: Xceed.Wpf.Toolkit.PropertyGrid.Editors.ComboBoxEditor
{
protected override IEnumerable CreateItemsSource(PropertyItem propertyItem)
{
var property = propertyItem.PropertyDescriptor as XmlAttributePropertyDescriptor;
Debug.Assert(property!=null);
return property.GetCompletionValues();
}
}
Here, the context is passed into method in the form of PropertyItem. Now it is possible to differentiate between different attributes and return appropriate items.

Is there a way to specify the initial cursor position in a Visual Studio item template?

When you add, for example, a class to a project by selecting Add > New Item > Visual C# Items > Class, the blinking text cursor inside the new class will be at row 1, column 1. Is there a way to modify the template so that the blinking cursor appears in a different location?
using System;
namespace SomeNamespace
{
class SomeClass
{
| <--- I'd like the blinking cursor to initially appear here
}
}
You want to use $END$. You can also make fields by surrounding other keywords with $$.
using System;
namespace $Namespace$
{
public class $ClassName$
{
$END$
}
}

JDK Locale class handling of ISO language codes for Hebrew (he), Yiddish (yi) and Indonesian (id)

When instantiating a Locale object with either one of the following language codes: he, yi and id it doesn't preserve their value.
For example:
Locale locale = new Locale("he", "il");
locale.getLanguage(); // -> "iw"
What is causing this and is there any way to work around this?
The Locale class does not impose any checks on what you feed in it, but it swaps out certain language codes for their old values. From the documentation:
ISO 639 is not a stable standard; some of the language codes it
defines (specifically "iw", "ji", and "in") have changed. This
constructor accepts both the old codes ("iw", "ji", and "in") and the
new codes ("he", "yi", and "id"), but all other API on Locale will
return only the OLD codes.
Here's the constructor:
public Locale(String language, String country, String variant) {
this.language = convertOldISOCodes(language);
this.country = toUpperCase(country).intern();
this.variant = variant.intern();
}
And here's the magic method:
private String convertOldISOCodes(String language) {
// we accept both the old and the new ISO codes for the languages whose ISO
// codes have changed, but we always store the OLD code, for backward compatibility
language = toLowerCase(language).intern();
if (language == "he") {
return "iw";
} else if (language == "yi") {
return "ji";
} else if (language == "id") {
return "in";
} else {
return language;
}
}
The objects it creates are immutable, so there's no working around this. The class is also final, so you can't extend it and it has no specific interface to implement. One way to make it preserve those language codes would be to create a wrapper around this class and use that.
The Java treatment of the Hebrew locale seems to had been changed in Java 17. It appears as an attempt to adhere to the ISO_639-1 language codes standard.
Unless property 'java.locale.useOldISOCodes' is set to true, Java now treats the Hebrew locale, by default as 'he' in adherence with ISO_639-1. This means you will succeed to load a Hebrew resource bundle named 'messages_he.properties' with either 'iw' or 'he' language code constructed locales. A 'messages_iw.properties' resource is de-prioritized and will only get loaded if a corresponding 'he' resource is none existent.
It's a step in the right direction and it's better late than never, as no more trickery and magic is required in the naming strategy of Hebrew resource bundles. Just use the 'he' ISO code.
I've recently answered this here at Locale code for Hebrew / Reference to other locale codes?. I've provided a small example class with basic resource bundles which demonstrates the new behavior.

Resources