package nf.co.haxter.gui.tabs;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.List;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.ListSelectionModel;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import nf.co.haxter.gui.layouts.WrapLayout;
import nf.co.haxter.util.BytecodeUtils;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTabbedPane;
import java.awt.GridLayout;
import javax.swing.JTextField;
import static nf.co.haxter.util.MiscUtils.parse;
import static nf.co.haxter.util.MiscUtils.parseBack;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
public class FieldInfoPanel extends JPanel {
private JList<FieldNode> list;
private DefaultListModel<FieldNode> fieldModel;
private JTabbedPane tabbedPane;
private JTextField textFieldName;
private JTextField textFieldDescriptor;
private JTextField textFieldSignature;
private JTextField textFieldInitialValue;
private JComboBox comboBoxInitialValueType;
private final ButtonGroup buttonGroup = new ButtonGroup();
private JRadioButton rdbtnPublic;
private JRadioButton rdbtnProtected;
private JRadioButton rdbtnPrivate;
private JCheckBox chckbxStatic;
private JCheckBox chckbxFinal;
private JCheckBox chckbxTransient;
private JCheckBox chckbxVolatile;
private JCheckBox chckbxSynthetic;
private JCheckBox chckbxEnumConstant;
private JRadioButton rdbtnDefault;
/**
* Create the panel.
*/
public FieldInfoPanel(final ClassNode cNode) {
setLayout(new BorderLayout(0, 0));
JSplitPane splitPane = new JSplitPane();
add(splitPane);
JPanel panelFieldListings = new JPanel();
splitPane.setLeftComponent(panelFieldListings);
panelFieldListings.setLayout(new BorderLayout(0, 0));
JLabel lblFields = new JLabel("Fields: ");
panelFieldListings.add(lblFields, BorderLayout.NORTH);
list = new JList<FieldNode>();
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> paramJList, Object paramObject,
int paramInt, boolean paramBoolean1, boolean paramBoolean2) {
Component renderer =
super.getListCellRendererComponent(paramJList, paramObject, paramInt, paramBoolean1,
paramBoolean2);
if (renderer instanceof JLabel && paramObject instanceof FieldNode) {
FieldNode fn = (FieldNode) paramObject;
((JLabel) renderer).setText(fn.name + ' ' + fn.desc);
}
return renderer;
}
});
fieldModel = new DefaultListModel<FieldNode>();
for (FieldNode fn : (List<FieldNode>) cNode.fields) {
fieldModel.addElement(fn);
}
list.setModel(fieldModel);
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent paramListSelectionEvent) {
onSelected(list.getSelectedValue());
}
});
panelFieldListings.add(list);
JPanel panelFieldInfo = new JPanel();
splitPane.setRightComponent(panelFieldInfo);
panelFieldInfo.setLayout(new BorderLayout(0, 0));
JPanel panelListControls = new JPanel();
panelListControls.setBorder(new LineBorder(new Color(0, 0, 0)));
panelFieldInfo.add(panelListControls, BorderLayout.NORTH);
panelListControls.setLayout(new WrapLayout());
JButton btnAddField = new JButton("Add Field...");
panelListControls.add(btnAddField);
JButton btnRemoveField = new JButton("Remove Field");
btnRemoveField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent paramActionEvent) {
FieldNode fn = list.getSelectedValue();
if (fn != null) {
fieldModel.removeElement(fn);
cNode.fields.remove(fn);
}
}
});
panelListControls.add(btnRemoveField);
JButton btnUpdateField = new JButton("Update Field");
panelListControls.add(btnUpdateField);
JPanel panelFieldStuff = new JPanel();
panelFieldInfo.add(panelFieldStuff);
panelFieldStuff.setLayout(new BorderLayout(0, 0));
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setVisible(false);
panelFieldStuff.add(tabbedPane, BorderLayout.CENTER);
JPanel panelNameData = new JPanel();
tabbedPane.addTab("Name Data", null, panelNameData, null);
panelNameData.setLayout(new GridLayout(0, 2, 0, 0));
JLabel lblName = new JLabel("Name: ");
panelNameData.add(lblName);
textFieldName = new JTextField();
panelNameData.add(textFieldName);
textFieldName.setColumns(10);
JLabel lblDescriptor = new JLabel("Descriptor: ");
panelNameData.add(lblDescriptor);
textFieldDescriptor = new JTextField();
panelNameData.add(textFieldDescriptor);
textFieldDescriptor.setColumns(10);
JLabel lblSignature = new JLabel("Signature: ");
panelNameData.add(lblSignature);
textFieldSignature = new JTextField();
panelNameData.add(textFieldSignature);
textFieldSignature.setColumns(10);
JLabel lblInitialValue = new JLabel("Initial Value: ");
panelNameData.add(lblInitialValue);
JPanel panelInitialValueInfo = new JPanel();
panelNameData.add(panelInitialValueInfo);
panelInitialValueInfo.setLayout(new BorderLayout(0, 0));
textFieldInitialValue = new JTextField();
panelInitialValueInfo.add(textFieldInitialValue, BorderLayout.CENTER);
textFieldInitialValue.setColumns(10);
comboBoxInitialValueType = new JComboBox();
comboBoxInitialValueType.setModel(new DefaultComboBoxModel(InitialValueType.values()));
panelInitialValueInfo.add(comboBoxInitialValueType, BorderLayout.EAST);
JPanel panelModifiers = new JPanel();
tabbedPane.addTab("Modifiers", null, panelModifiers, null);
panelModifiers.setLayout(new BorderLayout(0, 0));
JPanel panelAccessModifiers = new JPanel();
panelModifiers.add(panelAccessModifiers, BorderLayout.WEST);
panelAccessModifiers.setLayout(new BoxLayout(panelAccessModifiers, BoxLayout.Y_AXIS));
rdbtnPublic = new JRadioButton("PUBLIC");
buttonGroup.add(rdbtnPublic);
panelAccessModifiers.add(rdbtnPublic);
rdbtnProtected = new JRadioButton("PROTECTED");
buttonGroup.add(rdbtnProtected);
panelAccessModifiers.add(rdbtnProtected);
rdbtnPrivate = new JRadioButton("PRIVATE");
buttonGroup.add(rdbtnPrivate);
panelAccessModifiers.add(rdbtnPrivate);
rdbtnDefault = new JRadioButton("DEFAULT");
buttonGroup.add(rdbtnDefault);
panelAccessModifiers.add(rdbtnDefault);
JPanel panelOtherModifiers = new JPanel();
panelModifiers.add(panelOtherModifiers);
panelOtherModifiers.setLayout(new WrapLayout());
chckbxStatic = new JCheckBox("STATIC");
panelOtherModifiers.add(chckbxStatic);
chckbxFinal = new JCheckBox("FINAL");
panelOtherModifiers.add(chckbxFinal);
chckbxTransient = new JCheckBox("TRANSIENT");
panelOtherModifiers.add(chckbxTransient);
chckbxVolatile = new JCheckBox("VOLATILE");
panelOtherModifiers.add(chckbxVolatile);
chckbxSynthetic = new JCheckBox("SYNTHETIC");
panelOtherModifiers.add(chckbxSynthetic);
chckbxEnumConstant = new JCheckBox("ENUM CONSTANT");
panelOtherModifiers.add(chckbxEnumConstant);
}
private void onSelected(FieldNode fn) {
if (fn != null) {
this.tabbedPane.setVisible(true);
this.populateInfo(fn);
} else {
this.tabbedPane.setVisible(false);
}
}
private void populateInfo(FieldNode field) {
textFieldName.setText(parse(field.name));
textFieldDescriptor.setText(parse(field.desc));
textFieldSignature.setText(parse(field.signature));
Object val = field.value;
InitialValueType ivt = InitialValueType.OTHER;
if (val instanceof Integer) {
ivt = InitialValueType.INTEGER;
} else if (val instanceof Long) {
ivt = InitialValueType.LONG;
} else if (val instanceof Float) {
ivt = InitialValueType.FLOAT;
} else if (val instanceof Double) {
ivt = InitialValueType.DOUBLE;
} else if (val instanceof String) {
ivt = InitialValueType.STRING;
}
this.comboBoxInitialValueType.setSelectedItem(ivt);
this.textFieldInitialValue.setText(parse((val == null ? null : val.toString())));
{
boolean isPublic = BytecodeUtils.isPublic(field.access);
boolean isProtected = BytecodeUtils.isProtected(field.access);
boolean isPrivate = BytecodeUtils.isPrivate(field.access);
this.rdbtnPublic.setSelected(isPublic);
this.rdbtnProtected.setSelected(isProtected);
this.rdbtnPrivate.setSelected(isPrivate);
this.rdbtnDefault.setSelected(!isPublic && !isProtected && !isPrivate);
this.chckbxStatic.setSelected(BytecodeUtils.isStatic(field.access));
this.chckbxEnumConstant.setSelected(BytecodeUtils.isEnum(field.access));
this.chckbxFinal.setSelected(BytecodeUtils.isFinal(field.access));
this.chckbxSynthetic.setSelected(BytecodeUtils.isSynthetic(field.access));
this.chckbxTransient.setSelected(BytecodeUtils.isTransient(field.access));
this.chckbxVolatile.setSelected(BytecodeUtils.isVolatile(field.access));
}
}
public void saveField(FieldNode fn) {
{
InitialValueType ivt = (InitialValueType) comboBoxInitialValueType.getSelectedItem();
switch (ivt) {
case DOUBLE:
fn.value = Double.parseDouble(this.textFieldInitialValue.getText());
case FLOAT:
fn.value = Float.parseFloat(this.textFieldInitialValue.getText());
case INTEGER:
fn.value = Integer.parseInt(this.textFieldInitialValue.getText());
case LONG:
fn.value = Long.parseLong(this.textFieldInitialValue.getText());
case STRING:
fn.value = this.textFieldInitialValue.getText();
default:
fn.value = null;
}
}
fn.name = textFieldName.getText();
fn.desc = textFieldDescriptor.getText();
fn.signature = parseBack(textFieldSignature.getText());
// do modifiers
{
boolean isPublic = this.rdbtnPublic.isSelected();
boolean isProtected = this.rdbtnProtected.isSelected();
boolean isPrivate = this.rdbtnPrivate.isSelected();
fn.access = 0;
if (isPublic) {
fn.access |= Opcodes.ACC_PUBLIC;
} else if (isProtected) {
fn.access |= Opcodes.ACC_PROTECTED;
} else if (isPrivate) {
fn.access |= Opcodes.ACC_PRIVATE;
}
if (this.chckbxVolatile.isSelected()) {
fn.access |= Opcodes.ACC_VOLATILE;
}
if (this.chckbxTransient.isSelected()) {
fn.access |= Opcodes.ACC_TRANSIENT;
}
if (this.chckbxSynthetic.isSelected()) {
fn.access |= Opcodes.ACC_SYNTHETIC;
}
if (this.chckbxStatic.isSelected()) {
fn.access |= Opcodes.ACC_STATIC;
}
if (this.chckbxFinal.isSelected()) {
fn.access |= Opcodes.ACC_FINAL;
}
if (this.chckbxEnumConstant.isSelected()) {
fn.access |= Opcodes.ACC_ENUM;
}
}
}
private static enum InitialValueType {
OTHER, INTEGER, LONG, FLOAT, DOUBLE, STRING;
public Class<?> getType() {
switch (this) {
case DOUBLE:
return Double.TYPE;
case FLOAT:
return Float.TYPE;
case INTEGER:
return Integer.TYPE;
case LONG:
return Long.TYPE;
case STRING:
return String.class;
case OTHER:
default:
return null;
}
}
public static InitialValueType getValType(Class<?> c) {
for (InitialValueType ivt : values()) {
if (ivt.getType().equals(c)) {
return ivt;
}
}
return OTHER;
}
@Override
public String toString() {
String x = super.toString();
if (x == null || x.length() == 0) {
return x;
}
x = Character.toUpperCase(x.charAt(0)) + x.substring(1).toLowerCase();
return x;
}
}
}