http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/SequenceDiagram.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/SequenceDiagram.java b/geode-core/src/test/java/org/apache/sequence/SequenceDiagram.java deleted file mode 100644 index 1663add..0000000 --- a/geode-core/src/test/java/org/apache/sequence/SequenceDiagram.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.*; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Created by IntelliJ IDEA. - * User: dsmith - * Date: Oct 29, 2010 - * Time: 4:18:40 PM - * To change this template use File | Settings | File Templates. - */ -public class SequenceDiagram extends JPanel { - - /** - * - */ - private static final Color HIGHLIGHT_COLOR = Color.RED; - - private final List<String> lineNames; - private final Map<String, List<String>> shortLineNames; - private final SortedMap<Comparable, SubDiagram> subDiagrams = new TreeMap<Comparable, SubDiagram>(); - private final StateColorMap colorMap = new StateColorMap(); - private final long minTime; - private final long maxTime; - - private static int PADDING_BETWEEN_LINES = 100; - private static int Y_PADDING = 20; - private static final int STATE_WIDTH = 20; - private static final int LINE_LABEL_BOUNDARY = 5; - private static final int AXIS_SIZE=35; - - private int lineStep; - private int lineWidth; - private Popup mouseover; - private LifelineState mouseoverState; - private LifelineState selectedState; - - public SequenceDiagram(long minTime, long maxTime, List<String> lineNames, LineMapper lineMapper) { - this.lineNames = lineNames; - this.shortLineNames = parseShortNames(lineNames, lineMapper); - this.minTime = minTime; - this.maxTime = maxTime; - int width = getInitialWidth(); - int height = 500; - super.setPreferredSize(new Dimension(width, height)); - resizeMe(width, height); - addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - Component source = (Component) e.getSource(); - resizeMe(source.getWidth(), source.getHeight()); - } - }); - setBackground(Color.WHITE); - } - - private Map<String, List<String>> parseShortNames(List<String> lineNames, LineMapper lineMapper) { - Map<String, List<String>> shortNames = new LinkedHashMap<String, List<String>>(lineNames.size()); - for(String name : lineNames) { - String shortName = lineMapper.getShortNameForLine(name); - List<String> list = shortNames.get(shortName); - if(list == null) { - list = new ArrayList<String>(); - shortNames.put(shortName, list); - } - list.add(name); - } - - return shortNames; - } - - public List<Comparable> getSubDiagramsNames() { - return new ArrayList<Comparable>(subDiagrams.keySet()); - - } - - public void addSubDiagram(Comparable name, Map<String, Lifeline> lines, List<Arrow> arrows) { - subDiagrams.put(name, new SubDiagram(name, lines, arrows)); - } - - public void removeSubDiagram(Comparable name) { - this.subDiagrams.remove(name); - } - - private int getInitialWidth() { - return (this.shortLineNames.size()) * PADDING_BETWEEN_LINES; - } - - public void resizeMe(int width, int height) { - this.setPreferredSize(new Dimension(width, height)); - float xZoom = width / (float) getInitialWidth(); - - - long elapsedTime = maxTime - minTime; - double yScale = height / (double) elapsedTime; -// long yBase = (long) (minTime - ((long) Y_PADDING / yScale)); - long yBase = minTime; - lineStep = (int) (PADDING_BETWEEN_LINES * xZoom); - lineWidth = (int) (STATE_WIDTH * xZoom); - - if(subDiagrams.size() <= 0) { - return; - } - - int sublineWidth = lineWidth / subDiagrams.size(); - int sublineIndex = 0; - for(SubDiagram diagram : subDiagrams.values()) { - int lineIndex = 0; - for(List<String> fullNames : shortLineNames.values()) { - for(String name : fullNames) { - Lifeline line = diagram.lifelines.get(name); - if(line != null) { - int lineX = lineIndex * lineStep + sublineIndex * sublineWidth; - line.resize(lineX, sublineWidth, yBase, yScale); - } - } - lineIndex++; - } - sublineIndex++; - } - } - - public void showPopupText(int x, int y, int xOnScreen, int yOnScreen) { - LifelineState state = getStateAt(x, y); - if(state == mouseoverState) { - return; - } - if(mouseover != null) { - mouseover.hide(); - } - if(state == null) { - mouseover = null; - mouseoverState = null; - } else { - Component popupContents = state.getPopup(); - mouseoverState = state; - mouseover = PopupFactory.getSharedInstance().getPopup(this, popupContents, xOnScreen + 20, yOnScreen); - mouseover.show(); - } - } - - public void selectState(int x, int y) { - LifelineState state = getStateAt(x, y); - if(state == selectedState) { - return; - } - - if(selectedState != null) { - fireRepaintOfDependencies(selectedState); - } - - selectedState = state; - - if(state != null) { - fireRepaintOfDependencies(state); - } - } - - private LifelineState getStateAt(int x, int y) { - //TODO - this needs some - //serious optimization to go straight to the right state - // I think we need a tree map of of lines, keyed by x offset - //and a keymap of states keyed by y offset. - //That could make painting faster as well. - List<String> reverseList = new ArrayList<String>(lineNames); - Collections.reverse(reverseList); - for(SubDiagram diagram : subDiagrams.values()) { - for(String name : reverseList) { - Lifeline line = diagram.lifelines.get(name); - if(line != null) { - if(line.getX() < x && line.getX() + line.getWidth() > x) { - LifelineState state = line.getStateAt(y); - if(state != null) { - return state; - } - } - } - } - } - return null; - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - Graphics2D g2 = (Graphics2D) g.create(); - //TODO - we should clip these to the visible lines - for(SubDiagram subDiagram : subDiagrams.values()) { - subDiagram.paintStates(g2, colorMap); - } - - for(SubDiagram subDiagram : subDiagrams.values()) { - subDiagram.paintArrows(g2, colorMap); - } - paintHighlightedComponents(g2, selectedState, new HashSet<LifelineState>()); - } - - private void fireRepaintOfDependencies(LifelineState state) { - //TODO - it might be more efficient to repaint just the changed - //areas, but right now this will do. - repaint(); - } - - private void paintHighlightedComponents(Graphics2D g2, LifelineState endingState, Set<LifelineState> visited) { - if(!visited.add(endingState)) { - //Prevent cycles - return; - } - g2.setColor(HIGHLIGHT_COLOR); - if(endingState != null) { - endingState.highlight(g2); - - for(Arrow arrow : endingState.getInboundArrows()) { - arrow.paint(g2); - paintHighlightedComponents(g2, arrow.getStartingState(), visited); - } - } - - - } - - public long getMinTime() { - return minTime; - } - - public long getMaxTime() { - return maxTime; - } - - public JComponent createMemberAxis() { - return new MemberAxis(); - } - - private class MemberAxis extends JComponent { - public MemberAxis() { - setPreferredSize(new Dimension(getWidth(), AXIS_SIZE)); - SequenceDiagram.this.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - int newWidth = e.getComponent().getWidth(); - setPreferredSize(new Dimension(newWidth, AXIS_SIZE)); - revalidate(); - } - }); - } - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - Rectangle bounds = g.getClipBounds(); - int index = 0; - for(String name : shortLineNames.keySet()) { - int nameWidth = g.getFontMetrics().stringWidth(name); - int lineX = lineStep * index; - index++; - if(bounds.getMaxX() < lineX - || bounds.getMinX() > lineX + nameWidth) { - continue; - } - g.setClip(lineX + LINE_LABEL_BOUNDARY, 0, lineStep - + LINE_LABEL_BOUNDARY * 2, getHeight()); - g.drawString(name, lineX + LINE_LABEL_BOUNDARY, AXIS_SIZE / 3); - g.setClip(null); - } - } - } - - public static class SubDiagram { - private final Map<String, Lifeline> lifelines; - private final List<Arrow> arrows; - private final Comparable name; - - public SubDiagram(Comparable name, Map<String, Lifeline> lines, List<Arrow> arrows) { - this.name = name; - this.lifelines = lines; - this.arrows = arrows; - } - - public void paintStates(Graphics2D g2, StateColorMap colorMap) { - for(Lifeline line: lifelines.values()) { - line.paint(g2, colorMap); - } - } - public void paintArrows(Graphics2D g2, StateColorMap colorMap) { - Color lineColor = colorMap.getColor(name); - g2.setColor(lineColor); - for(Arrow arrow: arrows) { - arrow.paint(g2); - } - } - } -}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/SequencePanel.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/SequencePanel.java b/geode-core/src/test/java/org/apache/sequence/SequencePanel.java deleted file mode 100644 index 05a13e3..0000000 --- a/geode-core/src/test/java/org/apache/sequence/SequencePanel.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; - -/** - * Created by IntelliJ IDEA. - * User: dan - * Date: Oct 28, 2010 - * Time: 10:29:23 PM - * To change this template use File | Settings | File Templates. - */ -public class SequencePanel extends JPanel { - - public SequencePanel(SequenceDiagram sequenceDiagram) { - //Set up the drawing area. - ZoomingPanel drawingPane = new ZoomingPanel(); - drawingPane.setBackground(Color.white); - drawingPane.setSequenceDiagram(sequenceDiagram); - - //Put the drawing area in a scroll pane. - final JScrollPane scroller = new JScrollPane(drawingPane); - scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); - final TimeAxis timeAxis = new TimeAxis(TimeAxis.VERTICAL, - sequenceDiagram.getMinTime(), - sequenceDiagram.getMaxTime()); - timeAxis.setPreferredHeight(drawingPane.getHeight()); - scroller.setRowHeaderView(timeAxis); - scroller.setColumnHeaderView(sequenceDiagram.createMemberAxis()); - int preferredWidth = (int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() - 100); - int preferredHeight = (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() - 100); - scroller.setPreferredSize(new Dimension(preferredWidth, preferredHeight)); - scroller.setAutoscrolls(true); -// scroller.setPreferredSize(new Dimension(200,200)); - - sequenceDiagram.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - int height = e.getComponent().getHeight(); - timeAxis.setPreferredHeight(height); - timeAxis.revalidate(); - } - }); - - BorderLayout layout = new BorderLayout(); -// layout.setHgap(0); -// layout.setVgap(0); - setLayout(layout); - //Lay out this demo. -// add(instructionPanel, BorderLayout.PAGE_START); - add(scroller, BorderLayout.CENTER); - - addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - Component source =e.getComponent(); - scroller.setSize(source.getSize()); - scroller.revalidate(); - } - }); - - - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/StateColorMap.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/StateColorMap.java b/geode-core/src/test/java/org/apache/sequence/StateColorMap.java deleted file mode 100644 index 8248f27..0000000 --- a/geode-core/src/test/java/org/apache/sequence/StateColorMap.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence; - -import java.awt.*; -import java.util.HashMap; -import java.util.Map; - -import static java.lang.Math.random; - -/** - * Created by IntelliJ IDEA. - * User: dsmith - * Date: Nov 12, 2010 - * Time: 5:05:49 PM - * To change this template use File | Settings | File Templates. - */ -public class StateColorMap { - private Map<Object, Color> colors = new HashMap<Object, Color>(); - private static Color[] PREDEFINED_COLORS = new Color[] { Color.BLUE, Color.BLACK, Color.PINK, Color.CYAN, Color.ORANGE, Color.GREEN}; - - private ColorList colorList = new ColorList(); - - public StateColorMap() { - colors.put("created", Color.GREEN); - colors.put("destroyed", Color.WHITE); - colors.put("persisted", new Color(0, 150, 0)); - } - - - public Color getColor(Object state) { - Color color = colors.get(state); - if(color == null) { - color = colorList.nextColor(); - colors.put(state, color); - } - - return color; - } - - private static class ColorList { - int colorIndex; - - public Color nextColor() { - if(colorIndex < PREDEFINED_COLORS.length) { - return PREDEFINED_COLORS[colorIndex++]; - } else { - return Color.getHSBColor((float)random(), (float)random(), (float)random()); - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/TimeAxis.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/TimeAxis.java b/geode-core/src/test/java/org/apache/sequence/TimeAxis.java deleted file mode 100644 index c0a1fac..0000000 --- a/geode-core/src/test/java/org/apache/sequence/TimeAxis.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence; - -import javax.swing.*; -import java.awt.*; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * Created by IntelliJ IDEA. - * User: dsmith - * Date: Oct 29, 2010 - * Time: 5:24:54 PM - * To change this template use File | Settings | File Templates. - */ -public class TimeAxis extends JComponent { - public static final int HORIZONTAL = 0; - public static final int VERTICAL = 1; - public static final int SIZE = 100; - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS"); - - public int orientation; - private long minTime; - private long maxTime; - - public TimeAxis(int orientation, long minTime, long maxTime) { - this.orientation = orientation; - this.minTime = minTime; - this.maxTime = maxTime; - } - - public void setPreferredHeight(int ph) { - setPreferredSize(new Dimension(SIZE, ph)); - } - - public void setPreferredWidth(int pw) { - setPreferredSize(new Dimension(pw, SIZE)); - } - - protected void paintComponent(Graphics g) { - Rectangle drawHere = g.getClipBounds(); - - int height = getHeight(); - - double scale = (maxTime - minTime) / height; - int increment = 30; - // Fill clipping area with dirty brown/orange. - g.setColor(new Color(230, 163, 4)); - g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height); - - // Do the ruler labels in a small font that's black. - g.setFont(new Font("SansSerif", Font.PLAIN, 10)); - g.setColor(Color.black); - - // Some vars we need. - int end = 0; - int start = 0; - int tickLength = 0; - String text = null; - - // Use clipping bounds to calculate first and last tick locations. - if (orientation == HORIZONTAL) { - start = (drawHere.x / increment) * increment; - end = (((drawHere.x + drawHere.width) / increment) + 1) - * increment; - } else { - start = (drawHere.y / increment) * increment; - end = (((drawHere.y + drawHere.height) / increment) + 1) - * increment; - } - - // Make a special case of 0 to display the number - // within the rule and draw a units label. - if (start == 0) { - text = DATE_FORMAT.format(new Date(minTime)); - tickLength = 10; - if (orientation == HORIZONTAL) { - g.drawLine(0, SIZE-1, 0, SIZE-tickLength-1); - g.drawString(text, 2, 21); - } else { - g.drawLine(SIZE-1, 0, SIZE-tickLength-1, 0); - g.drawString(text, 9, 10); - } - text = null; - start = increment; - } - - // ticks and labels - for (int i = start; i < end; i += increment) { - tickLength = 10; - text = DATE_FORMAT.format(new Date((long) (minTime + i * scale))); - - if (tickLength != 0) { - if (orientation == HORIZONTAL) { - g.drawLine(i, SIZE-1, i, SIZE-tickLength-1); - if (text != null) - g.drawString(text, i-3, 21); - } else { - g.drawLine(SIZE-1, i, SIZE-tickLength-1, i); - if (text != null) - g.drawString(text, 9, i+3); - } - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/ZoomingPanel.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/ZoomingPanel.java b/geode-core/src/test/java/org/apache/sequence/ZoomingPanel.java deleted file mode 100644 index 782ee7b..0000000 --- a/geode-core/src/test/java/org/apache/sequence/ZoomingPanel.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseMotionAdapter; - -/** - * Created by IntelliJ IDEA. - * User: dan - * Date: Oct 28, 2010 - * Time: 10:30:40 PM - * To change this template use File | Settings | File Templates. - */ -public class ZoomingPanel extends JPanel { - private int zoomBoxStartX; - private int zoomBoxStartY; - private int zoomBoxWidth; - private int zoomBoxHeight; - private SequenceDiagram child; - - - public ZoomingPanel() { - super(); - addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - startBox(e.getX(), e.getY()); - } - - @Override - public void mouseReleased(MouseEvent e) { - endBox(e.getX(), e.getY()); - } - - @Override - public void mouseClicked(MouseEvent e) { - if (e.getButton() != MouseEvent.BUTTON1) { - unzoom(); - } else { - child.selectState(e.getX(), e.getY()); - } - - } - }); - - addMouseMotionListener(new MouseMotionAdapter() { - @Override - public void mouseDragged(MouseEvent e) { - Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1); - ((JPanel)e.getSource()).scrollRectToVisible(r); - showBox(e.getX(), e.getY()); - } - - @Override - public void mouseMoved(MouseEvent e) { - int popupX = ZoomingPanel.this.getLocationOnScreen().x + e.getX(); - int popupY = ZoomingPanel.this.getLocationOnScreen().y + e.getY(); - child.showPopupText(e.getX(), e.getY(), popupX, popupY); - } - }); - BorderLayout layout = new BorderLayout(); - layout.setHgap(0); - layout.setVgap(0); - this.setLayout(layout); - } - - private void unzoom() { - resizeMe(0, 0, getWidth(), getHeight()); - } - - void resizeMe(int zoomBoxX, int zoomBoxY, int zoomBoxWidth, int zoomBoxHeight) { - Dimension viewSize = getParent().getSize(); - double windowWidth = viewSize.getWidth(); - double windowHeight = viewSize.getHeight(); - double scaleX = getWidth() / ((double) zoomBoxWidth); - double scaleY = getHeight() / ((double) zoomBoxHeight); - int oldWidth = getWidth(); - int oldHeight = getHeight(); - int width = (int) (scaleX * windowWidth); - int height = (int) (scaleY * windowHeight); -// this.setPreferredSize(new Dimension(width, height)); - child.resizeMe(width, height); - //TODO not sure this one is needed - this.revalidate(); - - //scroll to the new rectangle -// int scrollX = (int) (zoomBoxX * scaleX); -// int scrollY = (int) (zoomBoxY * scaleY); -// int scrollWidth= (int) (zoomBoxWidth * scaleX); -// int scrollHeight = (int) (zoomBoxHeight * scaleY); - int scrollX = (int) (zoomBoxX * (width / (double) oldWidth)); - int scrollY = (int) (zoomBoxY * (height / (double) oldHeight)); - int scrollWidth= (int) (zoomBoxWidth * (width / (double) oldWidth)); - int scrollHeight = (int) (zoomBoxHeight * (height / (double) oldHeight)); - Rectangle r = new Rectangle(scrollX, scrollY, scrollWidth, scrollHeight); - ((JViewport)getParent()).scrollRectToVisible(r); - repaint(); - - } - - public void setSequenceDiagram(SequenceDiagram diag) { - this.child = diag; - this.add(child, BorderLayout.CENTER); - } - - private void showBox(int x, int y) { - if(zoomBoxWidth != -1) { - repaint(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight()); - } - - this.zoomBoxWidth = x - zoomBoxStartX; - this.zoomBoxHeight = y - zoomBoxStartY; - - repaint(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight()); - } - - private void startBox(int x, int y) { - this.zoomBoxStartX = x; - this.zoomBoxStartY = y; - } - - private void endBox(int x, int y) { - if(zoomBoxStartX != -1 && zoomBoxStartY != -1 - && zoomBoxWidth != -1 && zoomBoxHeight != -1 - && zoomBoxWidth != 0 && zoomBoxHeight != 0) { - resizeMe(getBoxX() , getBoxY(), getBoxWidth(), getBoxHeight()); - repaint(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight()); - this.zoomBoxStartX = -1; - this.zoomBoxStartY = -1; - this.zoomBoxWidth = -1; - this.zoomBoxHeight = -1; - } - } - - public int getBoxX() { - return zoomBoxWidth >= 0 ? zoomBoxStartX : zoomBoxStartX + zoomBoxWidth; - } - - public int getBoxY() { - return zoomBoxHeight >= 0 ? zoomBoxStartY : zoomBoxStartY + zoomBoxHeight; - } - - public int getBoxHeight() { - return zoomBoxHeight >= 0 ? zoomBoxHeight : -zoomBoxHeight; - } - - public int getBoxWidth() { - return zoomBoxWidth >= 0 ? zoomBoxWidth : -zoomBoxWidth; - } - - - - @Override - public void paint(Graphics g) { - super.paint(g); - - if(zoomBoxStartX != -1 && zoomBoxStartY != -1 && zoomBoxWidth != -1 && zoomBoxHeight != -1) { - Graphics2D g2 = (Graphics2D) g.create(); - - Composite old = g2.getComposite(); - g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); - g2.setColor(Color.BLUE); - -// g2.drawRect(zoomBoxStartX, zoomBoxStartY, zoomBoxWidth, zoomBoxHeight); -// g2.setBackground(Color.BLUE); - g2.fillRect(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight()); - g2.setComposite(old); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/gemfire/DefaultLineMapper.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/gemfire/DefaultLineMapper.java b/geode-core/src/test/java/org/apache/sequence/gemfire/DefaultLineMapper.java deleted file mode 100644 index 5f8268e..0000000 --- a/geode-core/src/test/java/org/apache/sequence/gemfire/DefaultLineMapper.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence.gemfire; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.sequence.LineMapper; - -/** - * A lifeline mapper that just returns a shortened version of - * a member id. - * - */ -public class DefaultLineMapper implements LineMapper { - private static Pattern MEMBER_ID_RE = Pattern.compile(".*\\((\\d+)(:admin)?(:loner)?\\).*:\\d+(/\\d+|.*:.*)"); - - public String getShortNameForLine(String name) { - Matcher matcher = MEMBER_ID_RE.matcher(name); - if(matcher.matches()) { - return matcher.group(1); - } else { - return name; - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/gemfire/GemfireSequenceDisplay.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/gemfire/GemfireSequenceDisplay.java b/geode-core/src/test/java/org/apache/sequence/gemfire/GemfireSequenceDisplay.java deleted file mode 100644 index 062ba7e..0000000 --- a/geode-core/src/test/java/org/apache/sequence/gemfire/GemfireSequenceDisplay.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence.gemfire; - -import org.apache.geode.internal.sequencelog.GraphType; -import org.apache.geode.internal.sequencelog.io.Filter; -import org.apache.geode.internal.sequencelog.io.GraphReader; -import org.apache.geode.internal.sequencelog.model.*; -import org.apache.sequence.*; - -import javax.swing.*; -import java.awt.event.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.*; -import java.util.regex.Pattern; - -/** - */ -public class GemfireSequenceDisplay { - - private JLabel selectedGraphsLabel; - private SelectGraphDialog selectGraphDialog; - - private Map<GraphID, Map<String, Lifeline>> lineMap = new HashMap(); - private Map<GraphID, List<Arrow>> arrowMap = new HashMap(); - private SequenceDiagram sequenceDiagram; - private JFrame frame; - private SequencePanel sequencePanel; - - /** - * Create the GUI and show it. For thread safety, - * this method should be invoked from the - * event-dispatching thread. - * - * @param graphs - * @param lineMapper - */ - private void createAndShowGUI(final GraphSet graphs, LineMapper lineMapper) { - //Create and set up the window. - - frame = new JFrame("SequenceDiagram"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - createMenu(); - createSequenceDiagram(graphs, lineMapper); - createSequenceMaps(graphs); - - createSelectGraphDialog(graphs); - - // for (GraphID id : graphs.getMap().keySet()) { - // showSubDiagram(id); - // - // } - - sequencePanel = new SequencePanel(sequenceDiagram); - frame.getContentPane().add(sequencePanel); - //Display the window. - frame.pack(); - frame.setVisible(true); - showGraphSelector(); - } - - private void createMenu() { - JMenuBar menuBar = new JMenuBar(); - - JMenu sequenceMenu = new JMenu("Sequence"); - sequenceMenu.setMnemonic(KeyEvent.VK_S); - sequenceMenu.getAccessibleContext().setAccessibleDescription( - "The only menu in this program that has menu items"); - menuBar.add(sequenceMenu); - JMenuItem selectGraphs = new JMenuItem("Choose Graphs", - KeyEvent.VK_G); - selectGraphs.setAccelerator(KeyStroke.getKeyStroke( - KeyEvent.VK_G, ActionEvent.ALT_MASK)); - selectGraphs.getAccessibleContext().setAccessibleDescription( - "Select what graphs to display"); - selectGraphs.setActionCommand("selectgraphs"); - selectGraphs.addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - showGraphSelector(); - } - }); - - sequenceMenu.add(selectGraphs); - frame.setJMenuBar(menuBar); - } - - private void createSelectGraphDialog(final GraphSet graphs) { - selectGraphDialog = new SelectGraphDialog(graphs); - selectGraphDialog.addSelectionListener(new SelectGraphDialog.SelectionListener() { - - public void selectionChanged(List<GraphID> selectedIds) { - updateGraphs(selectedIds); - } - }); - selectGraphDialog.pack(); - } - - private void updateGraphs(List<GraphID> selectedIds) { - List<GraphID> existingDiagrams =(List) sequenceDiagram.getSubDiagramsNames(); - for(GraphID id : selectedIds) { - showSubDiagram(id); - existingDiagrams.remove(id); - } - for(GraphID id : existingDiagrams) { - hideSubDiagram(id); - } - - sequenceDiagram.resizeMe(sequenceDiagram.getWidth(), sequenceDiagram.getHeight()); - sequencePanel.revalidate(); - sequencePanel.repaint(); - // sequenceDiagram.revalidate(); - // sequenceDiagram.repaint(); - } - - private void showGraphSelector() { - selectGraphDialog.setVisible(true); - } - - private void hideGraphSelector() { - selectGraphDialog.setVisible(false); - } - - // private static SequenceDiagram createSequenceDiagram() { - // long startTime = System.currentTimeMillis(); - // List<Lifeline> lines = new ArrayList<Lifeline>(); - // List<Arrow> arrows = new ArrayList<Arrow>(); - // for(int i =0 ; i < 10; i++) { - // List<LifelineState> states = new ArrayList<LifelineState>(); - // for(int j =0; j < 5; j++) { - // LifelineState state = new LifelineState(startTime + 20* j, startTime + 20 * j + 20); - // states.add(state); - // } - // Lifeline line = new Lifeline(i, states); - // lines.add(line); - // - // if(i > 0) { - // Arrow arrow = new Arrow("arrow" + i, line, lines.get(i - 1), line.getStates().get(2)); - // arrows.add(arrow); - // } - // } - // - // SequenceDiagram diag = new SequenceDiagram(startTime, startTime + 20 * 5, lines, arrows); - // return diag; - // } - - private void createSequenceMaps(GraphSet graphs) { - - Map<GraphID, Graph> map = graphs.getMap(); - for (Map.Entry<GraphID, Graph> entry : map.entrySet()) { - GraphID graphId = entry.getKey(); - Graph graph = entry.getValue(); - Map<String, Lifeline> lines = new LinkedHashMap<String, Lifeline>(graphs.getLocations().size()); - List<Arrow> arrows = new ArrayList<Arrow>(); - Map<Vertex, LifelineState> states = new HashMap<Vertex, LifelineState>(); - for (String location : graphs.getLocations()) { - lines.put(location, new Lifeline(graphId, location)); - } - - Collection<Edge> edges = graph.getEdges(); - for (Edge edge : edges) { - Vertex dest = edge.getDest(); - Vertex source = edge.getSource(); - if (dest == null) { - dest = source; - } - if (source == null) { - source = dest; - } - LifelineState destState = states.get(dest); - if (destState == null) { - final Lifeline lifeline = lines.get(dest.getName()); - destState = createState(lifeline, graphs, dest); - lifeline.addState(destState); - states.put(dest, destState); - } - LifelineState sourceState = states.get(source); - if (sourceState == null) { - final Lifeline lifeline = lines.get(source.getName()); - sourceState = createState(lifeline, graphs, source); - lifeline.addState(sourceState); - states.put(source, sourceState); - } - Arrow arrow = new Arrow(edge.getName(), sourceState, destState); - arrows.add(arrow); - destState.addInboundArrow(arrow); - } - - - lineMap.put(graphId, lines); - arrowMap.put(graphId, arrows); - } - } - - public void showSubDiagram(GraphID id) { - sequenceDiagram.addSubDiagram(id, lineMap.get(id), arrowMap.get(id)); - } - - public void hideSubDiagram(GraphID id) { - sequenceDiagram.removeSubDiagram(id); - } - - private SequenceDiagram createSequenceDiagram(GraphSet graphs, LineMapper lineMapper) { - - sequenceDiagram = new SequenceDiagram(graphs.getMinTime(), graphs.getMaxTime(), graphs.getLocations(), lineMapper); - return sequenceDiagram; - } - - private static LifelineState createState(Lifeline lifeline, GraphSet graphs, Vertex dest) { - long start = dest.getTimestamp(); - long end = dest.getNextVertexOnDest() == null ? graphs.getMaxTime() : dest.getNextVertexOnDest().getTimestamp(); - return new LifelineState(lifeline, dest.getState(), start, end); - } - - public static void main(String[] args) throws IOException { - File[] files; - Set<String> keyFilters = new HashSet<String>(); - boolean areGemfireLogs = false; - if (args.length > 0) { - ArrayList<File> fileList = new ArrayList<File>(); - for (int i =0; i < args.length; i++) { - String arg = args[i]; - if(arg.equals("-filterkey")) { - keyFilters.add(args[i+1]); - i++; - } else if(arg.equals("-logs")) { - areGemfireLogs = true; - } - else { - fileList.add(new File(args[i])); - } - - } - files = fileList.toArray(new File[0]); - } else { - System.err.println("Usage: java -jar sequence.jar (-logs) (-filterkey key)* <file>+\n\n" + - "\t-logs (expiremental) instead of using .graph files, parse the gemfire logs to generate the sequence display" + - "\t-filterkey a java regular expression to match against key names. If specified\n" + - "The list of key sequence diagrams will only contain matching keys"); - System.exit(1); - return; - } - - final GraphSet graphs; - - graphs = getGraphs(areGemfireLogs, keyFilters, files); - - final LineMapper lineMapper = getLineMapper(files); - final GemfireSequenceDisplay display = new GemfireSequenceDisplay(); - //Schedule a job for the event-dispatching thread: - //creating and showing this application's GUI. - javax.swing.SwingUtilities.invokeLater(new Runnable() { - public void run() { - display.createAndShowGUI(graphs, lineMapper); - } - }); - } - - private static GraphSet getGraphs(boolean useLogFiles, Set<String> keyFilters, File[] files) - throws IOException { - Filter graphFilter = new KeyFilter(keyFilters); - - - GraphReader reader = new GraphReader(files); - final GraphSet graphs; - if(keyFilters.isEmpty()) { - graphs = reader.readGraphs(useLogFiles); - } else { - graphs = reader.readGraphs(graphFilter, useLogFiles); - } - return graphs; - } - - /** - * @param files - * @return - */ - private static LineMapper getLineMapper(File[] files) { - if(HydraLineMapper.isInHydraRun(files)) { - return new HydraLineMapper(files); - } else { - return new DefaultLineMapper(); - } - } - - private static class KeyFilter implements Filter { - Set<Pattern> patterns = new HashSet<Pattern>(); - - - public KeyFilter(Set<String> keyFilters) { - for(String filterString : keyFilters) { - patterns.add(Pattern.compile(filterString)); - } - } - - public boolean accept(GraphType graphType, String name, String edgeName, - String source, String dest) { - if(graphType.equals(GraphType.KEY)) { - for(Pattern pattern : patterns) { - if(pattern.matcher(name).find()) { - return true; - } - } - - return false; - } else { - return true; - } - } - - public boolean acceptPattern(GraphType graphType, Pattern pattern, - String edgeName, String source, String dest) { - return true; - } - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/gemfire/HydraLineMapper.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/gemfire/HydraLineMapper.java b/geode-core/src/test/java/org/apache/sequence/gemfire/HydraLineMapper.java deleted file mode 100644 index ccb05d7..0000000 --- a/geode-core/src/test/java/org/apache/sequence/gemfire/HydraLineMapper.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence.gemfire; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.sequence.LineMapper; - -/** - * - */ -public class HydraLineMapper implements LineMapper { - private static final Pattern VM_NAME_PATTERN = Pattern.compile("(vm_\\d+).*_(\\d+)(_end)?\\.log"); - private static final Pattern DISK_DIR_PATTERN = Pattern.compile("vm_(\\d+).*_disk_1"); - private final Map<String, String> processIdToVMName = new HashMap<String, String>(); - private final DefaultLineMapper defaultMapper = new DefaultLineMapper(); - - public HydraLineMapper(File[] graphFiles) { - File firstFile = graphFiles[0]; - File directory = firstFile.getParentFile(); - if(directory == null || ! new File(directory, "latest.prop").exists()) { - directory = new File("."); - } - String[] files = directory.list(); - for(String file : files) { - Matcher matcher = VM_NAME_PATTERN.matcher(file); - if(matcher.matches()) { - processIdToVMName.put(matcher.group(2), matcher.group(1)); - } - } - - for(String file : files) { - Matcher matcher = DISK_DIR_PATTERN.matcher(file); - if(matcher.matches()) { - - String storeId = getDiskStoreId(file); - if(storeId != null) { - processIdToVMName.put(storeId, "disk_" + matcher.group(1)); - } - } - } - - - } - - private String getDiskStoreId(String diskStoreDir) { - File dir = new File(diskStoreDir); - String[] files = dir.list(); - for(String fileName : files) { - if(fileName.endsWith(".if")) { - try { - return getDiskStoreIdFromInitFile(dir, fileName); - } catch (Exception e) { - return null; - } - } - } - - return null; - } - - private String getDiskStoreIdFromInitFile(File dir, String fileName) - throws FileNotFoundException, IOException { - FileInputStream fis = new FileInputStream(new File(dir, fileName)); - try { - byte[] bytes = new byte[1 + 8 + 8]; - fis.read(bytes); - ByteBuffer buffer = ByteBuffer.wrap(bytes); - //Skip the record type. - buffer.get(); - long least = buffer.getLong(); - long most = buffer.getLong(); - UUID id = new UUID(most, least); - return id.toString(); - } finally { - fis.close(); - } - } - - public String getShortNameForLine(String lineName) { - String name = defaultMapper.getShortNameForLine(lineName); - if(processIdToVMName.containsKey(name)) { - return processIdToVMName.get(name); - } else { - return name; - } - } - - public static boolean isInHydraRun(File[] graphFiles) { - if(graphFiles.length == 0) { - return false; - } - File firstFile = graphFiles[0]; - File parentFile = firstFile.getParentFile(); - for(File file : graphFiles) { - if(parentFile == null && file.getParentFile() == null) { - return true; - } - if (parentFile == null || file.getParentFile() == null - || !file.getParentFile().equals(parentFile)) { - return false; - } - } - - return new File(parentFile, "latest.prop").exists() - || new File("latest.prop").exists(); - - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/gemfire/SelectGraphDialog.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/sequence/gemfire/SelectGraphDialog.java b/geode-core/src/test/java/org/apache/sequence/gemfire/SelectGraphDialog.java deleted file mode 100644 index 7863008..0000000 --- a/geode-core/src/test/java/org/apache/sequence/gemfire/SelectGraphDialog.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sequence.gemfire; - -import org.apache.geode.internal.sequencelog.model.GraphID; -import org.apache.geode.internal.sequencelog.model.GraphSet; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.*; -import java.util.List; -import java.util.regex.Pattern; - -/** - * Created by IntelliJ IDEA. - * User: dsmith - * Date: Dec 9, 2010 - * Time: 3:34:38 PM - * To change this template use File | Settings | File Templates. - */ -public class SelectGraphDialog extends JDialog { - private List<GraphID> selectedIds = new ArrayList<GraphID>(); - private Set<SelectionListener> listeners = new HashSet<SelectionListener>(); - - public SelectGraphDialog(final GraphSet graphs) { - - final List<GraphID> ids = new ArrayList<GraphID>(graphs.getMap().keySet()); - Collections.sort(ids); - final FilterableListModel listModel = new FilterableListModel(ids); - final JList list = new JList(listModel); - - JScrollPane selectGraphPane = new JScrollPane(list); - selectGraphPane.setPreferredSize(new Dimension(500, 500)); - - JButton apply = new JButton("Apply"); - apply.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - selectedIds = (List) Arrays.asList(list.getSelectedValues()); - fireSelectionChanged(); - setVisible(false); - } - }); - - JButton cancel= new JButton("Cancel"); - cancel.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - setVisible(false); - } - }); - - JPanel buttonPane = new JPanel(); - buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); - buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); - buttonPane.add(Box.createHorizontalGlue()); - buttonPane.add(apply); - buttonPane.add(cancel); - - final JTextField searchField = new JTextField(10); - searchField.getDocument().addDocumentListener(new DocumentListener() { - public void removeUpdate(DocumentEvent e) { - doUpdate(); - } - - public void insertUpdate(DocumentEvent e) { - doUpdate(); - } - - public void changedUpdate(DocumentEvent e) { - doUpdate(); - } - - private void doUpdate() { - listModel.updateFilter(searchField.getText()); - } - }); - - - Container contentPane = getContentPane(); - contentPane.add(searchField, BorderLayout.PAGE_START); - contentPane.add(selectGraphPane, BorderLayout.CENTER); - contentPane.add(buttonPane, BorderLayout.PAGE_END); - } - - private void fireSelectionChanged() { - for(SelectionListener listener : listeners) { - listener.selectionChanged(selectedIds); - } - } - - public void addSelectionListener(SelectionListener listener) { - listeners.add(listener); - - } - - public void removeSelectionListener(SelectionListener listener) { - listeners.remove(listener); - } - - /** - * A listener for changes to the graph selections - */ - public static interface SelectionListener { - void selectionChanged(List<GraphID> selectedIds); - } - - private static class FilterableListModel extends AbstractListModel { - private final List<?> allElements; - private List<Object> filteredElements; - - public FilterableListModel(List<?> elements) { - this.allElements = elements; - this.filteredElements = new ArrayList<Object>(elements); - } - - public int getSize() { - return filteredElements.size(); - } - - public Object getElementAt(int index) { - return filteredElements.get(index); - } - - public void updateFilter(String filter) { - Pattern pattern = Pattern.compile(filter); - filteredElements = new ArrayList<Object>(); - for(Object element : allElements) { - if(pattern.matcher(element.toString()).find()) { - filteredElements.add(element); - } - } - - fireContentsChanged(this, 0, filteredElements.size()); - } - - } -}
