-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from Florian-W/master
Implemented Issue #5 - filter root cases
- Loading branch information
Showing
6 changed files
with
703 additions
and
77 deletions.
There are no files selected for viewing
170 changes: 170 additions & 0 deletions
170
src/main/java/de/ibm/issw/requestmetrics/engine/filter/RootCaseFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
package de.ibm.issw.requestmetrics.engine.filter; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Date; | ||
import java.util.List; | ||
|
||
import javax.swing.JTable; | ||
import javax.swing.RowFilter; | ||
import javax.swing.RowFilter.ComparisonType; | ||
import javax.swing.table.TableRowSorter; | ||
|
||
import de.ibm.issw.requestmetrics.gui.CheckComboBox; | ||
import de.ibm.issw.requestmetrics.gui.UsecaseTableModel; | ||
|
||
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 JTable rootCaseTable; | ||
|
||
private final int TIMESTAMP_COLUMN = 1; | ||
private final int ELAPSED_TIME_COLUMN = 2; | ||
private final int TYPE_COLUMN = 3; | ||
private final int DETAIL_COLUMN = 5; | ||
|
||
public RootCaseFilter(JTable rootCaseTable) { | ||
this.rootCaseTable = rootCaseTable; | ||
} | ||
|
||
/** | ||
* uses a numberfilter in the elapsed time column. whenever the input | ||
* changes, the old filter is removed to ensure that filter is only | ||
* applied for the current input | ||
* @param userInput | ||
*/ | ||
public void filterElapsedTime(final Object userInput) { | ||
// | ||
if (elapsedTimeRowFilter != null && filters.contains(elapsedTimeRowFilter)) | ||
filters.remove(elapsedTimeRowFilter); | ||
elapsedTimeRowFilter = new RowFilter<UsecaseTableModel, Object>() { | ||
|
||
// | ||
@Override | ||
public boolean include(javax.swing.RowFilter.Entry<? extends UsecaseTableModel, ? extends Object> entry) { | ||
if (rootCaseTable != null){ | ||
Long elapsedTime = (Long) rootCaseTable.getModel().getValueAt((int) entry.getIdentifier(), ELAPSED_TIME_COLUMN); | ||
if (userInput == null || elapsedTime >= (Long) userInput) | ||
return true; | ||
else | ||
return false; | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
}; | ||
if (elapsedTimeRowFilter != null) { | ||
filters.add(elapsedTimeRowFilter); | ||
} | ||
buildCompoundFilter(); | ||
} | ||
|
||
/** | ||
* uses a regex filter in the detail column. whenever the input changes, | ||
* the old filter is removed to ensure that filter is only applied for | ||
* the current input | ||
* @param userInput the input we want to filter for | ||
*/ | ||
public void filterDetails(final String userInput) { | ||
if (detailFilter != null && filters.contains(detailFilter)) | ||
filters.remove(detailFilter); | ||
|
||
try { | ||
detailFilter = RowFilter.regexFilter(userInput, DETAIL_COLUMN); | ||
} catch (Exception e) { | ||
//TODO: define exception handling | ||
} | ||
|
||
if (detailFilter != null) | ||
filters.add(detailFilter); | ||
buildCompoundFilter(); | ||
} | ||
|
||
/** | ||
* | ||
* @param startDate | ||
*/ | ||
public void filterStartDate(final Date startDate) { | ||
if (dateTimeStartFilter != null && filters.contains(dateTimeStartFilter)) | ||
filters.remove(dateTimeStartFilter); | ||
|
||
dateTimeStartFilter = RowFilter.dateFilter(ComparisonType.AFTER, startDate, TIMESTAMP_COLUMN); | ||
|
||
if (dateTimeStartFilter != null) | ||
filters.add(dateTimeStartFilter); | ||
buildCompoundFilter(); | ||
} | ||
|
||
/** | ||
* uses a date filter in the timestamp column. whenever the input changes, | ||
* the old filter is removed to ensure that filter is only applied for | ||
* the current input | ||
* @param endDate | ||
*/ | ||
public void filterEndDate(final Date endDate) { | ||
if (dateTimeEndFilter != null && filters.contains(dateTimeEndFilter)) | ||
filters.remove(dateTimeEndFilter); | ||
|
||
dateTimeEndFilter = RowFilter.dateFilter(ComparisonType.BEFORE, endDate, TIMESTAMP_COLUMN); | ||
|
||
if (dateTimeEndFilter != null) | ||
filters.add(dateTimeEndFilter); | ||
buildCompoundFilter(); | ||
} | ||
|
||
/** | ||
* uses a date filter in the timestamp column. whenever the input changes, | ||
* the old filter is removed to ensure that filter is only applied for | ||
* the current input | ||
* @param comboBox | ||
*/ | ||
public void filterType(CheckComboBox comboBox) { | ||
if (typeFilter != null && filters.contains(typeFilter)) | ||
filters.remove(typeFilter); | ||
|
||
List<RowFilter<UsecaseTableModel, Object>> typeFilterList = new ArrayList<RowFilter<UsecaseTableModel, Object>>(); | ||
if (comboBox.getSelectedItems() != null) { | ||
for (Object type : comboBox.getSelectedItems()) { | ||
RowFilter<UsecaseTableModel, Object> rowFilter = RowFilter.regexFilter(type.toString(), TYPE_COLUMN); | ||
typeFilterList.add(rowFilter); | ||
} | ||
typeFilter = RowFilter.orFilter(typeFilterList); | ||
filters.add(typeFilter); | ||
} else { | ||
filters.remove(typeFilter); | ||
} | ||
|
||
buildCompoundFilter(); | ||
} | ||
|
||
/** | ||
* clears the all filters and thereby ensures that the table is unfiltered | ||
* (i.e. all table entries are displayed again) | ||
*/ | ||
public void clearFilters() { | ||
filters.clear(); | ||
|
||
if (rootCaseTable != null) { | ||
TableRowSorter<UsecaseTableModel> sorter = new TableRowSorter<UsecaseTableModel>((UsecaseTableModel) rootCaseTable.getModel()); | ||
rootCaseTable.setRowSorter(sorter); | ||
sorter.setRowFilter(null); | ||
} | ||
} | ||
|
||
/** | ||
* applies all the different filters on the table by using an "andFilter" | ||
* thereby ensures that different filters can be applied at the same time | ||
*/ | ||
private void buildCompoundFilter() { | ||
RowFilter<UsecaseTableModel, Object> compoundFilter = RowFilter.andFilter(filters); | ||
|
||
TableRowSorter<UsecaseTableModel> sorter = new TableRowSorter<UsecaseTableModel>((UsecaseTableModel) rootCaseTable.getModel()); | ||
rootCaseTable.setRowSorter(sorter); | ||
sorter.setRowFilter(compoundFilter); | ||
} | ||
} |
211 changes: 211 additions & 0 deletions
211
src/main/java/de/ibm/issw/requestmetrics/gui/CheckComboBox.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
package de.ibm.issw.requestmetrics.gui; | ||
|
||
import java.awt.Color; | ||
import java.awt.Component; | ||
import java.awt.event.ActionEvent; | ||
import java.util.EventListener; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
import java.util.Vector; | ||
|
||
import javax.swing.DefaultListCellRenderer; | ||
import javax.swing.JCheckBox; | ||
import javax.swing.JComboBox; | ||
import javax.swing.JList; | ||
import javax.swing.JSeparator; | ||
import javax.swing.ListCellRenderer; | ||
|
||
@SuppressWarnings({ "serial", "rawtypes", "unchecked" }) | ||
public class CheckComboBox extends JComboBox { | ||
private List<CheckBoxObject> checkBoxesList; | ||
private Map<Object, Boolean> mapCheckBoxObjectsSelected; | ||
private List<CheckComboBoxSelectionChangedListener> changedListeners = new Vector(); | ||
|
||
private Object nullObject = new Object(); | ||
|
||
public CheckComboBox(final Set objects) { | ||
resetCheckBoxes(objects, false); | ||
} | ||
|
||
public void addSelectionChangedListener(CheckComboBoxSelectionChangedListener listener) { | ||
if (listener == null) { | ||
return; | ||
} | ||
changedListeners.add(listener); | ||
} | ||
|
||
public void resetCheckBoxes(final Set objects, boolean selected) { | ||
mapCheckBoxObjectsSelected = new LinkedHashMap(); | ||
for (Object object : objects) { | ||
mapCheckBoxObjectsSelected.put(object, selected); | ||
} | ||
|
||
reset(); | ||
} | ||
|
||
public Object[] getSelectedItems() { | ||
Set selectedItemsSet = new TreeSet(); // alphabetically | ||
for (Map.Entry<Object, Boolean> entry : mapCheckBoxObjectsSelected.entrySet()) { | ||
Object object = entry.getKey(); | ||
Boolean selected = entry.getValue(); | ||
|
||
if (selected) { | ||
selectedItemsSet.add(object); | ||
} | ||
} | ||
|
||
if (selectedItemsSet.isEmpty()) | ||
return null; | ||
|
||
return selectedItemsSet.toArray(new Object[selectedItemsSet.size()]); | ||
} | ||
|
||
public void reset() { | ||
this.removeAllItems(); | ||
|
||
initCheckBoxes(); | ||
|
||
this.addItem(new String()); | ||
for (JCheckBox checkBox : checkBoxesList) { | ||
this.addItem(checkBox); | ||
} | ||
|
||
setRenderer(new CheckBoxRenderer(checkBoxesList)); | ||
addActionListener(this); | ||
} | ||
|
||
private void initCheckBoxes() { | ||
checkBoxesList = new Vector<CheckBoxObject>(); | ||
|
||
boolean selectedNone = false; | ||
|
||
CheckBoxObject checkBox; | ||
for (Map.Entry<Object, Boolean> entry : mapCheckBoxObjectsSelected.entrySet()) { | ||
Object object = entry.getKey(); | ||
Boolean selected = entry.getValue(); | ||
|
||
if (selected) | ||
selectedNone = false; | ||
|
||
checkBox = new CheckBoxObject(object); | ||
checkBox.setSelected(selected); | ||
checkBoxesList.add(checkBox); | ||
} | ||
|
||
checkBox = new CheckBoxObject("Clear Type Filters"); | ||
checkBox.setSelected(selectedNone); | ||
checkBoxesList.add(checkBox); | ||
} | ||
|
||
private void checkBoxSelectionChanged(int index) { | ||
int n = checkBoxesList.size(); | ||
if (index < 0 || index >= n) | ||
return; | ||
|
||
if (index < n - 1) { | ||
CheckBoxObject checkBox = checkBoxesList.get(index); | ||
if (checkBox.getObject() == nullObject) { | ||
return; | ||
} | ||
|
||
if (checkBox.isSelected()) { | ||
checkBox.setSelected(false); | ||
mapCheckBoxObjectsSelected.put(checkBox.getObject(), false); | ||
|
||
checkBoxesList.get(n - 1).setSelected(getSelectedItems() == null); // select | ||
// none | ||
} else { | ||
checkBox.setSelected(true); | ||
mapCheckBoxObjectsSelected.put(checkBox.getObject(), true); | ||
|
||
checkBoxesList.get(n - 1).setSelected(false); // select none | ||
} | ||
} else if (index == n - 1){ | ||
for (Object object : mapCheckBoxObjectsSelected.keySet()) { | ||
mapCheckBoxObjectsSelected.put(object, false); | ||
} | ||
|
||
for (int i = 0; i < n - 1; i++) { | ||
checkBoxesList.get(i).setSelected(false); | ||
} | ||
checkBoxesList.get(n - 1).setSelected(true); | ||
} | ||
} | ||
|
||
@Override | ||
public void actionPerformed(ActionEvent e) { | ||
int selection = getSelectedIndex(); | ||
|
||
if (selection == 0) { | ||
getUI().setPopupVisible(this, true); | ||
} else if (selection > 0) { | ||
checkBoxSelectionChanged(selection - 1); | ||
for (CheckComboBoxSelectionChangedListener l : changedListeners) { | ||
l.selectionChanged(); | ||
} | ||
} | ||
|
||
this.setSelectedIndex(-1); // clear selection | ||
} | ||
|
||
// checkbox renderer for combobox | ||
class CheckBoxRenderer implements ListCellRenderer { | ||
private final DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer(); | ||
private JSeparator separator; | ||
private final List<CheckBoxObject> checkBoxes; | ||
|
||
public CheckBoxRenderer(final List<CheckBoxObject> checkBoxes) { | ||
this.checkBoxes = checkBoxes; | ||
separator = new JSeparator(JSeparator.HORIZONTAL); | ||
} | ||
|
||
// @Override | ||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, | ||
boolean cellHasFocus) { | ||
if (index > 0 && index <= checkBoxes.size()) { | ||
CheckBoxObject checkBox = checkBoxes.get(index - 1); | ||
if (checkBox.getObject() == nullObject) { | ||
return separator; | ||
} | ||
|
||
checkBox.setBackground(isSelected ? Color.blue : Color.white); | ||
checkBox.setForeground(isSelected ? Color.white : Color.black); | ||
|
||
return checkBox; | ||
} | ||
|
||
String string; | ||
Object[] objects = getSelectedItems(); | ||
Vector<String> strings = new Vector(); | ||
if (objects == null) { | ||
string = "Please select one or more ID types"; | ||
} else { | ||
for (Object object : objects) { | ||
strings.add(object.toString()); | ||
} | ||
string = strings.toString(); | ||
} | ||
return defaultRenderer.getListCellRendererComponent(list, string, index, isSelected, cellHasFocus); | ||
} | ||
} | ||
|
||
class CheckBoxObject extends JCheckBox { | ||
private final Object object; | ||
|
||
public CheckBoxObject(final Object obj) { | ||
super(obj.toString()); | ||
this.object = obj; | ||
} | ||
|
||
public Object getObject() { | ||
return object; | ||
} | ||
} | ||
} | ||
|
||
interface CheckComboBoxSelectionChangedListener extends EventListener { | ||
public void selectionChanged(); | ||
} |
Oops, something went wrong.