com.lyonesgamer.propertygrid.properties.IntegerProperty Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JPropertyGrid Show documentation
Show all versions of JPropertyGrid Show documentation
A property editor component for Swing.
The newest version!
package com.lyonesgamer.propertygrid.properties;
import com.lyonesgamer.propertygrid.PGProperty;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import java.awt.*;
import java.util.*;
import java.util.List;
/**
* A property for whole numbers. Uses long to store them.
*
* The property can be unsigned, which disallows the value from being negative. However, because Java doesn't support
* unsigned longs, the maximum value is still {@link Long#MAX_VALUE}.
*
* @author Tristan Patch
* @since 1.0
*/
public class IntegerProperty extends PGProperty {
/**
* The value of the property.
*/
protected long value;
/**
* The minimum value of the spinner. Defaults to {@link Long#MIN_VALUE}.
*/
protected long minimum = Long.MIN_VALUE;
/**
* The maximum value of the spinner. Defaults to {@link Long#MAX_VALUE}.
*/
protected long maximum = Long.MAX_VALUE;
/**
* The editor to use.
*/
protected IntegerEditor editor = new IntegerEditor();
/**
* The renderer to use.
*/
protected IntegerRenderer renderer = new IntegerRenderer();
/**
* Creates a new property.
*
* @param name The name of the property in the grid.
* @param value The initial value of the property.
*/
public IntegerProperty(String name, long value) {
super(name);
this.value = value;
}
/**
* The minimum value this property can hold.
* @return The minimum value.
*/
public long getMinimum() {
return minimum;
}
/**
* Sets the minimum value this property can hold. The spinner will go no lower than this, and values are clamped both
* during this call and on following setValue* calls.
* @param minimum The new minimum.
*/
public void setMinimum(long minimum) {
if (value < minimum)
value = minimum;
this.minimum = minimum;
}
/**
* The maximum value this property can hold.
* @return The maximum value.
*/
public long getMaximum() {
return maximum;
}
/**
* Sets the maximum value this property can hold. The spinner will go no higher than this, and values are clamped both
* during this call and on following setValue* calls.
* @param maximum The new maximum.
*/
public void setMaximum(long maximum) {
if (value > maximum)
value = maximum;
this.maximum = maximum;
}
@Override
protected void doAfterAdded() {}
/**
* Validates the passed value. If the property is signed, the value is valid. If the property is unsigned, the value
* is valid iff the value is positive or zero.
*
* @param value The value to be validated.
* @return If the value is valid.
*/
@Override
public boolean onValidateValue(Long value) {
return value >= minimum && value <= maximum;
}
@Override
public void onSetValue(Long value) {
if (parent != null)
parent.firePropertyChangeEvent(this, value);
this.value = value;
}
@Override
public void setValueFromString(String value) {
setValue(Long.parseLong(value));
}
@Override
public void setValueFromLong(long value) {
setValue(value);
}
@Override
public Long getValue() {
return value;
}
@Override
public Long stringToValue(String value) {
try {
long value2 = Long.parseLong(value);
if (!onValidateValue(value2))
value2 = 0;
return value2;
} catch (NumberFormatException e) {
return -1L;
}
}
@Override
public Long longToValue(long value) {
if (!onValidateValue(value))
value = 0;
return value;
}
@Override
public String valueToString(Long value) {
return value.toString();
}
@Override
public PGCellRenderer getRenderer() {
return renderer;
}
@Override
public PGCellEditor getEditor() {
return editor;
}
protected class IntegerEditor extends JSpinner implements PGCellEditor {
//No need to use an EventListenerList if we only have one listener type
protected final List listeners = new ArrayList<>();
protected final Set listenersToRemove = new HashSet<>();
@Override
@SuppressWarnings("all") //I'd think "boxing" would be the proper one here, but it doesn't work
public Component getTableCellEditorComponent(JTable table, Object passedValue, boolean isSelected, int row, int column) {
//IDEs may complain that this is unnecessary boxing, but it's necessary to get the constructor to use Number
//instead of converting to double
SpinnerModel model = new SpinnerNumberModel(new Long(value), new Long(minimum), new Long(maximum), new Long(1));
this.setModel(model);
return this;
}
@Override
public Object getCellEditorValue() {
return value;
}
@Override
public boolean isCellEditable(EventObject anEvent) {
return !disabled;
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
@Override
public boolean stopCellEditing() {
onSetValue((Long)this.getValue());
fireEditingStopped();
return true;
}
@Override
public void cancelCellEditing() {
fireEditingCancelled();
}
public void fireEditingCancelled() {
ChangeEvent event = new ChangeEvent(this);
for (CellEditorListener l : listeners)
l.editingCanceled(event);
doClearListeners();
}
public void fireEditingStopped() {
ChangeEvent event = new ChangeEvent(this);
for (CellEditorListener l : listeners)
l.editingStopped(event);
doClearListeners();
}
@Override
public void addCellEditorListener(CellEditorListener l) {
listeners.add(l);
}
@Override
public void removeCellEditorListener(CellEditorListener l) {
listenersToRemove.add(l);
}
protected void doClearListeners() {
listeners.removeAll(listenersToRemove);
listenersToRemove.clear();
}
}
protected class IntegerRenderer extends JLabel implements PGCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
setText(valueToString(getValue()));
setToolTipText(helpString);
return this;
}
}
}