Статьи

Пользовательский Float PropertyEditor

И Java SE, и платформа NetBeans имеют редакторы свойств по умолчанию для нескольких простых и распространенных типов данных. Они подходят для большинства случаев, и большинству из нас почти никогда не нужно беспокоиться об этом. Однако есть несколько моментов, когда подход «один размер подходит всем» на самом деле не подходит. Например, поплавковый редактор по умолчанию — это текстовый редактор:

Для случаев общего назначения это должно быть хорошо. Теперь, что если вы хотите ограничить значения, которые может иметь ваша собственность, или иметь другой контроль над ней? Или просто предоставьте пользователю более удобный элемент управления вводом данных, например, JSpinner:

Большая часть того, что я покажу, была взята из учебников по NetBeans и Javadoc , поэтому я не буду подробно останавливаться на том, что вы можете легко найти там.

Во-первых, давайте реализуем PropertyEditor и InlineEditor (не забудьте <Shift + Ctrl + I>, чтобы исправить импорт):

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
}
}
}

До сих пор мы внимательно следили за учебниками. Обратите внимание, что класс FloatPropertyEditor является абстрактным. Это связано с тем, что классы PropertyEditor должны иметь конструктор по умолчанию (подробнее об этом ниже).

Может быть, это не очень выгодно, но теперь у вас есть JSpinner в качестве редактора. Теперь представьте, что вы разрабатываете трехмерное приложение «тела в космосе». Вы можете выбрать элемент, и вы можете изменить его размеры и координаты по желанию. Координаты могут иметь любое реальное значение, будь то отрицательное, нулевое или положительное (помимо практических ограничений размеров, которые может иметь ваша вселенная), в то время как измерения должны быть по крайней мере равны нулю.

Здесь реферат играет свою роль. Унаследовав класс выше, вы можете решить, какие значения могут иметь наши свойства. Для координатных свойств установите этот класс как PropertyEditor:

public class CoordinateFloatPropertyEditor extends FloatPropertyEditor {

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

И, для свойств измерения, используйте это вместо этого:

public class DimensionFloatPropertyEditor extends FloatPropertyEditor {

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

Вам решать, как определить максимальные, минимальные и пошаговые значения, и настроить этот образец для своих нужд.

Я также хочу добавить, что это часть реального приложения, откуда я был вдохновлен, чтобы написать эту статью. Я буду дальше расширять эту тему в следующих постах.

Спасибо за внимание.
Muchas gracias por su atención.