Skip to content

Commit

Permalink
added new features for issue #5:
Browse files Browse the repository at this point in the history
- changed format of timestamps in filter
- default start and end value of the pickers are now set by our data
- time picker now works properly for "second" value
- no more problems when canceling file dialog
- edited labels
- updating number of root cases in frame title
  • Loading branch information
nbrass committed Dec 9, 2015
1 parent 13aae33 commit dbebe32
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
import javax.swing.table.TableRowSorter;

import de.ibm.issw.requestmetrics.gui.CheckComboBox;
import de.ibm.issw.requestmetrics.gui.UsecaseTableModel;
import de.ibm.issw.requestmetrics.gui.RequestMetricsGui;
import de.ibm.issw.requestmetrics.gui.RootCaseTableModel;

public class RootCaseFilter{

private RowFilter<UsecaseTableModel, Object> elapsedTimeRowFilter;
private RowFilter<UsecaseTableModel, Object> detailFilter;
private RowFilter<UsecaseTableModel, Object> dateTimeStartFilter;
private RowFilter<UsecaseTableModel, Object> dateTimeEndFilter;
private RowFilter<UsecaseTableModel, Object> typeFilter;
private List<RowFilter<UsecaseTableModel, Object>> filters = new ArrayList<RowFilter<UsecaseTableModel, Object>>();
private RowFilter<RootCaseTableModel, Object> elapsedTimeRowFilter;
private RowFilter<RootCaseTableModel, Object> detailFilter;
private RowFilter<RootCaseTableModel, Object> dateTimeStartFilter;
private RowFilter<RootCaseTableModel, Object> dateTimeEndFilter;
private RowFilter<RootCaseTableModel, Object> typeFilter;
private List<RowFilter<RootCaseTableModel, Object>> filters = new ArrayList<RowFilter<RootCaseTableModel, Object>>();
private JTable rootCaseTable;

private final int TIMESTAMP_COLUMN = 1;
Expand All @@ -41,11 +42,11 @@ public void filterElapsedTime(final Object userInput) {
//
if (elapsedTimeRowFilter != null && filters.contains(elapsedTimeRowFilter))
filters.remove(elapsedTimeRowFilter);
elapsedTimeRowFilter = new RowFilter<UsecaseTableModel, Object>() {
elapsedTimeRowFilter = new RowFilter<RootCaseTableModel, Object>() {

//
@Override
public boolean include(javax.swing.RowFilter.Entry<? extends UsecaseTableModel, ? extends Object> entry) {
public boolean include(javax.swing.RowFilter.Entry<? extends RootCaseTableModel, ? extends Object> entry) {
if (rootCaseTable != null){
Long elapsedTime = (Long) rootCaseTable.getModel().getValueAt((Integer) entry.getIdentifier(), ELAPSED_TIME_COLUMN);
if (userInput == null || elapsedTime >= (Long) userInput)
Expand Down Expand Up @@ -127,10 +128,10 @@ public void filterType(CheckComboBox comboBox) {
if (typeFilter != null && filters.contains(typeFilter))
filters.remove(typeFilter);

List<RowFilter<UsecaseTableModel, Object>> typeFilterList = new ArrayList<RowFilter<UsecaseTableModel, Object>>();
List<RowFilter<RootCaseTableModel, Object>> typeFilterList = new ArrayList<RowFilter<RootCaseTableModel, Object>>();
if (comboBox.getSelectedItems() != null) {
for (Object type : comboBox.getSelectedItems()) {
RowFilter<UsecaseTableModel, Object> rowFilter = RowFilter.regexFilter(type.toString(), TYPE_COLUMN);
RowFilter<RootCaseTableModel, Object> rowFilter = RowFilter.regexFilter(type.toString(), TYPE_COLUMN);
typeFilterList.add(rowFilter);
}
typeFilter = RowFilter.orFilter(typeFilterList);
Expand All @@ -150,7 +151,7 @@ public void clearFilters() {
filters.clear();

if (rootCaseTable != null) {
TableRowSorter<UsecaseTableModel> sorter = new TableRowSorter<UsecaseTableModel>((UsecaseTableModel) rootCaseTable.getModel());
TableRowSorter<RootCaseTableModel> sorter = new TableRowSorter<RootCaseTableModel>((RootCaseTableModel) rootCaseTable.getModel());
rootCaseTable.setRowSorter(sorter);
sorter.setRowFilter(null);
}
Expand All @@ -161,10 +162,13 @@ public void clearFilters() {
* thereby ensures that different filters can be applied at the same time
*/
private void buildCompoundFilter() {
RowFilter<UsecaseTableModel, Object> compoundFilter = RowFilter.andFilter(filters);
RowFilter<RootCaseTableModel, Object> compoundFilter = RowFilter.andFilter(filters);

TableRowSorter<UsecaseTableModel> sorter = new TableRowSorter<UsecaseTableModel>((UsecaseTableModel) rootCaseTable.getModel());
TableRowSorter<RootCaseTableModel> sorter = new TableRowSorter<RootCaseTableModel>((RootCaseTableModel) rootCaseTable.getModel());
rootCaseTable.setRowSorter(sorter);
sorter.setRowFilter(compoundFilter);

// update the number of root cases in the frame title
RequestMetricsGui.setTitleRootCaseFrame(rootCaseTable.getRowCount());
}
}
62 changes: 32 additions & 30 deletions src/main/java/de/ibm/issw/requestmetrics/gui/RequestMetricsGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ public RequestMetricsGui() {
private StringBuffer invalidFiles = new StringBuffer();
// GUI elements
private static final JInternalFrame treeInternalFrame = new JInternalFrame("Transaction Drilldown", true, false, true, true);
private static final JInternalFrame listInternalFrame = new JInternalFrame("Business Transactions", true, false, true, true);
private static final JInternalFrame listInternalFrame = new JInternalFrame("Root Cases", true, false, true, true);

private static final SimpleDateFormat sdf = new SimpleDateFormat("y/MM/dd HH:mm:ss:S");
private static final SimpleDateFormat sdf = new SimpleDateFormat("y/MM/dd HH:mm:ss.S");

private RmProcessor processor;
private static JTable rootCaseTable;
private ProgressBarDialog fileProcessingDialog;
private UsecasePanel transactionDrilldownPanel;
private TransactionDrilldownPanel transactionDrilldownPanel;
private RMNode currentSelectedRootNode;
private TransactionDrilldownToolBar transactionDrilldownToolBar = new TransactionDrilldownToolBar();
private RootCaseToolBar rootCaseToolBar = new RootCaseToolBar();
Expand All @@ -79,7 +79,7 @@ public void createAndShowGUI(final RmProcessor processor) {
// register the GUI as observer for the events of the processor
processor.addObserver(this);

rootCaseTable = buildRootCaseTable();
buildRootCaseTable();
JScrollPane listScrollPane = new JScrollPane(rootCaseTable);

listInternalFrame.add(rootCaseToolBar, "North");
Expand Down Expand Up @@ -118,11 +118,11 @@ private JMenuBar buildMenubar(JFrame mainFrame, final RmProcessor processor) {
@Override
public void actionPerformed(ActionEvent e) {
fd.setVisible(true);
processor.reset();
invalidFiles = new StringBuffer();
final File[] files = fd.getFiles();
if(files.length == 0) return;

processor.reset();
invalidFiles = new StringBuffer();
resetGui();

//create a new dialog containing 2 progress bars
Expand All @@ -131,24 +131,24 @@ public void actionPerformed(ActionEvent e) {
new Thread(new Runnable() {
public void run() {
processor.processInputFiles(files);
listInternalFrame.setTitle(processor.getRootCases().size() + " Business Transactions");
setTitleRootCaseFrame(processor.getRootCases().size());

// remove the old model
List<RmRootCase> rootCases = processor.getRootCases();
if(rootCases != null && !rootCases.isEmpty()) {
final UsecaseTableModel rootCaseModel = new UsecaseTableModel(rootCases);
final RootCaseTableModel rootCaseModel = new RootCaseTableModel(rootCases);
rootCaseTable.setModel(rootCaseModel);
// the width is currently hard coded and could be gathered from data in future
rootCaseTable.getColumnModel().getColumn(0).setMinWidth(215);
rootCaseTable.getColumnModel().getColumn(0).setMaxWidth(515);
rootCaseTable.getColumnModel().getColumn(1).setMinWidth(160);
rootCaseTable.getColumnModel().getColumn(1).setMaxWidth(160);
rootCaseTable.getColumnModel().getColumn(2).setMinWidth(100);
rootCaseTable.getColumnModel().getColumn(2).setMaxWidth(100);
rootCaseTable.getColumnModel().getColumn(3).setMinWidth(140);
rootCaseTable.getColumnModel().getColumn(3).setMaxWidth(140);
rootCaseTable.getColumnModel().getColumn(4).setMinWidth(85);
rootCaseTable.getColumnModel().getColumn(4).setMaxWidth(85);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.FILE_COLUMN_INDEX).setMinWidth(215);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.FILE_COLUMN_INDEX).setMaxWidth(515);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.TIMESTAMP_COLUMN_INDEX).setMinWidth(160);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.TIMESTAMP_COLUMN_INDEX).setMaxWidth(160);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.ELAPSEDTIME_COLUMN_INDEX).setMinWidth(100);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.ELAPSEDTIME_COLUMN_INDEX).setMaxWidth(100);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.TYPE_COLUMN_INDEX).setMinWidth(140);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.TYPE_COLUMN_INDEX).setMaxWidth(140);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.REQUESTID_COLUMN_INDEX).setMinWidth(85);
rootCaseTable.getColumnModel().getColumn(RootCaseTableModel.REQUESTID_COLUMN_INDEX).setMaxWidth(85);

// initially sort root cases by elapsed time descending
Collections.sort(rootCases, new ElapsedTimeComparator());
Expand Down Expand Up @@ -176,30 +176,34 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
menu.add(fileMenu);
return menu;
}

public static void setTitleRootCaseFrame(int numberOfRootCases) {
listInternalFrame.setTitle(numberOfRootCases + " Root Cases");
}

private JTable buildRootCaseTable() {
final JTable businessTransactionTable = new JTable();
businessTransactionTable.setFillsViewportHeight(true);
businessTransactionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
businessTransactionTable.setAutoCreateRowSorter(true);
private void buildRootCaseTable() {
rootCaseTable = new JTable();
rootCaseTable.setFillsViewportHeight(true);
rootCaseTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
rootCaseTable.setAutoCreateRowSorter(true);

// reference to this window
final RequestMetricsGui rootWindow = this;

// add selection listener to select the use cases
businessTransactionTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
rootCaseTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
// check if we are in an event sequence and only process the last one
if(!event.getValueIsAdjusting() && !businessTransactionTable.getSelectionModel().isSelectionEmpty()) {
int row = businessTransactionTable.getSelectedRow();
if(!event.getValueIsAdjusting() && !rootCaseTable.getSelectionModel().isSelectionEmpty()) {
int row = rootCaseTable.getSelectedRow();
if(row != -1) { //if no row is selected row = -1 (and we do nothing)
final RmRootCase currentSelectedRootCase = processor.getRootCases().get(businessTransactionTable.convertRowIndexToModel(row));
final RmRootCase currentSelectedRootCase = processor.getRootCases().get(rootCaseTable.convertRowIndexToModel(row));
LOG.fine("user selected use case " + currentSelectedRootCase.getRmNode().toString());

currentSelectedRootNode = currentSelectedRootCase.getRmNode();
currentSelectedRootNode.calculateExecutionTime();
resetGui();
transactionDrilldownPanel = new UsecasePanel(rootWindow, currentSelectedRootNode, processor);
transactionDrilldownPanel = new TransactionDrilldownPanel(rootWindow, currentSelectedRootNode, processor);
treeInternalFrame.getContentPane().add(transactionDrilldownPanel, "Center");
treeInternalFrame.setTitle("Transaction Drilldown for #" + currentSelectedRootCase.getRmNode().getData().getCurrentCmp().getReqid() + " " + currentSelectedRootCase.getRmNode().getData().getDetailCmp());

Expand All @@ -211,8 +215,6 @@ public void valueChanged(ListSelectionEvent event) {
}
}
});

return businessTransactionTable;
}

private void resetGui() {
Expand Down
79 changes: 56 additions & 23 deletions src/main/java/de/ibm/issw/requestmetrics/gui/RootCaseToolBar.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package de.ibm.issw.requestmetrics.gui;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
Expand All @@ -21,6 +26,8 @@
import org.freixas.jcalendar.JCalendarCombo;

import de.ibm.issw.requestmetrics.engine.filter.RootCaseFilter;
import de.ibm.issw.requestmetrics.gui.comparator.LogTimeStampComparator;
import de.ibm.issw.requestmetrics.model.RmRootCase;

@SuppressWarnings("serial")
public class RootCaseToolBar extends JToolBar{
Expand All @@ -33,15 +40,18 @@ public class RootCaseToolBar extends JToolBar{
private JCalendarCombo startDatePicker = new JCalendarCombo(JCalendarCombo.DISPLAY_DATE | JCalendarCombo.DISPLAY_TIME, false);
private JCalendarCombo endDatePicker = new JCalendarCombo(JCalendarCombo.DISPLAY_DATE | JCalendarCombo.DISPLAY_TIME, false);

private final String EJB = "EJB";
private final String SERVLET_FILTER = "Servlet Filter";
private final String WEB_SERVICES = "Web Services";
private final String JNDI = "JNDI";
private final String JMS = "JMS";
private final String ASYNC_BEANS = "AsyncBeans";
public static final SimpleDateFormat sdf = new SimpleDateFormat("y/MM/dd HH:mm:ss");
private static final String EJB = "EJB";
private static final String SERVLET_FILTER = "Servlet Filter";
private static final String WEB_SERVICES = "Web Services";
private static final String JNDI = "JNDI";
private static final String JMS = "JMS";
private static final String ASYNC_BEANS = "AsyncBeans";

private static Date startLogTimeStamp;
private static Date endLogTimeStamp;

public RootCaseToolBar() {

setFloatable(false);
setLayout(new FlowLayout());

Expand Down Expand Up @@ -70,42 +80,50 @@ public RootCaseToolBar() {
comboBox.setEnabled(false);
comboBox.addSelectionChangedListener(checkBoxListener);

startDatePicker.setDateFormat(sdf);
startDatePicker.setDate(null);
startDatePicker.setEditable(false);
startDatePicker.setEnabled(false);
startDatePicker.setPreferredSize(new Dimension(150, 25));
startDatePicker.setMinimumSize(startDatePicker.getPreferredSize());
startDatePicker.setMaximumSize(startDatePicker.getPreferredSize());
startDatePicker.setToolTipText("Filter for entries which occured after the chosen date");
startDatePicker.addDateListener(startDateListener);

endDatePicker.setDateFormat(sdf);
endDatePicker.setDate(null);
endDatePicker.setEditable(false);
endDatePicker.setEnabled(false);
endDatePicker.setPreferredSize(new Dimension(150, 25));
endDatePicker.setMinimumSize(startDatePicker.getPreferredSize());
endDatePicker.setMaximumSize(startDatePicker.getPreferredSize());
endDatePicker.setToolTipText("Filter for entries which occured before the chosen date");
endDatePicker.addDateListener(endDateListener);

this.add(new JLabel("Types:"));
this.add(comboBox);
this.add(new JLabel("Start Date:"));
this.add(new JLabel("Start Date >"));
this.add(startDatePicker);
this.add(new JLabel("End Date: "));
this.add(new JLabel("End Date <"));
this.add(endDatePicker);
this.add(new JLabel("Show Elapsed Time > "));
this.add(new JLabel("Elapsed Time >"));
this.add(elapsedTimeFilterField);
this.add(new JLabel("Filter Details: "));
this.add(new JLabel("Filter Details:"));
this.add(detailFilterField);
this.add(clearFiltersButton);

}

private DateListener startDateListener = new DateListener() {

@Override
public void dateChanged(DateEvent evt) {
rootCaseFilter.filterStartDate(evt.getSelectedDate().getTime());
if(evt.getSelectedDate() != null) rootCaseFilter.filterStartDate(evt.getSelectedDate().getTime());
}
};

private DateListener endDateListener = new DateListener() {

@Override
public void dateChanged(DateEvent evt) {
rootCaseFilter.filterEndDate(evt.getSelectedDate().getTime());
if(evt.getSelectedDate() != null) rootCaseFilter.filterEndDate(evt.getSelectedDate().getTime());
}
};

Expand All @@ -123,7 +141,6 @@ public void keyReleased(KeyEvent evt) {
};

private KeyAdapter detailFieldListener = new KeyAdapter() {

@Override
public void keyReleased(KeyEvent evt) {
if (evt != null) {
Expand All @@ -138,23 +155,27 @@ public void keyReleased(KeyEvent evt) {
};

private ActionListener clearFiltersListener = new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
rootCaseFilter.clearFilters();
comboBox.resetCheckBoxes(checkBoxes, false);
elapsedTimeFilterField.setValue(null);
detailFilterField.setText("");
clearFilters();
}
};

private CheckComboBoxSelectionChangedListener checkBoxListener = new CheckComboBoxSelectionChangedListener() {

@Override
public void selectionChanged() {
rootCaseFilter.filterType(comboBox);
}
};

private void clearFilters() {
rootCaseFilter.clearFilters();
comboBox.resetCheckBoxes(checkBoxes, false);
elapsedTimeFilterField.setValue(null);
detailFilterField.setText("");
startDatePicker.setDate(startLogTimeStamp);
endDatePicker.setDate(endLogTimeStamp);
}

/**
* enables the filters and generates a new instance of the filter class
Expand All @@ -168,6 +189,16 @@ public void enableFilters(JTable rootCaseTable) {
startDatePicker.setEnabled(true);
endDatePicker.setEnabled(true);
rootCaseFilter = new RootCaseFilter(rootCaseTable);

// set start- and end-date after rootCaseFilter is initialized
if(rootCaseTable != null && rootCaseTable.getModel() != null) {
List<RmRootCase> rootCases = ((RootCaseTableModel)rootCaseTable.getModel()).getUseCases();
Collections.sort(rootCases, new LogTimeStampComparator());
// substract and add one millisecond to include the first and the last root case in the filter
startLogTimeStamp = new Date(rootCases.get(0).getRmNode().getData().getLogTimeStamp().getTime()-1);
endLogTimeStamp = new Date(rootCases.get(rootCases.size()-1).getRmNode().getData().getLogTimeStamp().getTime()+1);
}
clearFilters();
}

/**
Expand All @@ -179,7 +210,9 @@ public void disableFilters() {
comboBox.setEnabled(false);
clearFiltersButton.setEnabled(false);
startDatePicker.setEnabled(false);
startDatePicker.setDate(null);
endDatePicker.setEnabled(false);
endDatePicker.setDate(null);
if (rootCaseFilter != null)
rootCaseFilter.clearFilters();
}
Expand Down
Loading

0 comments on commit dbebe32

Please sign in to comment.