package com.jsonde.gui.sdedit;
import com.jsonde.client.ClassListener;
import com.jsonde.client.Client;
import com.jsonde.client.MethodCallListener;
import com.jsonde.client.dao.DaoFactory;
import com.jsonde.client.domain.Clazz;
import com.jsonde.client.domain.Method;
import com.jsonde.client.domain.MethodCall;
import com.jsonde.gui.ApplicationUserInterface;
import com.jsonde.gui.Main;
import com.jsonde.gui.action.*;
import com.jsonde.gui.action.composite.CreateCompositeComponentTabAction;
import com.jsonde.gui.action.reports.ReportActions;
import com.jsonde.gui.components.JActionIcon;
import com.jsonde.gui.components.JActionLabel;
import com.jsonde.gui.components.accordion.JAccordionPanel;
import com.jsonde.gui.components.listpane.DefaultListPaneModel;
import com.jsonde.gui.components.listpane.JListPane;
import com.jsonde.gui.dialog.error.ErrorsDialog;
import com.jsonde.gui.reports.ReportCompositeComponentProvider;
import com.jsonde.gui.reports.ReportException;
import com.jsonde.gui.reports.Reports;
import com.jsonde.gui.tree.Node;
import net.sf.sdedit.config.ConfigurationManager;
import net.sf.sdedit.editor.Editor;
import net.sf.sdedit.ui.UserInterface;
import net.sf.sdedit.ui.components.ATabbedPane;
import net.sf.sdedit.ui.components.ATabbedPaneListener;
import net.sf.sdedit.ui.impl.UserInterfaceImpl;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
public class SdEditUIAdapter implements MethodCallListener, ApplicationUserInterface, ClassListener {
private UserInterface userInterface;
private JFrame frame;
private Editor editor;
private JTree tree;
private DefaultTreeModel treeModel;
private java.util.List<Action> reportActions;
public SdEditUIAdapter() {
try {
reportActions = ReportActions.getInstance(this).getActions();
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
editor = Editor.getEditor();
userInterface = editor.getUI();
frame = (JFrame) userInterface;
processFrame();
processMenuBar();
processToolBar();
createStatusBar();
createTree();
addTree();
JPanel welcomePanel = new JPanel();
welcomePanel.setLayout(new BorderLayout());
welcomePanel.add(new JLabel("Welcome to jSonde"), BorderLayout.CENTER);
addTab(welcomePanel, "Welcome to jSonde");
frame.repaint();
}
});
} catch (Exception e) {
Main.getInstance().processException(e);
}
}
private JLabel instrumentedClassesLabel;
private long instrumentedClassesCount;
private JActionLabel errorsLabel;
public void onRegisterClass(Clazz clazz) {
instrumentedClassesCount++;
instrumentedClassesLabel.setText("Instrumented " + instrumentedClassesCount + " classes");
}
private StringWriter exceptionStringWriter = new StringWriter();
private PrintWriter exceptionPrintWriter = new PrintWriter(exceptionStringWriter);
private long exceptionsCounter;
public void processException(Throwable e) {
e.printStackTrace(exceptionPrintWriter);
exceptionsCounter++;
errorsLabel.setText(exceptionsCounter + " Errors");
}
private void createStatusBar() {
JPanel statusBar = new JPanel();
statusBar.setLayout(new GridBagLayout());
JLabel statusLabel = new JLabel("volatile text");
statusLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.DARK_GRAY));
instrumentedClassesLabel = new JLabel("Instrumented 0 classes");
instrumentedClassesLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.DARK_GRAY));
errorsLabel = new JActionLabel(new AbstractAction() {
{
putValue(Action.NAME, "0 Errors");
}
public void actionPerformed(ActionEvent e) {
ErrorsDialog errorsDialog = new ErrorsDialog(exceptionStringWriter.getBuffer());
errorsDialog.setVisible(true);
}
});
errorsLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.DARK_GRAY));
// Memory usage progress bar
final JProgressBar jProgressBar = new JProgressBar();
jProgressBar.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.DARK_GRAY));
jProgressBar.setStringPainted(true);
jProgressBar.setMinimum(0);
javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Runtime runtime = Runtime.getRuntime();
int freeMemory = (int)
(runtime.freeMemory() / 1024 / 1024);
int totalMemory = (int)
(Runtime.getRuntime().totalMemory() / 1024 / 1024);
int usedMemory = totalMemory - freeMemory;
jProgressBar.setMaximum(totalMemory);
jProgressBar.setValue(usedMemory);
jProgressBar.setString(usedMemory + "M of " + totalMemory + "M");
}
});
timer.start();
// Garbage collection button
JActionIcon gcButton = new JActionIcon(new AbstractAction() {
{
putValue(Action.SMALL_ICON,
new ImageIcon(
getClass().getClassLoader().getResource("trashcan.png")
)
);
}
public void actionPerformed(ActionEvent e) {
System.gc();
}
});
int x = 0;
statusBar.add(
statusLabel,
new GridBagConstraints(
x, 0,
1, 1,
1, 0,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 2, 2), 3, 0
)
);
x++;
statusBar.add(
instrumentedClassesLabel,
new GridBagConstraints(
x, 0,
1, 1,
0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 3, 0
)
);
x++;
statusBar.add(
errorsLabel,
new GridBagConstraints(
x, 0,
1, 1,
0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 3, 0
)
);
x++;
statusBar.add(
jProgressBar,
new GridBagConstraints(
x, 0,
1, 1,
0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 3, 0
)
);
x++;
statusBar.add(
gcButton,
new GridBagConstraints(
x, 0,
1, 1,
0, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 3, 0
)
);
frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
}
public UserInterface getUserInterface() {
return userInterface;
}
public JFrame getFrame() {
return frame;
}
public Editor getEditor() {
return editor;
}
private ATabbedPane tabbedPane;
public ATabbedPane getTabbedPane() {
if (null == tabbedPane) {
try {
Field tabbedPaneField = UserInterfaceImpl.class.getDeclaredField("tabbedPane");
tabbedPaneField.setAccessible(true);
tabbedPane = (ATabbedPane) tabbedPaneField.get(userInterface);
Field stainedImageField = ATabbedPane.class.getDeclaredField("stain");
stainedImageField.setAccessible(true);
Field cleanImageField = ATabbedPane.class.getDeclaredField("clean");
cleanImageField.setAccessible(true);
stainedImageField.set(null, cleanImageField.get(null));
Field listenersField = ATabbedPane.class.getDeclaredField("listeners");
listenersField.setAccessible(true);
java.util.List aTabbedPaneListeners =
(java.util.List) listenersField.get(tabbedPane);
aTabbedPaneListeners.clear();
tabbedPane.addListener(new ATabbedPaneListener() {
public void currentTabClosing() {
new CloseDiagramAction(SdEditUIAdapter.this).actionPerformed(null);
}
});
} catch (Exception e) {
Main.getInstance().processException(e);
}
}
return tabbedPane;
}
public Client getClient() {
return client;
}
public void addTab(Component component, String title) {
getTabbedPane().addTab(component, title);
}
public void onMethodCall(MethodCall methodCall) {
try {
Method method = DaoFactory.getMethodDao().get(
methodCall.getMethodId()
);
String methodName = method.getName();
String className =
null == methodCall.getActualClassId() ?
DaoFactory.getClazzDao().get(method.getClassId()).getName() :
DaoFactory.getClazzDao().get(methodCall.getActualClassId()).getName();
//
Node rootNode = (Node) treeModel.getRoot();
String[] packages = className.split("\\.");
Node contextNode = rootNode;
for (int i = 0; i < packages.length - 1; i++) {
String packageName = packages[i];
boolean nodeFound = false;
Enumeration children = contextNode.children();
while (children.hasMoreElements()) {
Node node = (Node) children.nextElement();
if (node.getAllowsChildren() && (node.getValue().equals(packageName))) {
contextNode = node;
nodeFound = true;
break;
}
}
if (!nodeFound) {
Node node = new Node(packageName);
node.setAllowsChildren(true);
treeModel.insertNodeInto(node, contextNode, contextNode.getChildCount());
contextNode = node;
}
}
String value = packages[packages.length - 1] + "." + methodName;
Node node = new Node(value, methodCall);
node.setAllowsChildren(false);
treeModel.insertNodeInto(node, contextNode, contextNode.getChildCount());
} catch (Exception e) {
Main.getInstance().processException(e);
}
}
private void createTree() {
tree = new JTree();
Node root = new Node("Packages");
treeModel = new DefaultTreeModel(root);
tree.setModel(treeModel);
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if ((MouseEvent.BUTTON1 == e.getButton()) && (2 == e.getClickCount())) {
TreePath treePath =
tree.getPathForLocation(e.getX(), e.getY());
if (null != treePath) {
Node selectedNode = (Node) treePath.getLastPathComponent();
if (selectedNode.isLeaf() && !selectedNode.getAllowsChildren()) {
MethodCall methodCall = selectedNode.getRootMethodCall();
renderDiagram(methodCall);
}
}
}
}
});
}
private void renderDiagram(MethodCall methodCall) {
try {
Method method = DaoFactory.getMethodDao().get(
methodCall.getMethodId()
);
String methodName = method.getName();
String className =
null == methodCall.getActualClassId() ?
DaoFactory.getClazzDao().get(method.getClassId()).getName() :
DaoFactory.getClazzDao().get(methodCall.getActualClassId()).getName();
String title = editor.getUI().addTab(className + "." + methodName,
ConfigurationManager.createNewDefaultConfiguration());
SdEditDataRenderer sdEditDataRenderer = new SdEditDataRenderer();
editor.getUI().appendText(title, sdEditDataRenderer.processMethodCall(methodCall));
} catch (Exception e) {
Main.getInstance().processException(e);
}
}
private void addTree() {
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setViewportView(tree);
JAccordionPanel jAccordionPanel = new JAccordionPanel();
jAccordionPanel.addPanel(
"Sequence Diagrams",
new ImageIcon(
getClass().getClassLoader().getResource("kdisknav.png")
),
scrollPane);
JListPane reportsListPane = getReportsListPane();
jAccordionPanel.addPanel(
"Reports",
new ImageIcon(
getClass().getClassLoader().getResource("3d.png")
),
reportsListPane);
JListPane profilerListPane = getProfilerListPane();
jAccordionPanel.addPanel(
"Profiler",
new ImageIcon(
getClass().getClassLoader().getResource("agt_add-to-autorun.png")
),
profilerListPane);
Component sdEditTabbedPane = frame.getContentPane().getComponent(0);
JSplitPane jSondeSplitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jAccordionPanel, sdEditTabbedPane);
frame.getContentPane().remove(sdEditTabbedPane);
frame.getContentPane().add(jSondeSplitter, BorderLayout.CENTER);
}
private JListPane getReportsListPane() {
DefaultListPaneModel reportsListPaneModel = new DefaultListPaneModel();
for (Action action : reportActions) {
reportsListPaneModel.addListPaneItem(action);
}
return new JListPane(reportsListPaneModel);
}
private JListPane getProfilerListPane() {
DefaultListPaneModel reportsListPaneModel = new DefaultListPaneModel();
reportsListPaneModel.addListPaneItem(openMethodCallProfilerViewAction);
reportsListPaneModel.addListPaneItem(openMemoryHeapViewAction);
//reportsListPaneModel.addListPaneItem(openMemoryTelemetryViewAction);
try {
Action a = new CreateCompositeComponentTabAction(
this,
new ReportCompositeComponentProvider(
Reports.getReport("memory-telemetry")
)
);
reportsListPaneModel.addListPaneItem(a);
} catch (ReportException e) {
Main.getInstance().processException(e);
}
try {
Action a = new CreateCompositeComponentTabAction(
this,
new ReportCompositeComponentProvider(
Reports.getReport("class-telemetry")
)
);
reportsListPaneModel.addListPaneItem(a);
} catch (ReportException e) {
Main.getInstance().processException(e);
}
return new JListPane(reportsListPaneModel);
}
private void processToolBar() {
JToolBar toolBar = (JToolBar)
frame.getContentPane().getComponent(1);
int[] indexes = {0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 21, 22};
java.util.List<Component> components = new ArrayList<Component>(indexes.length);
for (int index : indexes) {
components.add(toolBar.getComponentAtIndex(index));
}
for (Component component : components) {
toolBar.remove(component);
}
}
private Client client;
public void setClient(Client client) {
this.client = client;
client.addMethodCallListener(this);
client.addClassListener(this);
instrumentedClassesLabel.setText("Instrumented " + client.getClassCount() + " classes");
}
private Action openMethodCallProfilerViewAction =
new OpenMethodCallProfilerViewAction(this);
private Action openMemoryHeapViewAction =
new OpenMemoryHeapViewAction(this);
private void processMenuBar() {
JMenuBar menuBar = frame.getRootPane().getJMenuBar();
menuBar.removeAll();
JMenu fileMenu = new JMenu("File");
fileMenu.add(new NewProjectAction(this));
fileMenu.add(new NewLocalSunJVMProjectAction(this));
fileMenu.add(new OpenProjectAction(this));
fileMenu.add(new CloseAllDiagramsAction(this));
fileMenu.add(new ExitJSondeAction(this));
menuBar.add(fileMenu);
JMenu reportsMenu = new JMenu("Reports");
for (Action action : reportActions) {
reportsMenu.add(action);
}
menuBar.add(reportsMenu);
JMenu profilingMenu = new JMenu("Profiling");
profilingMenu.add(openMethodCallProfilerViewAction);
profilingMenu.add(openMemoryHeapViewAction);
//profilingMenu.add(openMemoryTelemetryViewAction);
try {
Action a = new CreateCompositeComponentTabAction(
this,
new ReportCompositeComponentProvider(
Reports.getReport("memory-telemetry")
)
);
profilingMenu.add(a);
} catch (ReportException e) {
Main.getInstance().processException(e);
}
try {
Action a = new CreateCompositeComponentTabAction(
this,
new ReportCompositeComponentProvider(
Reports.getReport("class-telemetry")
)
);
profilingMenu.add(a);
} catch (ReportException e) {
Main.getInstance().processException(e);
}
menuBar.add(profilingMenu);
JMenu helpMenu = new JMenu("Help");
helpMenu.add(new HelpAction(this));
helpMenu.add(new AboutAction(this));
menuBar.add(helpMenu);
}
private void processFrame() {
for (WindowListener windowListener : frame.getWindowListeners()) {
frame.removeWindowListener(windowListener);
}
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setTitle("jSonde GUI version 1.1.0");
frame.addPropertyChangeListener("title", new PropertyChangeListener() {
private boolean revertingTitle;
public void propertyChange(PropertyChangeEvent evt) {
if (!revertingTitle) {
revertingTitle = true;
frame.setTitle((String) evt.getOldValue());
} else {
revertingTitle = false;
}
}
});
}
}