snippetjavaMinor
Generate Property Classes for JavaFX
Viewed 0 times
generatepropertyforclassesjavafx
Problem
Description
Generate Property Classes for JavaFX
Java 1.8 is used.
This code can also be downloaded from PCloud:Zip File ,
Github
File Summary
Dependencies
Code
FXMLController.java: (111 lines, 3198 bytes)
```
/**
* Controller for Scene.fxml
*
* @author Bhathiya
*/
public class FXMLController {
//------
//Table of Properties
@FXML
private TableView tvProperties;
@FXML
private TableColumn tcName;
@FXML
private TableColumn tcType;
//------
@FXML
private ComboBox cmbPropertyType;
@FXML
private TextArea txtCode;
@FXML
private TextField txtProperty;
@FXML
private TextField txtClassName;
//property info observable list : this is bind to table view
private ObservableList propertyInfoList;
//property type observable list : this is bind to combobox of data types
private ObservableList propertyTypeList;
@FXML
void addOnAction(ActionEvent event) {
String name = txtProperty.getText().trim();
if (name.isEmpty()) {
return;
}
String type = cmbPropertyType.getValue();
propertyInfoList.add(new PropertyInfo(name, type));
//clear
txtProperty.clear();
cmbPropertyType.getSelectionModel().selectFirst();
}
@FXML
void generateOnAction(ActionEvent event) {
String className = txtClassName.getText().trim();
if (className.isEmpty()) {
return;
}
PropertyClassBuilder generator = new PropertyClassBuilder(className);
txtCode.setText(generator.generateCode(propertyInfoList));
}
@FXML
void btnClearOnAction(Ac
Generate Property Classes for JavaFX
Java 1.8 is used.
This code can also be downloaded from PCloud:Zip File ,
Github
File Summary
- FXMLController.java: Controller for Scene.fxml
- JavaDataType.java: Java Data Type Enum
- MainApp.java: Main Application Sub Class
- PropertyClassBuilder.java: Code Generator
- PropertyInfo.java: Property Info property class
- pom.xml: Maven (Generated)
- Scene.fxml: Main FXML file (Generated from SceneBuilder)
Dependencies
- javafx
Code
FXMLController.java: (111 lines, 3198 bytes)
```
/**
* Controller for Scene.fxml
*
* @author Bhathiya
*/
public class FXMLController {
//------
//Table of Properties
@FXML
private TableView tvProperties;
@FXML
private TableColumn tcName;
@FXML
private TableColumn tcType;
//------
@FXML
private ComboBox cmbPropertyType;
@FXML
private TextArea txtCode;
@FXML
private TextField txtProperty;
@FXML
private TextField txtClassName;
//property info observable list : this is bind to table view
private ObservableList propertyInfoList;
//property type observable list : this is bind to combobox of data types
private ObservableList propertyTypeList;
@FXML
void addOnAction(ActionEvent event) {
String name = txtProperty.getText().trim();
if (name.isEmpty()) {
return;
}
String type = cmbPropertyType.getValue();
propertyInfoList.add(new PropertyInfo(name, type));
//clear
txtProperty.clear();
cmbPropertyType.getSelectionModel().selectFirst();
}
@FXML
void generateOnAction(ActionEvent event) {
String className = txtClassName.getText().trim();
if (className.isEmpty()) {
return;
}
PropertyClassBuilder generator = new PropertyClassBuilder(className);
txtCode.setText(generator.generateCode(propertyInfoList));
}
@FXML
void btnClearOnAction(Ac
Solution
Duplicated string literals in
You're duplicating the names used by the enums:
This is not good. As usual, if you make a change in one place, you have to remember to make the same change at the other too. It's fragile.
It would be better to iterate over the values of the enum, for example:
Or if you fancy Java 8:
Duplicated string literals in
Similar to the earlier point,
it's a pity to duplicate the string values of the enums in the
Better build a static map from them and use it, without duplicating anything.
Hardcoded Java class names
Still about
Instead of hardcoding the class names of
how about using the real class types instead?
Minor things
This javadoc comment is really pointless, especially on a private field:
This is really hard to read:
For one thing, why write a string segmented like this:
why not as:
And the whole expression would become a lot easier to read if you break a line after each actual
You don't need to call
That is:
You could chain these together, which will make it slightly shorter:
like this:
FXMLController.initializeYou're duplicating the names used by the enums:
propertyTypeList.addAll("String", "Integer", "Boolean", "Double",
"Float", "Long");This is not good. As usual, if you make a change in one place, you have to remember to make the same change at the other too. It's fragile.
It would be better to iterate over the values of the enum, for example:
for (JavaDataType javaDataType : JavaDataType.values()) {
propertyTypeList.add(javaDataType.toString());
}Or if you fancy Java 8:
propertyTypeList.addAll(Arrays.asList(JavaDataType.values()).stream()
.map(JavaDataType::toString)
.collect(Collectors.toList()));Duplicated string literals in
JavaDataType.fromStringSimilar to the earlier point,
it's a pity to duplicate the string values of the enums in the
case statements.Better build a static map from them and use it, without duplicating anything.
private static final Map STRING_TO_ENUM = new HashMap<>();
static {
for (JavaDataType javaDataType : values()) {
STRING_TO_ENUM.put(javaDataType.toString(), javaDataType);
}
}
public static JavaDataType fromString(String type) {
return STRING_TO_ENUM.get(type);
}Hardcoded Java class names
Still about
JavaDataType...Instead of hardcoding the class names of
String, Double, ...,how about using the real class types instead?
STRING(String.class),
INTEGER(Integer.class),
BOOLEAN(Boolean.class),
DOUBLE(Double.class),
FLOAT(Float.class),
LONG(Long.class);
private final String value;
JavaDataType(Class klass) {
this.value = klass.getSimpleName();
}Minor things
This javadoc comment is really pointless, especially on a private field:
/**
* String value
*/
private final String value;This is really hard to read:
String code = "import javafx.beans.property.*;\n" + "\n" + "/**\n"
+ " * Class Information\n" + " * @author Your Name\n" + " */\n"
+ "public class %s {\n" + "\n" + "%s\n" + "\n"
+ " public %s() {\n" + "%s\n" + " }\n" + "\n" + "%s\n"
+ "\n" + "}";For one thing, why write a string segmented like this:
"import javafx.beans.property.*;\n" + "\n" + "/**\n"why not as:
"import javafx.beans.property.*;\n\n/**\n"And the whole expression would become a lot easier to read if you break a line after each actual
\n in the string, like this:String code = "import javafx.beans.property.*;\n\n"
+ "/**\n"
+ " * Class Information\n"
+ " * @author Your Name\n"
+ " */\n"
+ "public class %s {\n\n"
+ "%s\n\n"
+ " public %s() {\n"
+ "%s\n"
+ " }\n\n"
+ "%s\n\n"
+ "}";You don't need to call
.toString() on parameters when formatting a string:return String.format(code, className, fields.toString(), className,
initCodes.toString(), methods.toString());That is:
return String.format(code, className, fields, className, initCodes, methods);You could chain these together, which will make it slightly shorter:
methods.append(toGetterMethod(type, name));
methods.append("\n\n");
methods.append(toSetterMethod(type, name));
methods.append("\n\n");
methods.append(toPropertyMethod(type, name));
methods.append("\n\n");like this:
methods.append(toGetterMethod(type, name))
.append("\n\n")
.append(toSetterMethod(type, name))
.append("\n\n")
.append(toPropertyMethod(type, name))
.append("\n\n");Code Snippets
propertyTypeList.addAll("String", "Integer", "Boolean", "Double",
"Float", "Long");for (JavaDataType javaDataType : JavaDataType.values()) {
propertyTypeList.add(javaDataType.toString());
}propertyTypeList.addAll(Arrays.asList(JavaDataType.values()).stream()
.map(JavaDataType::toString)
.collect(Collectors.toList()));private static final Map<String, JavaDataType> STRING_TO_ENUM = new HashMap<>();
static {
for (JavaDataType javaDataType : values()) {
STRING_TO_ENUM.put(javaDataType.toString(), javaDataType);
}
}
public static JavaDataType fromString(String type) {
return STRING_TO_ENUM.get(type);
}STRING(String.class),
INTEGER(Integer.class),
BOOLEAN(Boolean.class),
DOUBLE(Double.class),
FLOAT(Float.class),
LONG(Long.class);
private final String value;
JavaDataType(Class<?> klass) {
this.value = klass.getSimpleName();
}Context
StackExchange Code Review Q#64027, answer score: 2
Revisions (0)
No revisions yet.