Skip to content

Commit 670c1ca

Browse files
committed
Fix color chooser, visibility, and formatting in User Events Tool
Change-Id: I63ab58e97e3e3766808e957756f5ba4e5ff03c05
1 parent 97f6fdc commit 670c1ca

File tree

10 files changed

+264
-41
lines changed

10 files changed

+264
-41
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package projections.Tools.UserEvents;
2+
3+
import projections.gui.*;
4+
5+
import javax.swing.JFrame;
6+
import javax.swing.JTable;
7+
import javax.swing.JScrollPane;
8+
import javax.swing.JPanel;
9+
import javax.swing.JButton;
10+
import javax.swing.table.TableColumn;
11+
12+
import java.awt.BorderLayout;
13+
import java.awt.FlowLayout;
14+
import java.awt.Color;
15+
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
import java.util.Map;
19+
20+
public class ChooseUserEntriesWindow extends JFrame {
21+
22+
private int myRun = 0;
23+
24+
final private ColorUpdateNotifier gw;
25+
final private EntryMethodVisibility data;
26+
private List<List> tabledata;
27+
final private Map<Integer, String> entryNames;
28+
final private GenericGraphColorer colorer;
29+
final private String[] eventNames;
30+
final private String option;
31+
32+
public ChooseUserEntriesWindow(EntryMethodVisibility data, ColorUpdateNotifier gw, GenericGraphColorer colorer, Map<Integer, String> entryNames, String option) {
33+
this.data = data;
34+
this.gw = gw;
35+
this.colorer = colorer;
36+
this.entryNames = entryNames;
37+
this.eventNames = null;
38+
this.option = option;
39+
createLayout();
40+
}
41+
42+
ChooseUserEntriesWindow(EntryMethodVisibility data, ColorUpdateNotifier gw, GenericGraphColorer colorer, Map<Integer, String> entryNames, String option, String[] eventNames) {
43+
this.data = data;
44+
this.gw = gw;
45+
this.colorer = colorer;
46+
this.entryNames = entryNames;
47+
this.eventNames = eventNames;
48+
this.option = option;
49+
createLayout();
50+
}
51+
52+
private void createLayout() {
53+
setTitle("Choose which User " + option + "s are displayed");
54+
List<String> columnNames = new ArrayList<>(4);
55+
columnNames.add("Visible");
56+
columnNames.add("User " + option + " Name");
57+
columnNames.add("ID");
58+
columnNames.add("Color");
59+
60+
tabledata = new ArrayList<>();
61+
62+
makeTableData();
63+
64+
final MyTableModel tableModel = new MyTableModel(tabledata, columnNames, data, true);
65+
66+
JTable table = new JTable(tableModel);
67+
initColumnSizes(table);
68+
69+
table.setDefaultRenderer(ClickableColorBox.class, new ColorRenderer());
70+
table.setDefaultEditor(ClickableColorBox.class, new ColorEditor());
71+
table.setAutoCreateRowSorter(true);
72+
73+
JScrollPane scroller = new JScrollPane(table);
74+
scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
75+
76+
JPanel p = new JPanel();
77+
p.setLayout(new BorderLayout());
78+
79+
JPanel buttonPanel = new JPanel();
80+
buttonPanel.setLayout(new FlowLayout());
81+
JButton checkAll = new JButton("Make All Visible");
82+
checkAll.addActionListener(actionEvent -> {
83+
changeVisibility(true, tableModel);
84+
tableModel.fireTableDataChanged();
85+
data.displayMustBeRedrawn();
86+
});
87+
JButton uncheckAll = new JButton("Hide All");
88+
uncheckAll.addActionListener(actionEvent -> {
89+
changeVisibility(false, tableModel);
90+
tableModel.fireTableDataChanged();
91+
data.displayMustBeRedrawn();
92+
});
93+
buttonPanel.add(checkAll);
94+
buttonPanel.add(uncheckAll);
95+
p.add(buttonPanel, BorderLayout.NORTH);
96+
p.add(scroller, BorderLayout.CENTER);
97+
this.setContentPane(p);
98+
99+
pack();
100+
setSize(800, 400);
101+
setVisible(true);
102+
}
103+
104+
private void makeTableData() {
105+
tabledata.clear();
106+
for (Integer id : entryNames.keySet()) {
107+
int currIndex = id;
108+
if (eventNames != null) {
109+
String currName = entryNames.get(id);
110+
for (int i = 0; i < eventNames.length; i++) {
111+
if (currName.equals(eventNames[i])) {
112+
currIndex = i;
113+
break;
114+
}
115+
}
116+
}
117+
List<Object> tableRow = new ArrayList<>(4);
118+
tableRow.add(data.entryIsVisibleID(currIndex));
119+
if (eventNames != null)
120+
tableRow.add(eventNames[currIndex]);
121+
else
122+
tableRow.add(entryNames.get(currIndex));
123+
tableRow.add(currIndex);
124+
tableRow.add(new ClickableColorBox(currIndex, (Color) colorer.getColorMap()[currIndex], myRun, gw, colorer));
125+
tabledata.add(tableRow);
126+
}
127+
}
128+
129+
private void initColumnSizes(JTable table) {
130+
TableColumn column;
131+
132+
column = table.getColumnModel().getColumn(0);
133+
column.setPreferredWidth(70);
134+
135+
column = table.getColumnModel().getColumn(1);
136+
column.setPreferredWidth(680);
137+
138+
column = table.getColumnModel().getColumn(2);
139+
column.setPreferredWidth(50);
140+
}
141+
142+
private void changeVisibility(boolean visible, MyTableModel tableModel) {
143+
for (List<Object> v : tabledata) {
144+
Integer id = (Integer) v.get(2);
145+
if (visible)
146+
data.makeEntryVisibleID(id);
147+
else
148+
data.makeEntryInvisibleID(id);
149+
}
150+
for (List<Object> v : tabledata) {
151+
v.set(0, visible);
152+
}
153+
tableModel.fireTableDataChanged();
154+
data.displayMustBeRedrawn();
155+
}
156+
}

