/* Copyright 2012 Jan Ove Saltvedt This file is part of KBot. KBot is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. KBot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with KBot. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright � 2010 Jan Ove Saltvedt. * All rights reserved. */ /* * Created by JFormDesigner on Fri Sep 18 18:15:05 CEST 2009 */ package com.kbotpro.ui; import java.awt.*; import java.awt.event.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Arrays; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; import org.jdesktop.layout.*; import org.jdesktop.layout.GroupLayout; import org.jdesktop.layout.LayoutStyle; import com.kbotpro.bot.BotEnvironment; import com.kbotpro.reflection.ReflectionEngine; import com.kbotpro.utils.EscapeChars; /** * @author Jan Ove */ public class ReflectionExplorer extends JFrame { public DefaultMutableTreeNode topNode; private BotEnvironment bot; public ReflectionExplorer(BotEnvironment bot) { this.bot = bot; topNode = new DefaultMutableTreeNode("Please select a field."); initComponents(); } private void tree1ValueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); if(node == null){ return; // Nothing is selected } Object obj = node.getUserObject(); if(!(obj instanceof WrappedObject)){ return; // We just handle the WrappedObjects } node.removeAllChildren(); WrappedObject wrappedObject = (WrappedObject) obj; for(MutableTreeNode mutableTreeNode: wrappedObject.getAllChildren()){ node.add(mutableTreeNode); } // show info fieldInfo.setText(wrappedObject.getValueHTML()); } private void updateButtonActionPerformed(ActionEvent e) { ClassLoader classLoader = bot.clientClassLoader; try { Class klass = classLoader.loadClass(classNameTextField.getText()); Field field = klass.getDeclaredField(fieldNameTextField.getText()); if(!field.isAccessible()){ field.setAccessible(true); } if(!Modifier.isStatic(field.getModifiers())){ JOptionPane.showMessageDialog(this, "Field is not static..."); return; } Object obj = field.get(null); if(obj == null){ JOptionPane.showMessageDialog(this, "Field value is null..."); return; } WrappedObject wrappedObject = new WrappedObject(obj, bot, field); DefaultMutableTreeNode defaultMutableTreeNode = new DefaultMutableTreeNode(wrappedObject); tree.setModel(new DefaultTreeModel(defaultMutableTreeNode)); } catch (ClassNotFoundException e1) { JOptionPane.showMessageDialog(this, "Class not found..."); } catch (NoSuchFieldException e1) { JOptionPane.showMessageDialog(this, "Field not found..."); } catch (IllegalAccessException e1) { JOptionPane.showMessageDialog(this, "Can't access field."); } } private void updateDataButoonActionPerformed(ActionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); if(node == null){ return; // Nothing is selected } Object obj = node.getUserObject(); if(!(obj instanceof WrappedObject)){ return; // We just handle the WrappedObjects } node.removeAllChildren(); WrappedObject wrappedObject = (WrappedObject) obj; for(MutableTreeNode mutableTreeNode: wrappedObject.getAllChildren()){ node.add(mutableTreeNode); } // show info fieldInfo.setText(wrappedObject.getValueHTML()); } private void addFieldWatchButtonActionPerformed(ActionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); if(node == null){ JOptionPane.showMessageDialog(this, "No field selected."); return; // Nothing is selected } Object obj = node.getUserObject(); if(!(obj instanceof WrappedObject)){ JOptionPane.showMessageDialog(this, "No field selected."); return; // We just handle the WrappedObjects } final WrappedObject wrappedObject = (WrappedObject) obj; SwingUtilities.invokeLater(new Runnable() { public void run() { new FieldWatcher(wrappedObject.obj).setVisible(true); } }); } private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents label1 = new JLabel(); label2 = new JLabel(); classNameTextField = new JTextField(); fieldNameTextField = new JTextField(); updateButton = new JButton(); separator1 = new JSeparator(); scrollPane1 = new JScrollPane(); tree = new JTree(topNode); separator2 = new JSeparator(); updateDataButoon = new JButton(); scrollPane2 = new JScrollPane(); fieldInfo = new JLabel(); separator3 = new JSeparator(); addFieldWatchButton = new JButton(); //======== this ======== setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setTitle("Reflection Explorer"); Container contentPane = getContentPane(); //---- label1 ---- label1.setText("Class:"); label1.setLabelFor(classNameTextField); //---- label2 ---- label2.setText("Field:"); label2.setLabelFor(fieldNameTextField); //---- updateButton ---- updateButton.setText("Update"); updateButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { updateButtonActionPerformed(e); } }); //======== scrollPane1 ======== { //---- tree ---- tree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { tree1ValueChanged(e); } }); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); scrollPane1.setViewportView(tree); } //---- separator2 ---- separator2.setOrientation(SwingConstants.VERTICAL); //---- updateDataButoon ---- updateDataButoon.setText("Update data"); updateDataButoon.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { updateDataButoonActionPerformed(e); } }); //======== scrollPane2 ======== { //---- fieldInfo ---- fieldInfo.setText("<html>\n<body>\nField info is displayed here\n</body>\n</html>"); fieldInfo.setVerticalAlignment(SwingConstants.TOP); scrollPane2.setViewportView(fieldInfo); } //---- separator3 ---- separator3.setOrientation(SwingConstants.VERTICAL); //---- addFieldWatchButton ---- addFieldWatchButton.setText("Add field watch"); addFieldWatchButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { addFieldWatchButtonActionPerformed(e); } }); GroupLayout contentPaneLayout = new GroupLayout(contentPane); contentPane.setLayout(contentPaneLayout); contentPaneLayout.setHorizontalGroup( contentPaneLayout.createParallelGroup() .add(contentPaneLayout.createSequentialGroup() .addContainerGap() .add(contentPaneLayout.createParallelGroup() .add(contentPaneLayout.createSequentialGroup() .add(scrollPane1, GroupLayout.PREFERRED_SIZE, 244, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(separator2, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(contentPaneLayout.createParallelGroup() .add(scrollPane2, GroupLayout.DEFAULT_SIZE, 226, Short.MAX_VALUE) .add(updateDataButoon, GroupLayout.DEFAULT_SIZE, 226, Short.MAX_VALUE))) .add(separator1, GroupLayout.DEFAULT_SIZE, 492, Short.MAX_VALUE) .add(contentPaneLayout.createSequentialGroup() .add(label1) .addPreferredGap(LayoutStyle.RELATED) .add(classNameTextField, GroupLayout.PREFERRED_SIZE, 35, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(label2) .addPreferredGap(LayoutStyle.RELATED) .add(fieldNameTextField, GroupLayout.PREFERRED_SIZE, 36, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(updateButton) .add(32, 32, 32) .add(separator3, GroupLayout.PREFERRED_SIZE, 13, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(addFieldWatchButton))) .addContainerGap()) ); contentPaneLayout.setVerticalGroup( contentPaneLayout.createParallelGroup() .add(contentPaneLayout.createSequentialGroup() .addContainerGap() .add(contentPaneLayout.createParallelGroup(GroupLayout.TRAILING) .add(contentPaneLayout.createParallelGroup(GroupLayout.BASELINE) .add(label1) .add(classNameTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .add(label2) .add(fieldNameTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .add(updateButton)) .add(GroupLayout.LEADING, separator3, GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE) .add(addFieldWatchButton)) .addPreferredGap(LayoutStyle.RELATED) .add(separator1, GroupLayout.PREFERRED_SIZE, 5, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(contentPaneLayout.createParallelGroup() .add(separator2, GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE) .add(scrollPane1, GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE) .add(GroupLayout.TRAILING, contentPaneLayout.createSequentialGroup() .add(scrollPane2, GroupLayout.DEFAULT_SIZE, 303, Short.MAX_VALUE) .addPreferredGap(LayoutStyle.RELATED) .add(updateDataButoon))) .addContainerGap()) ); pack(); setLocationRelativeTo(getOwner()); // JFormDesigner - End of component initialization //GEN-END:initComponents } // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables private JLabel label1; private JLabel label2; private JTextField classNameTextField; private JTextField fieldNameTextField; private JButton updateButton; private JSeparator separator1; private JScrollPane scrollPane1; public JTree tree; private JSeparator separator2; private JButton updateDataButoon; private JScrollPane scrollPane2; private JLabel fieldInfo; private JSeparator separator3; private JButton addFieldWatchButton; // JFormDesigner - End of variables declaration //GEN-END:variables }