/* * Copyright (C) 2012 Brendan Robert (BLuRry) brendan.robert@gmail.com. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ package jace.cheat; import jace.core.Utility; import static jace.core.Utility.gripe; /** * This represents the window of the memory spy module. The memory view itself * is implemented in MemorySpyGrid. * * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public class MemorySpy extends javax.swing.JFrame { static MemorySpy singleton = null; /** * Creates new form MemorySpy */ public MemorySpy() { initComponents(); setDefaultCloseOperation(HIDE_ON_CLOSE); singleton = this; } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { mapType = new javax.swing.ButtonGroup(); viewScroll = new javax.swing.JScrollPane(); memorySpyGrid = new jace.cheat.MemorySpyGrid(); controlPanel = new javax.swing.JPanel(); showLabel = new javax.swing.JLabel(); zoomAmount = new javax.swing.JSlider(); mapActivityMode = new javax.swing.JRadioButton(); mapValueMode = new javax.swing.JRadioButton(); zoomLabel = new javax.swing.JLabel(); startAddress = new javax.swing.JTextField(); startLabel = new javax.swing.JLabel(); endAddress = new javax.swing.JTextField(); statusLabel = new javax.swing.JLabel(); endLabel = new javax.swing.JLabel(); updateAddressButton = new javax.swing.JButton(); useColorCheckbox = new javax.swing.JCheckBox(); fastFadeCheckbox = new javax.swing.JCheckBox(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); addComponentListener(new java.awt.event.ComponentAdapter() { public void componentResized(java.awt.event.ComponentEvent evt) { formComponentResized(evt); } public void componentShown(java.awt.event.ComponentEvent evt) { formComponentShown(evt); } public void componentHidden(java.awt.event.ComponentEvent evt) { formComponentHidden(evt); } }); addHierarchyBoundsListener(new java.awt.event.HierarchyBoundsListener() { public void ancestorMoved(java.awt.event.HierarchyEvent evt) { } public void ancestorResized(java.awt.event.HierarchyEvent evt) { formAncestorResized(evt); } }); viewScroll.setPreferredSize(new java.awt.Dimension(640, 480)); memorySpyGrid.setPreferredSize(new java.awt.Dimension(580, 480)); javax.swing.GroupLayout memorySpyGridLayout = new javax.swing.GroupLayout(memorySpyGrid); memorySpyGrid.setLayout(memorySpyGridLayout); memorySpyGridLayout.setHorizontalGroup( memorySpyGridLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 631, Short.MAX_VALUE) ); memorySpyGridLayout.setVerticalGroup( memorySpyGridLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 490, Short.MAX_VALUE) ); viewScroll.setViewportView(memorySpyGrid); controlPanel.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true)); showLabel.setText("Show"); zoomAmount.setMaximum(15); zoomAmount.setMinimum(1); zoomAmount.setPaintTicks(true); zoomAmount.setSnapToTicks(true); zoomAmount.setValue(5); zoomAmount.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { zoomAmountStateChanged(evt); } }); mapType.add(mapActivityMode); mapActivityMode.setSelected(true); mapActivityMode.setText("Activity"); mapActivityMode.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mapActivityModeActionPerformed(evt); } }); mapType.add(mapValueMode); mapValueMode.setText("Value"); mapValueMode.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mapValueModeActionPerformed(evt); } }); zoomLabel.setText("Zoom"); startAddress.setText("$0000"); startLabel.setText("Start"); endAddress.setText("$FFFF"); statusLabel.setFont(new java.awt.Font("Courier New", 0, 14)); // NOI18N statusLabel.setText(" "); statusLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED)); endLabel.setText("End"); updateAddressButton.setText("Update"); updateAddressButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { updateAddressButtonActionPerformed(evt); } }); useColorCheckbox.setText("Color Gradient"); useColorCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { useColorCheckboxActionPerformed(evt); } }); fastFadeCheckbox.setText("Fast Fade"); fastFadeCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { fastFadeCheckboxActionPerformed(evt); } }); javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); controlPanel.setLayout(controlPanelLayout); controlPanelLayout.setHorizontalGroup( controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(controlPanelLayout.createSequentialGroup() .addGap(19, 19, 19) .addComponent(showLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(mapActivityMode) .addComponent(fastFadeCheckbox)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(controlPanelLayout.createSequentialGroup() .addComponent(mapValueMode) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(zoomLabel)) .addComponent(useColorCheckbox)) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(controlPanelLayout.createSequentialGroup() .addGap(144, 144, 144) .addComponent(endLabel)) .addGroup(controlPanelLayout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(zoomAmount, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(startLabel))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(endAddress, javax.swing.GroupLayout.DEFAULT_SIZE, 60, Short.MAX_VALUE) .addComponent(startAddress)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(updateAddressButton) .addContainerGap(28, Short.MAX_VALUE)) .addGroup(controlPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(statusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); controlPanelLayout.setVerticalGroup( controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(controlPanelLayout.createSequentialGroup() .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(controlPanelLayout.createSequentialGroup() .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(zoomAmount, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(startLabel) .addComponent(startAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(endAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(endLabel) .addComponent(updateAddressButton) .addComponent(useColorCheckbox) .addComponent(fastFadeCheckbox))) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(mapActivityMode, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(showLabel)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(zoomLabel) .addComponent(mapValueMode)))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(statusLabel) .addContainerGap()) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(viewScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 633, Short.MAX_VALUE) .addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(viewScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 492, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); pack(); }// //GEN-END:initComponents private void mapActivityModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mapActivityModeActionPerformed memorySpyGrid.setDisplayMode(MemorySpyGrid.Modes.ACTIVITY); }//GEN-LAST:event_mapActivityModeActionPerformed private void mapValueModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mapValueModeActionPerformed memorySpyGrid.setDisplayMode(MemorySpyGrid.Modes.VALUE); }//GEN-LAST:event_mapValueModeActionPerformed private void zoomAmountStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_zoomAmountStateChanged if (!zoomAmount.getValueIsAdjusting()) { memorySpyGrid.setZoomAmount(zoomAmount.getValue()); } }//GEN-LAST:event_zoomAmountStateChanged private void updateAddressButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateAddressButtonActionPerformed int startAddr = Utility.parseHexInt(startAddress.getText()); int endAddr = Utility.parseHexInt(endAddress.getText()); if (startAddr < 0 || startAddr > 0x0ffff) { gripe("Start address is out of range!"); return; } if (endAddr < 0 || endAddr > 0x0ffff) { gripe("End address is out of range!"); return; } if (startAddr > endAddr) { gripe("Start address must be smaller than end address"); return; } memorySpyGrid.updateRange(startAddr, endAddr); }//GEN-LAST:event_updateAddressButtonActionPerformed @Override public void validate() { super.validate(); memorySpyGrid.adjustSize(); } private void formComponentHidden(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentHidden memorySpyGrid.stopDisplay(); }//GEN-LAST:event_formComponentHidden private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown memorySpyGrid.startDisplay(); }//GEN-LAST:event_formComponentShown long lastRefresh = -1L; long refreshDelay = 1000L; private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized }//GEN-LAST:event_formComponentResized private void formAncestorResized(java.awt.event.HierarchyEvent evt) {//GEN-FIRST:event_formAncestorResized // java.awt.EventQueue.invokeLater(new Runnable() { // @Override // public void run() { // lastRefresh = System.currentTimeMillis() + refreshDelay + 10; // try { // Thread.sleep(refreshDelay); // } catch (InterruptedException ex) { // Logger.getLogger(MemorySpy.class.getName()).log(Level.SEVERE, null, ex); // } // if (System.currentTimeMillis() >= lastRefresh) { // int newWidth = getParent().getWidth(); // } // } // }); // memorySpyGrid.adjustSize(); }//GEN-LAST:event_formAncestorResized private void useColorCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useColorCheckboxActionPerformed memorySpyGrid.setColorGradient(useColorCheckbox.isSelected()); }//GEN-LAST:event_useColorCheckboxActionPerformed private void fastFadeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastFadeCheckboxActionPerformed memorySpyGrid.setFastFade(fastFadeCheckbox.isSelected()); }//GEN-LAST:event_fastFadeCheckboxActionPerformed /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ // /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(MemorySpy.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(MemorySpy.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(MemorySpy.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(MemorySpy.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } // /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MemorySpy().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel controlPanel; private javax.swing.JTextField endAddress; private javax.swing.JLabel endLabel; private javax.swing.JCheckBox fastFadeCheckbox; private javax.swing.JRadioButton mapActivityMode; private javax.swing.ButtonGroup mapType; private javax.swing.JRadioButton mapValueMode; private jace.cheat.MemorySpyGrid memorySpyGrid; private javax.swing.JLabel showLabel; private javax.swing.JTextField startAddress; private javax.swing.JLabel startLabel; public javax.swing.JLabel statusLabel; private javax.swing.JButton updateAddressButton; private javax.swing.JCheckBox useColorCheckbox; private javax.swing.JScrollPane viewScroll; private javax.swing.JSlider zoomAmount; private javax.swing.JLabel zoomLabel; // End of variables declaration//GEN-END:variables }