Merge remote-tracking branch 'origin/patch'

Conflicts:
	Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java
This commit is contained in:
Ryan Kurtz 2023-11-02 12:18:46 -04:00
commit 0e48d6e055
8 changed files with 225 additions and 140 deletions

View File

@ -51,7 +51,7 @@ import ghidra.base.widgets.table.DataTypeTableCellEditor;
import ghidra.dbg.error.DebuggerModelAccessException;
import ghidra.debug.api.target.Target;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.docking.settings.Settings;
import ghidra.docking.settings.*;
import ghidra.framework.model.DomainObject;
import ghidra.framework.model.DomainObjectChangeRecord;
import ghidra.framework.options.AutoOptions;
@ -80,6 +80,7 @@ import ghidra.util.data.DataTypeParser.AllowedDataTypes;
import ghidra.util.exception.CancelledException;
import ghidra.util.table.GhidraTable;
import ghidra.util.table.GhidraTableFilterPanel;
import ghidra.util.table.column.GColumnRenderer;
import ghidra.util.task.TaskMonitor;
public class DebuggerRegistersProvider extends ComponentProviderAdapter
@ -143,33 +144,53 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
protected enum RegisterTableColumns
implements EnumeratedTableColumn<RegisterTableColumns, RegisterRow> {
FAV("Fav", Boolean.class, RegisterRow::isFavorite, RegisterRow::setFavorite, //
FAV("Fav", 1, Boolean.class, RegisterRow::isFavorite, RegisterRow::setFavorite, //
r -> true, SortDirection.DESCENDING),
NUMBER("#", Integer.class, RegisterRow::getNumber),
NAME("Name", String.class, RegisterRow::getName),
VALUE("Value", BigInteger.class, RegisterRow::getValue, RegisterRow::setValue, //
RegisterRow::isValueEditable, SortDirection.ASCENDING),
TYPE("Type", DataType.class, RegisterRow::getDataType, RegisterRow::setDataType, //
NUMBER("#", 1, Integer.class, RegisterRow::getNumber),
NAME("Name", 40, String.class, RegisterRow::getName),
VALUE("Value", 100, BigInteger.class, RegisterRow::getValue, RegisterRow::setValue, //
RegisterRow::isValueEditable, SortDirection.ASCENDING) {
private static final RegisterValueCellRenderer RENDERER =
new RegisterValueCellRenderer();
private static final SettingsDefinition[] DEFS = new SettingsDefinition[] {
FormatSettingsDefinition.DEF_HEX,
};
@Override
public GColumnRenderer<BigInteger> getRenderer() {
return RENDERER;
}
@Override
public SettingsDefinition[] getSettingsDefinitions() {
return DEFS;
}
},
TYPE("Type", 40, DataType.class, RegisterRow::getDataType, RegisterRow::setDataType, //
r -> true, SortDirection.ASCENDING),
REPR("Repr", String.class, RegisterRow::getRepresentation, RegisterRow::setRepresentation, //
REPR("Repr", 100, String.class, RegisterRow::getRepresentation, RegisterRow::setRepresentation, //
RegisterRow::isRepresentationEditable, SortDirection.ASCENDING);
private final String header;
private final int width;
private final Function<RegisterRow, ?> getter;
private final BiConsumer<RegisterRow, Object> setter;
private final Predicate<RegisterRow> editable;
private final Class<?> cls;
private final SortDirection direction;
<T> RegisterTableColumns(String header, Class<T> cls, Function<RegisterRow, T> getter) {
this(header, cls, getter, null, null, SortDirection.ASCENDING);
<T> RegisterTableColumns(String header, int width, Class<T> cls,
Function<RegisterRow, T> getter) {
this(header, width, cls, getter, null, null, SortDirection.ASCENDING);
}
@SuppressWarnings("unchecked")
<T> RegisterTableColumns(String header, Class<T> cls, Function<RegisterRow, T> getter,
<T> RegisterTableColumns(String header, int width, Class<T> cls,
Function<RegisterRow, T> getter,
BiConsumer<RegisterRow, T> setter, Predicate<RegisterRow> editable,
SortDirection direction) {
this.header = header;
this.width = width;
this.cls = cls;
this.getter = getter;
this.setter = (BiConsumer<RegisterRow, Object>) setter;
@ -206,6 +227,11 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
public SortDirection defaultSortDirection() {
return direction;
}
@Override
public int getPreferredWidth() {
return width;
}
}
protected static class RegistersTableModel
@ -387,7 +413,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
}
class RegisterValueCellRenderer extends HexBigIntegerTableCellRenderer {
static class RegisterValueCellRenderer extends HexDefaultGColumnRenderer<BigInteger> {
@Override
public final Component getTableCellRendererComponent(GTableCellRenderingData data) {
super.getTableCellRendererComponent(data);
@ -574,21 +600,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
});
TableColumnModel columnModel = regsTable.getColumnModel();
TableColumn favCol = columnModel.getColumn(RegisterTableColumns.FAV.ordinal());
favCol.setPreferredWidth(1);
TableColumn numCol = columnModel.getColumn(RegisterTableColumns.NUMBER.ordinal());
numCol.setPreferredWidth(1);
TableColumn nameCol = columnModel.getColumn(RegisterTableColumns.NAME.ordinal());
nameCol.setPreferredWidth(40);
TableColumn valCol = columnModel.getColumn(RegisterTableColumns.VALUE.ordinal());
valCol.setCellRenderer(new RegisterValueCellRenderer());
valCol.setCellEditor(new HexBigIntegerTableCellEditor());
valCol.setPreferredWidth(100);
TableColumn typeCol = columnModel.getColumn(RegisterTableColumns.TYPE.ordinal());
typeCol.setCellEditor(new RegisterDataTypeEditor());
typeCol.setPreferredWidth(50);
TableColumn reprCol = columnModel.getColumn(RegisterTableColumns.REPR.ordinal());
reprCol.setPreferredWidth(100);
}
@Override

View File

@ -21,8 +21,10 @@ import java.util.function.Predicate;
import docking.widgets.table.ColumnSortState.SortDirection;
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
import ghidra.docking.settings.Settings;
import ghidra.docking.settings.SettingsDefinition;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.util.table.column.GColumnRenderer;
/**
* A table model whose columns are described using an {@link Enum}.
@ -106,6 +108,26 @@ public class DefaultEnumeratedColumnTableModel<C extends Enum<C> & EnumeratedTab
default public SortDirection defaultSortDirection() {
return SortDirection.ASCENDING;
}
default public int getPreferredWidth() {
return -1;
}
/**
* Because of limitations with Java generics and Enumerations, type checking cannot be
* guaranteed here. The user must ensure that any returned by {@link #getValueOf(Object)}
* can be accepted by the renderer returned here. The framework will perform an unchecked
* cast of the renderer.
*
* @return the renderer
*/
default public GColumnRenderer<?> getRenderer() {
return null;
}
default public SettingsDefinition[] getSettingsDefinitions() {
return null;
}
}
private final List<R> modelData = new ArrayList<>();
@ -167,6 +189,26 @@ public class DefaultEnumeratedColumnTableModel<C extends Enum<C> & EnumeratedTab
ServiceProvider serviceProvider) {
col.setValueOf(row, value);
}
@Override
@SuppressWarnings("unchecked")
public GColumnRenderer<Object> getColumnRenderer() {
return (GColumnRenderer<Object>) col.getRenderer();
}
@Override
public int getColumnPreferredWidth() {
return col.getPreferredWidth();
}
@Override
public SettingsDefinition[] getSettingsDefinitions() {
SettingsDefinition[] defs = col.getSettingsDefinitions();
if (defs != null) {
return defs;
}
return super.getSettingsDefinitions();
}
}
@Override

View File

@ -52,6 +52,7 @@ public class HexBigIntegerTableCellEditor extends AbstractCellEditor implements
input.setHexMode();
input.setAllowsHexPrefix(false);
input.setShowNumberMode(true);
input.setHorizontalAlignment(JTextField.RIGHT);
if (value != null) {
input.setValue((BigInteger) value);

View File

@ -1,49 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.widgets.table;
import java.awt.Component;
import java.math.BigInteger;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import ghidra.docking.settings.Settings;
import ghidra.util.table.column.AbstractGColumnRenderer;
public class HexBigIntegerTableCellRenderer extends AbstractGColumnRenderer<BigInteger> {
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(fixedWidthFont);
}
protected String formatBigInteger(BigInteger value) {
return value == null ? "??" : value.toString(16);
}
@Override
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
super.getTableCellRendererComponent(data);
setText(formatBigInteger((BigInteger) data.getValue()));
return this;
}
// TODO: Seems the filter model does not heed this....
@Override
public String getFilterString(BigInteger t, Settings settings) {
return formatBigInteger(t);
}
}

View File

@ -0,0 +1,35 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.widgets.table;
import ghidra.docking.settings.FormatSettingsDefinition;
import ghidra.docking.settings.Settings;
import ghidra.util.table.column.AbstractGColumnRenderer;
public class HexDefaultGColumnRenderer<T extends Number> extends AbstractGColumnRenderer<T> {
private final static FormatSettingsDefinition INTEGER_RADIX_SETTING =
FormatSettingsDefinition.DEF_HEX;
@Override
protected int getRadix(Settings settings) {
return INTEGER_RADIX_SETTING.getRadix(settings);
}
@Override
public String getFilterString(Number t, Settings settings) {
return formatNumber(t, settings);
}
}

View File

@ -50,10 +50,10 @@ public abstract class AbstractDynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOU
protected static final FloatingPointPrecisionSettingsDefinition FLOATING_POINT_PRECISION_SETTING =
FloatingPointPrecisionSettingsDefinition.DEF;
protected static SettingsDefinition[] INTEGER_SETTINGS_DEFINITIONS =
protected static final SettingsDefinition[] INTEGER_SETTINGS_DEFINITIONS =
new SettingsDefinition[] { INTEGER_RADIX_SETTING, INTEGER_SIGNEDNESS_MODE_SETTING };
protected static SettingsDefinition[] FLOATING_POINT_SETTINGS_DEFINITIONS =
protected static final SettingsDefinition[] FLOATING_POINT_SETTINGS_DEFINITIONS =
new SettingsDefinition[] { FLOATING_POINT_PRECISION_SETTING };
private boolean hasConfiguredDefaultSettings = false;

View File

@ -34,8 +34,8 @@ import ghidra.util.*;
import ghidra.util.exception.AssertException;
/**
* A default table cell renderer that relies on the <code>toString()</code> method
* when rendering the cells of the table.
* A default table cell renderer that relies on the <code>toString()</code> method when rendering
* the cells of the table.
*/
public class GTableCellRenderer extends AbstractGCellRenderer implements TableCellRenderer {
@ -84,6 +84,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
/**
* Constructs a new GTableCellRenderer using the specified font.
*
* @param f the font to use when rendering text in the table cells
*/
public GTableCellRenderer(Font f) {
@ -93,6 +94,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
/**
* Return the cell renderer text
*
* @param value Cell object value
* @return A string interpretation of value; generated by calling value.toString()
*/
@ -101,8 +103,8 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
}
/**
* Satisfies the Java {@link javax.swing.table.TableCellRenderer} interface; retrieves
* column data via a GTableCellRenderingData object, and defers painting to
* Satisfies the Java {@link javax.swing.table.TableCellRenderer} interface; retrieves column
* data via a GTableCellRenderingData object, and defers painting to
* {@link #getTableCellRendererComponent(GTableCellRenderingData)}.
* <p>
* This is marked <code>final</code> to redirect subclasses to the enhanced method,
@ -111,8 +113,9 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
* Throws an AssertException if the table this renderer is used with is not a
* {@link docking.widgets.table.GTable} instance.
*
* @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
* @see #getTableCellRendererComponent(GTableCellRenderingData)
* @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable,
* java.lang.Object, boolean, boolean, int, int)
* @see #getTableCellRendererComponent(GTableCellRenderingData)
*/
@Override
public final Component getTableCellRendererComponent(JTable table, Object value,
@ -144,8 +147,9 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
/**
* Provide basic cell rendering -- setting foreground and background colors, font, text,
* alignment, drop color, and border. Additional data that may be of use to the renderer
* is passed through the {@link docking.widgets.table.GTableCellRenderingData} object.
* alignment, drop color, and border. Additional data that may be of use to the renderer is
* passed through the {@link docking.widgets.table.GTableCellRenderingData} object.
*
* @param data Context data used in the rendering of a data cell.
* @return The component used for drawing the table cell.
*/
@ -199,8 +203,21 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
setFont(defaultFont);
}
protected int getRadix(Settings settings) {
return INTEGER_RADIX_SETTING.getRadix(settings);
}
protected SignednessFormatMode getSignMode(Settings settings) {
return INTEGER_SIGNEDNESS_MODE_SETTING.getFormatMode(settings);
}
protected int getPrecision(Settings settings) {
return FLOATING_POINT_PRECISION_SETTING.getPrecision(settings);
}
/**
* Format a Number per the Settings parameters.
*
* @param value the number to format
* @param settings settings controlling the display of the Number parameter
* @return a formatted representation of the Number value
@ -208,8 +225,8 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
protected String formatNumber(Number value, Settings settings) {
if (NumericUtilities.isIntegerType(value)) {
int radix = INTEGER_RADIX_SETTING.getRadix(settings);
SignednessFormatMode signMode = INTEGER_SIGNEDNESS_MODE_SETTING.getFormatMode(settings);
int radix = getRadix(settings);
SignednessFormatMode signMode = getSignMode(settings);
long number = value.longValue();
return NumericUtilities.formatNumber(number, radix, signMode);
}
@ -219,18 +236,18 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
if (number.isNaN() || number.isInfinite()) {
return Character.toString('\u221e'); // infinity symbol
}
int precision = FLOATING_POINT_PRECISION_SETTING.getPrecision(settings);
int precision = getPrecision(settings);
return getFormatter(precision).format(number);
}
if (value instanceof BigInteger) {
int radix = INTEGER_RADIX_SETTING.getRadix(settings);
int radix = getRadix(settings);
return ((BigInteger) value).toString(radix);
}
if (value instanceof BigDecimal) {
int precision = FLOATING_POINT_PRECISION_SETTING.getPrecision(settings);
int precision = getPrecision(settings);
DecimalFormat formatter = getFormatter(precision);
formatter.format(value);

View File

@ -34,28 +34,30 @@ import ghidra.util.SystemUtilities;
/**
* TextField for entering integer numbers, either in decimal or hex.
*
* <P> This field does continuous checking, so
* you can't enter a bad value.
* <P>
* This field does continuous checking, so you can't enter a bad value.
*
* <P> Internally, values are maintained using BigIntegers so this field can
* contain numbers as large as desired. There are convenience methods for getting the value as
* either an int or long. If using these convenience methods, you should also set the max allowed
* value so that users can't enter a value larger than can be represented by the {@link #getIntValue()}
* or {@link #getLongValue()} methods as appropriate.
* <P>
* Internally, values are maintained using BigIntegers so this field can contain numbers as large as
* desired. There are convenience methods for getting the value as either an int or long. If using
* these convenience methods, you should also set the max allowed value so that users can't enter a
* value larger than can be represented by the {@link #getIntValue()} or {@link #getLongValue()}
* methods as appropriate.
*
* <P> There are several configuration options as follows:
* <P>
* There are several configuration options as follows:
* <UL>
* <LI> Allows negative numbers - either support all integer numbers or just non-negative
* numbers. See {@link #setAllowNegativeValues(boolean)} </LI>
* <LI> Allows hex prefix - If this mode is on, then hex mode is turned on and off automatically
* depending whether or not the text starts with 0x. Otherwise, the hex/decimal mode is set externally
* (either programmatically or pressing &lt;CTRL&gt; M) and the user is restricted to the numbers/letters
* appropriate for that mode. See {@link #setAllowsHexPrefix(boolean)}</LI>
* <LI> Have a max value - a max value can be set (must be positive) such that the user can not type a
* number whose absolute value is greater than the max. Otherwise, the value is unlimited if max is
* null/unspecified. See {@link #setMaxValue(BigInteger)}</LI>
* <LI> Show the number mode as hint text - If on either "Hex" or "Dec" is displayed lightly in the
* bottom right portion of the text field. See {@link #setShowNumberMode(boolean)}</LI>
* <LI>Allows negative numbers - either support all integer numbers or just non-negative numbers.
* See {@link #setAllowNegativeValues(boolean)}</LI>
* <LI>Allows hex prefix - If this mode is on, then hex mode is turned on and off automatically
* depending whether or not the text starts with 0x. Otherwise, the hex/decimal mode is set
* externally (either programmatically or pressing &lt;CTRL&gt; M) and the user is restricted to the
* numbers/letters appropriate for that mode. See {@link #setAllowsHexPrefix(boolean)}</LI>
* <LI>Have a max value - a max value can be set (must be positive) such that the user can not type
* a number whose absolute value is greater than the max. Otherwise, the value is unlimited if max
* is null/unspecified. See {@link #setMaxValue(BigInteger)}</LI>
* <LI>Show the number mode as hint text - If on either "Hex" or "Dec" is displayed lightly in the
* bottom right portion of the text field. See {@link #setShowNumberMode(boolean)}</LI>
* </UL>
*
*/
@ -92,9 +94,9 @@ public class IntegerTextField {
* Creates a new IntegerTextField with the specified number of columns and an initial value
*
* @param columns the number of columns to display in the JTextField.
* @param initialValue the initial value. This constructor takes an initialValue as a long. If
* you need a value that is bigger (or smaller) than can be specified as a long, then use
* the constructor that takes a BigInteger as an initial value.
* @param initialValue the initial value. This constructor takes an initialValue as a long. If
* you need a value that is bigger (or smaller) than can be specified as a long, then
* use the constructor that takes a BigInteger as an initial value.
*/
public IntegerTextField(int columns, long initialValue) {
this(columns, BigInteger.valueOf(initialValue));
@ -159,11 +161,13 @@ public class IntegerTextField {
/**
* Returns the current value as an int.
*
* <P> If the field has no current value, 0 will be returned. If
* the value is bigger (or smaller) than an int, it will be cast to an int.
* <P>
* If the field has no current value, 0 will be returned. If the value is bigger (or smaller)
* than an int, it will be cast to an int.
*
* <P> If using this method, it is highly recommended that you set the max value to {@link Integer#MAX_VALUE}
* or lower.
* <P>
* If using this method, it is highly recommended that you set the max value to
* {@link Integer#MAX_VALUE} or lower.
*
* @return the current value as an int. Or 0 if there is no value
* @throws ArithmeticException if the value in this field will not fit into an int
@ -179,11 +183,13 @@ public class IntegerTextField {
/**
* Returns the current value as a long.
*
* <P> If the field has no current value, 0 will be returned. If
* the value is bigger (or smaller) than an long, it will be cast to a long.
* <P>
* If the field has no current value, 0 will be returned. If the value is bigger (or smaller)
* than an long, it will be cast to a long.
*
* <P> If using this method, it is highly recommended that you set the max value to {@link Long#MAX_VALUE}
* or lower.
* <P>
* If using this method, it is highly recommended that you set the max value to
* {@link Long#MAX_VALUE} or lower.
*
* @return the current value as a long. Or 0 if there is no value
* @throws ArithmeticException if the value in this field will not fit into a long
@ -215,13 +221,13 @@ public class IntegerTextField {
}
/**
* Sets the field to the given text. The text must be a properly formated string that is
* a value that is valid for this field. If the field is set to not allow "0x" prefixes, then
* the input string cannot start with 0x and furthermore, if the field is in decimal mode, then
* input string cannot take in hex digits a-f. On the other hand, if "0x" prefixes are allowed,
* then the input string can be either a decimal number or a hex number depending on if the
* input string starts with "0x". In this case, the field's hex mode will be set to match
* the input text. If the text is not valid, the field will not change.
* Sets the field to the given text. The text must be a properly formated string that is a value
* that is valid for this field. If the field is set to not allow "0x" prefixes, then the input
* string cannot start with 0x and furthermore, if the field is in decimal mode, then input
* string cannot take in hex digits a-f. On the other hand, if "0x" prefixes are allowed, then
* the input string can be either a decimal number or a hex number depending on if the input
* string starts with "0x". In this case, the field's hex mode will be set to match the input
* text. If the text is not valid, the field will not change.
*
* @param text the value as text to set on this field
* @return true if the set was successful
@ -233,7 +239,7 @@ public class IntegerTextField {
}
/**
* Sets the value of the field to the given value. A null value will clear the field.
* Sets the value of the field to the given value. A null value will clear the field.
*
* @param newValue the new value or null.
*/
@ -259,8 +265,9 @@ public class IntegerTextField {
/**
* Sets the radix mode to Hex.
*
* <P> If the field is currently in decimal mode, the current text will be
* change from displaying the current value from decimal to hex.
* <P>
* If the field is currently in decimal mode, the current text will be change from displaying
* the current value from decimal to hex.
*/
public void setHexMode() {
BigInteger currentValue = getValue();
@ -271,8 +278,9 @@ public class IntegerTextField {
/**
* Sets the mode to Decimal.
*
* <P> If the field is currently in hex mode, the current text will be
* change from displaying the current value from hex to decimal.
* <P>
* If the field is currently in hex mode, the current text will be change from displaying the
* current value from hex to decimal.
*/
public void setDecimalMode() {
BigInteger currentValue = getValue();
@ -283,12 +291,12 @@ public class IntegerTextField {
/**
* Sets whether on not the field supports the 0x prefix.
*
* <P> If 0x is supported, hex numbers
* will be displayed with the 0x prefix. Also, when typing, you must type 0x first to enter
* a hex number, otherwise it will only allow digits 0-9. If the 0x prefix option is turned
* off, then hex numbers are displayed without the 0x prefix and you can't change the decimal/hex
* mode by typing 0x. The field will either be in decimal or hex mode and the typed text
* will be interpreted appropriately for the mode.
* <P>
* If 0x is supported, hex numbers will be displayed with the 0x prefix. Also, when typing, you
* must type 0x first to enter a hex number, otherwise it will only allow digits 0-9. If the 0x
* prefix option is turned off, then hex numbers are displayed without the 0x prefix and you
* can't change the decimal/hex mode by typing 0x. The field will either be in decimal or hex
* mode and the typed text will be interpreted appropriately for the mode.
*
* @param allowsHexPrefix true to use the 0x convention for hex.
*/
@ -333,9 +341,10 @@ public class IntegerTextField {
}
/**
* Returns the current maximum allowed value. Null indicates that there is no maximum value.
* If negative values are permitted (see {@link #setAllowNegativeValues(boolean)}) this value
* will establish the upper and lower limit of the absolute value.
* Returns the current maximum allowed value. Null indicates that there is no maximum value. If
* negative values are permitted (see {@link #setAllowNegativeValues(boolean)}) this value will
* establish the upper and lower limit of the absolute value.
*
* @return the current maximum value allowed.
*/
public BigInteger getMaxValue() {
@ -343,7 +352,7 @@ public class IntegerTextField {
}
/**
* Sets the maximum allowed value. The maximum must be a positive number. Null indicates that
* Sets the maximum allowed value. The maximum must be a positive number. Null indicates that
* there is no maximum value.
* <p>
* If negative values are permitted (see {@link #setAllowNegativeValues(boolean)}) this value
@ -451,6 +460,15 @@ public class IntegerTextField {
textField.selectAll();
}
/**
* Sets the horizontal alignment of the JTextField
*
* @param alignment the alignment as in {@link JTextField#setHorizontalAlignment(int)}
*/
public void setHorizontalAlignment(int alignment) {
textField.setHorizontalAlignment(alignment);
}
private String computeTextForValue(BigInteger value) {
if (value == null) {
return "";
@ -724,7 +742,13 @@ public class IntegerTextField {
Dimension size = getSize();
Insets insets = getInsets();
int x = size.width - insets.right - hintWidth;
int x;
if (getHorizontalAlignment() == RIGHT) {
x = insets.left;
}
else {
x = size.width - insets.right - hintWidth;
}
int y = size.height - insets.bottom - 1;
String mode = isHexMode ? "Hex" : "Dec";
GraphicsUtils.drawString(this, g, mode, x, y);