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
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
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

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • What Is Quick Sort in C Programming?
  • TypeScript: Useful Features
  • Training a Handwritten Digits Classifier in Pytorch With Apache Cassandra Database
  • Build a Digital Collectibles Portal Using Flow and Cadence (Part 1)

Trending

  • The State of Data Streaming for Digital Natives (Born in the Cloud)
  • Monetizing APIs: Accelerate Growth and Relieve Strain on Your Engineers
  • Understanding Europe's Cyber Resilience Act and What It Means for You
  • Maximising Data Analytics: Microsoft Fabric vs. Power BI
  1. DZone
  2. Data Engineering
  3. Data
  4. A Custom Float PropertyEditor

A Custom Float PropertyEditor

Alied Pérez user avatar by
Alied Pérez
·
Mar. 01, 11 · Interview
Like (1)
Save
Tweet
Share
10.81K 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

  • What Is Quick Sort in C Programming?
  • TypeScript: Useful Features
  • Training a Handwritten Digits Classifier in Pytorch With Apache Cassandra Database
  • Build a Digital Collectibles Portal Using Flow and Cadence (Part 1)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • 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: