diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bean/FixedBitSizeValueField.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bean/FixedBitSizeValueField.java index 6f40b946b3..a3ee981ea1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bean/FixedBitSizeValueField.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bean/FixedBitSizeValueField.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +17,8 @@ package ghidra.app.util.bean; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.math.BigInteger; import java.util.ArrayList; @@ -28,12 +28,11 @@ import javax.swing.event.ChangeListener; import javax.swing.text.*; import docking.widgets.SmallBorderButton; - import resources.ResourceManager; /** - * + * */ public class FixedBitSizeValueField extends JPanel { private static final ImageIcon DROP_DOWN_MENU_ICON = ResourceManager.loadImage("images/menu16.gif"); @@ -46,13 +45,13 @@ public class FixedBitSizeValueField extends JPanel { private BigInteger maxUnsignedValue; private BigInteger maxSignedValue; private BigInteger minSignedValue; - + private BigInteger maxValue; private BigInteger minValue; protected JPopupMenu popupMenu; - protected java.util.List menuItems = new ArrayList(); - protected java.util.List listeners = new ArrayList(); - + protected java.util.List menuItems = new ArrayList<>(); + protected java.util.List listeners = new ArrayList<>(); + public FixedBitSizeValueField(int bitSize, boolean includeFormatButton, boolean leftJustify) { setLayout(new BorderLayout()); valueField = new JTextField(); @@ -65,49 +64,50 @@ public class FixedBitSizeValueField extends JPanel { add(buttonPanel, BorderLayout.EAST); menuButton.setFocusable(false); menuButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { showPopup(); } }); - + } add(valueField, BorderLayout.CENTER); Font f2 = new Font("monospaced", Font.PLAIN, 14); valueField.setFont(f2); valueField.setMargin(new Insets(0,2,0,2)); - + createPopup(); - + doc = new PlainDocument(); docFilter = new MyDocFilter(); - doc.setDocumentFilter(docFilter); - valueField.setDocument(doc); - if (!leftJustify) { - valueField.setHorizontalAlignment(SwingConstants.TRAILING); - } + doc.setDocumentFilter(docFilter); + valueField.setDocument(doc); + if (!leftJustify) { + valueField.setHorizontalAlignment(SwingConstants.TRAILING); + } - setBitSize(bitSize); + setBitSize(bitSize); setFormat(16, false); } public void setBitSize(int bitSize) { - BigInteger b = BigInteger.valueOf(2); + BigInteger b = BigInteger.valueOf(2); maxSignedValue = b.pow(bitSize-1).subtract(BigInteger.ONE); minSignedValue = b.pow(bitSize-1).negate(); maxUnsignedValue = b.pow(bitSize).subtract(BigInteger.ONE); maxValue = signed ? maxSignedValue : maxUnsignedValue; minValue = signed ? minSignedValue : BigInteger.ZERO; - setValue(getValue()); + setValue(getValue()); } - + public void addChangeListener(ChangeListener listener) { listeners.add(listener); } public void removeChangeListener(ChangeListener listener) { listeners.remove(listener); } - + public boolean processText() { String text = valueField.getText().trim(); if (text.length() == 0) { @@ -135,12 +135,13 @@ public class FixedBitSizeValueField extends JPanel { protected void createPopup() { ActionListener actionListener = new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { JCheckBoxMenuItem item = (JCheckBoxMenuItem)e.getSource(); menuActivated(item); } }; - + popupMenu = new JPopupMenu(); menuItems.add(new JCheckBoxMenuItem("Hex, Unsigned")); menuItems.add(new JCheckBoxMenuItem("Hex, Signed")); @@ -181,7 +182,7 @@ public class FixedBitSizeValueField extends JPanel { } } protected void menuActivated(JCheckBoxMenuItem item) { - + int index = menuItems.indexOf(item); switch(index) { case 0: @@ -206,7 +207,7 @@ public class FixedBitSizeValueField extends JPanel { } public void setFormat(int radix, boolean signed) { BigInteger curValue = getValue(valueField.getText()); - + this.radix = radix; this.signed = signed; updatePopup(); @@ -214,7 +215,7 @@ public class FixedBitSizeValueField extends JPanel { maxValue = signed ? maxSignedValue : maxUnsignedValue; minValue = signed ? minSignedValue : BigInteger.ZERO; - + if (curValue != null) { BigInteger newValue = curValue; if (signed) { @@ -257,7 +258,7 @@ public class FixedBitSizeValueField extends JPanel { break; } menuButton.setText(buttonText); - + } public boolean setValue(BigInteger value) { @@ -316,7 +317,7 @@ public class FixedBitSizeValueField extends JPanel { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { - } + } JFrame f = new JFrame("Test"); JPanel panel = new JPanel(new BorderLayout()); FixedBitSizeValueField rf = new FixedBitSizeValueField(8, true, false); @@ -325,31 +326,44 @@ public class FixedBitSizeValueField extends JPanel { f.pack(); f.setVisible(true); } - - + + String normalizeText(String s) { + s = s.strip(); + if (radix == 16 && (s.startsWith("0x") || s.startsWith("0X"))) { + return s.substring(2); + } + if (radix == 2 && (s.startsWith("0b") || s.startsWith("0B"))) { + return s.substring(2); + } + + return s; + } + + class MyDocFilter extends DocumentFilter { - /** - * @see javax.swing.text.DocumentFilter#insertString(FilterBypass, int, String, AttributeSet) - */ - @Override - public void insertString(FilterBypass fb, int offset, String string, - AttributeSet attr) throws BadLocationException { + /** + * @see javax.swing.text.DocumentFilter#insertString(FilterBypass, int, String, AttributeSet) + */ + @Override + public void insertString(FilterBypass fb, int offset, String string, + AttributeSet attr) throws BadLocationException { String oldText = doc.getText(0, doc.getLength()); - fb.insertString(offset, string, attr); + string = normalizeText(string); + fb.insertString(offset, string, attr); if (!processText()) { fb.replace(0, doc.getLength(), oldText, attr); valueField.setCaretPosition(offset); } valueChanged(); - } + } - /** - * @see javax.swing.text.DocumentFilter#remove(FilterBypass, int, int) - */ - @Override - public void remove(FilterBypass fb, int offset, int length) - throws BadLocationException { + /** + * @see javax.swing.text.DocumentFilter#remove(FilterBypass, int, int) + */ + @Override + public void remove(FilterBypass fb, int offset, int length) + throws BadLocationException { String oldText = doc.getText(0, doc.getLength()); fb.remove(offset, length); @@ -358,23 +372,24 @@ public class FixedBitSizeValueField extends JPanel { valueField.setCaretPosition(offset); } valueChanged(); - } + } - /** - * @see javax.swing.text.DocumentFilter#replace(FilterBypass, int, int, String, AttributeSet) - */ - @Override - public void replace(FilterBypass fb, int offset, int length, - String text, AttributeSet attrs) throws BadLocationException { + /** + * @see javax.swing.text.DocumentFilter#replace(FilterBypass, int, int, String, AttributeSet) + */ + @Override + public void replace(FilterBypass fb, int offset, int length, + String text, AttributeSet attrs) throws BadLocationException { String oldText = doc.getText(0, doc.getLength()); - fb.replace(offset, length, text, attrs); + text = normalizeText(text); + fb.replace(offset, length, text, attrs); if (!processText()) { fb.replace(0, doc.getLength(), oldText, attrs); valueField.setCaretPosition(offset); } valueChanged(); - } - } + } + } public Component getTextComponent() { @@ -396,4 +411,4 @@ public class FixedBitSizeValueField extends JPanel { } - +