DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Unit Testing Large Codebases: Principles, Practices, and C++ Examples
  • Recurrent Workflows With Cloud Native Dapr Jobs
  • Thermometer Continuation in Scala
  • Thumbnail Generator Microservice for PDF in Spring Boot

Trending

  • The Smart Way to Talk to Your Database: Why Hybrid API + NL2SQL Wins
  • Enforcing Architecture With ArchUnit in Java
  • How To Build Resilient Microservices Using Circuit Breakers and Retries: A Developer’s Guide To Surviving
  • The Future of Java and AI: Coding in 2025
  1. DZone
  2. Data Engineering
  3. Data
  4. A Custom Float PropertyEditor

A Custom Float PropertyEditor

By 
Alied Pérez user avatar
Alied Pérez
·
Mar. 01, 11 · Interview
Likes (1)
Comment
Save
Tweet
Share
11.4K Views

Join the DZone community and get the full member experience.

Join For Free

Both Java SE and the NetBeans Platform have default property editors for several primitive and common data types. These are suitable for most cases and most of us almost never need to worry about it. There are, however, those few moments where the one-size-fits-all approach does not actually fit. For instance, the default float editor is a text editor:

For general-purpose cases, this should be fine. Now, what if you want to restrict the values your property can have or have other control over it? Or simply give the user a more comfortable control for data input, like a JSpinner:

Most of what I'll show was taken from the NetBeans tutorials and Javadoc, so I will not extend in details what you can find easily there.

First, lets implement the PropertyEditor and the InlineEditor (don't forget to <Shift+Ctrl+I> to fix imports):

public abstract class FloatPropertyEditor
extends PropertyEditorSupport
implements ExPropertyEditor, InplaceEditor.Factory{

protected InplaceEditor ed = null;
protected SpinnerNumberModel model;

public FloatPropertyEditor(Object source, SpinnerNumberModel model) {
super(source);
this.model = model;
}

public FloatPropertyEditor(SpinnerNumberModel model) {
this.model = model;
}

@Override
public String getAsText() {
Float d = (Float)getValue();
if (d == null) {
return "0.0";
}
return NumberFormat.getNumberInstance().format(d.floatValue());
}

@Override
public void setAsText(String s) {
try {
setValue(new Float(
NumberFormat.getNumberInstance().parse(s).floatValue()));
} catch (ParseException ex) {
setValue(Float.valueOf(0.0f));
}
}

@Override
public void attachEnv(PropertyEnv env) {
env.registerInplaceEditorFactory(this);
}

@Override
public InplaceEditor getInplaceEditor() {
if (ed == null) {
ed = new FloatInplaceEditor(model);
}
return ed;
}

protected static class FloatInplaceEditor implements InplaceEditor {

private final JSpinner spinner;
private PropertyEditor editor = null;
private PropertyModel model;

public FloatInplaceEditor(SpinnerNumberModel model) {
this.spinner = new JSpinner(model);
}

@Override
public void connect(PropertyEditor propertyEditor, PropertyEnv env) {
editor = propertyEditor;
reset();
}

@Override
public JComponent getComponent() {
return spinner;
}

@Override
public void clear() {
//avoid memory leaks:
editor = null;
model = null;
}

@Override
public Object getValue() {
return spinner.getValue();
}

@Override
public void setValue(Object object) {
try {
spinner.setValue(object);
} catch (IllegalArgumentException e) {
spinner.setValue(null);
}
}

@Override
public boolean supportsTextEntry() {
return true;
}

@Override
public void reset() {
Float d = (Float) editor.getValue();
if (d != null) {
setValue(d);
}
}

@Override
public KeyStroke[] getKeyStrokes() {
return new KeyStroke[0];
}

@Override
public PropertyEditor getPropertyEditor() {
return editor;
}

@Override
public PropertyModel getPropertyModel() {
return model;
}

@Override
public void setPropertyModel(PropertyModel propertyModel) {
this.model = propertyModel;
}

@Override
public boolean isKnownComponent(Component component) {
return component == spinner || spinner.isAncestorOf(component);
}

@Override
public void addActionListener(ActionListener actionListener) {
//do nothing - not needed for this component
}

@Override
public void removeActionListener(ActionListener actionListener) {
//do nothing - not needed for this component
}
}
}


So far, we've been closely following the tutorials. Notice that the FloatPropertyEditor class is abstract. This is because PropertyEditor classes should have a default constructor (more on this below).

Not much of a gain, maybe, but now you have a JSpinner as an editor. Now imagine you are developing a 3D "bodies in space" application. You can select an item and you can change its dimensions and coordinates at will. Coordinates can have any real value, whether negative, zero, or positive (besides the practical dimensional limits your universe might have), while dimensions must be at least be zero.

This is where the abstract plays its role. By inheriting the class above, you can decide which values our properties can have. For coordinate properties, set this class as PropertyEditor:

public class CoordinateFloatPropertyEditor extends FloatPropertyEditor {

public CoordinateFloatPropertyEditor() {
super(new SpinnerNumberModel(0.0, -100000.0, 100000.0, 0.5));
}
}

And, for dimension properties, use this one, instead:
public class DimensionFloatPropertyEditor extends FloatPropertyEditor {

public DimensionFloatPropertyEditor() {
super(new SpinnerNumberModel(0.0, 0.09999, 100000.0, 0.5));
}
}


It's up to you to decide the maximum, minimum, and step values, and tweak this sample for your needs.

I want also to add that this is part of a real application, from where I was inspired to write this article. I'll be further extending this subject in the next posts.

Thanks for you attention.
Muchas gracias por su atención.

Data Types

Opinions expressed by DZone contributors are their own.

Related

  • Unit Testing Large Codebases: Principles, Practices, and C++ Examples
  • Recurrent Workflows With Cloud Native Dapr Jobs
  • Thermometer Continuation in Scala
  • Thumbnail Generator Microservice for PDF in Spring Boot

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!