src/projections/Tools/UserEvents/UserEventsWindow.java

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* Legends are in place (and probably replace the name)
2525
*/
2626
public class UserEventsWindow extends GenericGraphWindow
27-
implements ActionListener
27+
implements ActionListener, EntryMethodVisibility
2828
{
2929

3030
private UserEventsWindow thisWindow;
@@ -54,6 +54,8 @@ public class UserEventsWindow extends GenericGraphWindow
5454
private double[][] graphData;
5555
private double[][] timeSpent;
5656
private double[][] callRate;
57+
private boolean[] display_mask;
58+
private GenericGraphColorer colorer;
5759

5860
// buttons to switch between displaying "time spent" vs "call rate"
5961
private JRadioButton timeSpentButton;
@@ -69,19 +71,35 @@ public class UserEventsWindow extends GenericGraphWindow
6971
private double unitTime = 1;
7072
private String unitTimeStr = "ms";
7173

72-
private DecimalFormat _format;
74+
private static DecimalFormat decimalFormatter = new DecimalFormat("###,###.###");
75+
private static DecimalFormat scientificFormatter = new DecimalFormat("0.###E0");
7376

7477
public UserEventsWindow(MainWindow mainWindow) {
7578
super("Projections User Events Tool - " +
7679
MainWindow.runObject[myRun].getFilename() + ".sts", mainWindow);
7780
// hardcode start. Usually derived from MainWindow.runObject[myRun].java
7881
numActivities = MainWindow.runObject[myRun].getNumUserDefinedEvents();
7982
activityNames = MainWindow.runObject[myRun].getUserEventNames();
80-
// Normally would set activity names here.
81-
82-
_format = new DecimalFormat("###,###.###");
83+
display_mask = new boolean[numActivities];
84+
for(int i = 0; i < numActivities; i++)
85+
display_mask[i] = true;
86+
colorer = new GenericGraphColorer() {
87+
private final Paint[] colorMap = ColorManager.createColorMap(numActivities);
88+
@Override
89+
public Paint[] getColorMap() {
90+
return colorMap;
91+
}
92+
};
8393

8494
createMenus();
95+
if(mChooseColors.getActionListeners()[0] != null)
96+
mChooseColors.removeActionListener(mChooseColors.getActionListeners()[0]);
97+
mChooseColors.addActionListener(new ActionListener() {
98+
@Override
99+
public void actionPerformed(ActionEvent actionEvent) {
100+
new ChooseUserEntriesWindow(thisWindow, thisWindow, colorer, MainWindow.runObject[myRun].getSts().getUserEventNameMap(), "Event", activityNames);
101+
}
102+
});
85103
createLayout();
86104
pack();
87105
thisWindow = this;
@@ -224,33 +242,14 @@ private void constructToolData() {
224242
graphData = timeSpent;
225243
}
226244

227-
228-
229-
230-
231-
232-
/** A class that provides the colors for the display */
233-
public class UserEventColorer implements GenericGraphColorer {
234-
public Paint[] getColorMap() {
235-
int numUserEvents = MainWindow.runObject[myRun].getNumUserDefinedEvents();
236-
Paint[] outColors = ColorManager.createColorMap(numUserEvents);
237-
return outColors;
238-
}
239-
}
240-
241-
242-
243-
244245
protected void setGraphSpecificData() {
245246
setXAxis("Processors", processorList);
246247
setYAxisLabelAndUnits();
247248
setYAxis(yAxisLabel, yAxisUnits);
248-
setDataSource("User Events", graphData, new UserEventColorer() , this);
249+
setDataSource("User Events", graphData, colorer, this, display_mask);
249250
refreshGraph();
250251
}
251252

252-
253-
254253
public String[] getPopup(int xVal, int yVal) {
255254
if ((xVal < 0) || (yVal < 0)) {
256255
return null;
@@ -260,9 +259,9 @@ public String[] getPopup(int xVal, int yVal) {
260259
rString[0] = "Name: " + activityNames[yVal];
261260
rString[1] = "Time Spent: " + U.humanReadableString((long)(timeSpent[xVal][yVal]));
262261
rString[2] = String.format("Rate: %s calls/%s (%s calls)",
263-
_format.format(callRate[xVal][yVal]),
262+
formatNumber(callRate[xVal][yVal]),
264263
unitTimeStr,
265-
_format.format(callRate[xVal][yVal] * intervalSize/unitTime));
264+
formatNumber(callRate[xVal][yVal] * intervalSize/unitTime));
266265
return rString;
267266
}
268267

@@ -284,17 +283,14 @@ public void actionPerformed(ActionEvent e) {
284283
else if (e.getSource() == microseconds) {
285284
scaleHistogramData(0.001);
286285
setGraphSpecificData();
287-
refreshGraph();
288286
}
289287
else if (e.getSource() == milliseconds) {
290288
scaleHistogramData(1.0);
291289
setGraphSpecificData();
292-
refreshGraph();
293290
}
294291
else if (e.getSource() == seconds) {
295292
scaleHistogramData(1000.0);
296293
setGraphSpecificData();
297-
refreshGraph();
298294
}
299295
}
300296

@@ -321,4 +317,46 @@ private void setYAxisLabelAndUnits() {
321317
}
322318
}
323319

320+
@Override
321+
public void displayMustBeRedrawn() {
322+
setGraphSpecificData();
323+
refreshGraph();
324+
}
325+
326+
@Override
327+
public boolean entryIsVisibleID(Integer id) {
328+
return display_mask[id];
329+
}
330+
331+
@Override
332+
public int[] getEntriesArray() {
333+
return null;
334+
}
335+
336+
@Override
337+
public void makeEntryInvisibleID(Integer id) {
338+
display_mask[id] = false;
339+
}
340+
341+
@Override
342+
public void makeEntryVisibleID(Integer id) {
343+
display_mask[id] = true;
344+
}
345+
346+
@Override
347+
public boolean hasEntryList() {
348+
return false;
349+
}
350+
351+
@Override
352+
public boolean handleIdleOverhead() {
353+
return false;
354+
}
355+
356+
private static String formatNumber(double number) {
357+
String formatted = decimalFormatter.format(number);
358+
if (formatted.equals("0"))
359+
formatted = scientificFormatter.format(number);
360+
return formatted;
361+
}
324362
}

src/projections/gui/ClickableColorBox.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ public class ClickableColorBox {
1010
final private int id;
1111
final private GenericGraphColorer colorer;
1212

13-
ClickableColorBox(int id_, Color c_, int myRun_, ColorUpdateNotifier gw_) {
13+
public ClickableColorBox(int id_, Color c_, int myRun_, ColorUpdateNotifier gw_) {
1414
id = id_;
1515
c = c_;
1616
myRun = myRun_;
1717
gw = gw_;
1818
colorer = null;
1919
}
2020

21-
ClickableColorBox(int id_, Color c_, int myRun_, ColorUpdateNotifier gw_, GenericGraphColorer colorer_) {
21+
public ClickableColorBox(int id_, Color c_, int myRun_, ColorUpdateNotifier gw_, GenericGraphColorer colorer_) {
2222
id = id_;
2323
c = c_;
2424
myRun = myRun_;

src/projections/gui/GenericGraphWindow.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,18 +188,26 @@ protected void setYAxis(String title, String units){
188188
// This should be the correct way of setting a data source with a partial
189189
// set of colors
190190
protected void setDataSource(String title, double data[][], GenericGraphColorer colorer, GenericGraphWindow parent) {
191+
setDataSource(title, data, colorer, parent, null);
192+
}
193+
194+
protected void setDataSource(String title, double data[][], GenericGraphWindow parent) {
195+
setDataSource( title, data, new GenericGraphDefaultColors(), parent, null);
196+
}
197+
198+
protected void setDataSource(String title, double data[][], GenericGraphColorer colorer, GenericGraphWindow parent, boolean[] mask) {
191199
dataSource = new DataSource2D(title, data, parent);
200+
if (mask != null) {
201+
// Set display_mask
202+
dataSource.setMask(mask);
203+
}
192204
this.colorer = colorer;
193205
dataSource.setColors(colorer.getColorMap());
194206
if (yAxis != null) {
195207
yAxis = new YAxisAuto(yAxis.getTitle(),yAxis.getUnits(),dataSource);
196208
}
197209
}
198210

199-
protected void setDataSource(String title, double data[][], GenericGraphWindow parent) {
200-
setDataSource( title, data, new GenericGraphDefaultColors(), parent);
201-
}
202-
203211
// refresh graph
204212
protected void refreshGraph(){
205213
if(graphCanvas!=null){

src/projections/gui/MyTableModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class MyTableModel extends AbstractTableModel implements ActionListener {
1212
final private List<List> tabledata;
1313
final private List<String> columnNames;
1414

15-
MyTableModel(List<List> TD, List<String> CN, EntryMethodVisibility data_, boolean checkboxesVisible) {
15+
public MyTableModel(List<List> TD, List<String> CN, EntryMethodVisibility data_, boolean checkboxesVisible) {
1616
tabledata = TD;
1717
columnNames = CN;
1818
data = data_;

src/projections/gui/graph/DataSource.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public void setColors(Paint paints[]) {
9292
this.paints = paints;
9393
}
9494

95+
public abstract void setMask(boolean[] mask);
9596

9697
/**
9798
* Return the values associated with this index.

0 commit comments

Comments
 (0)