Index: core/output2/nbproject/project.xml =================================================================== RCS file: /cvs/core/output2/nbproject/project.xml,v retrieving revision 1.9 diff -u -r1.9 project.xml --- core/output2/nbproject/project.xml 19 Jul 2006 06:53:54 -0000 1.9 +++ core/output2/nbproject/project.xml 14 Aug 2006 19:42:15 -0000 @@ -22,6 +22,23 @@ org.netbeans.core.output2 + + + unit + + org.netbeans.core.output2 + + + + + org.openide.nodes + + + + + qa-functional + + org.openide.actions @@ -44,7 +61,7 @@ - 1.11 + @@ -72,23 +89,6 @@ - - - unit - - org.netbeans.core.output2 - - - - - org.openide.nodes - - - - - qa-functional - - Index: core/output2/src/org/netbeans/core/output2/AbstractLines.java =================================================================== RCS file: /cvs/core/output2/src/org/netbeans/core/output2/AbstractLines.java,v retrieving revision 1.17 diff -u -r1.17 AbstractLines.java --- core/output2/src/org/netbeans/core/output2/AbstractLines.java 1 Jul 2006 08:51:57 -0000 1.17 +++ core/output2/src/org/netbeans/core/output2/AbstractLines.java 14 Aug 2006 19:42:16 -0000 @@ -31,14 +31,17 @@ import java.util.regex.Pattern; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import org.netbeans.modules.openide.io.OutputScrollHandler; +import org.netbeans.modules.openide.io.ScrollerAccessor; import org.openide.util.Exceptions; import org.openide.util.Mutex; import org.openide.windows.OutputListener; +import org.openide.windows.OutputScroller; /** * Abstract Lines implementation with handling for getLine wrap calculations, etc. */ -abstract class AbstractLines implements Lines, Runnable { +abstract class AbstractLines implements Lines, Runnable, OutputScrollHandler { /** A collections-like lineStartList that maps file positions to getLine numbers */ IntList lineStartList; /** Maps output listeners to the lines they are associated with */ @@ -513,6 +516,9 @@ if (important) { importantLines.add(line); } + if (l instanceof OutputScroller) { + ScrollerAccessor.assignHandler((OutputScroller) l, this); + } } } @@ -859,5 +865,20 @@ public String toString() { return lineStartList.toString(); + } + + public void requestScroll(OutputScroller scroller) { + //Safe cast - we are not handling anything else + OutputListener l = (OutputListener) scroller; + int[] lns = this.linesToListeners.getKeys(); + for (int i = 0; i < lns.length; i++) { + OutputListener check = (OutputListener) linesToListeners.get(lns[i]); + if (check == l) { + getIO().post(new IOEvent(getIO(), IOEvent.CMD_SCROLL, + new Integer(lns[i]))); + return; + } + } + throw new IllegalArgumentException ("No known line for " + scroller); } } Index: core/output2/src/org/netbeans/core/output2/Controller.java =================================================================== RCS file: /cvs/core/output2/src/org/netbeans/core/output2/Controller.java,v retrieving revision 1.47 diff -u -r1.47 Controller.java --- core/output2/src/org/netbeans/core/output2/Controller.java 1 Jul 2006 08:51:57 -0000 1.47 +++ core/output2/src/org/netbeans/core/output2/Controller.java 14 Aug 2006 19:42:18 -0000 @@ -1044,6 +1044,10 @@ OutWriter out = io.out(); switch (command) { + case IOEvent.CMD_SCROLL : + int line = ((Integer) data).intValue(); + scrollTo (win, tab, line); + break; case IOEvent.CMD_CREATE : createOutputTab(win, io, io.isFocusTaken(), value); break; @@ -1410,6 +1414,11 @@ if (in != null) { in.eof(); } + } + + private void scrollTo(OutputWindow win, OutputTab tab, int line) { + win.setSelectedTab(tab); + tab.scrollTo (line); } } Index: core/output2/src/org/netbeans/core/output2/IOEvent.java =================================================================== RCS file: /cvs/core/output2/src/org/netbeans/core/output2/IOEvent.java,v retrieving revision 1.6 diff -u -r1.6 IOEvent.java --- core/output2/src/org/netbeans/core/output2/IOEvent.java 1 Jul 2006 08:51:58 -0000 1.6 +++ core/output2/src/org/netbeans/core/output2/IOEvent.java 14 Aug 2006 19:42:18 -0000 @@ -108,6 +108,12 @@ static final int CMD_DETACH = 11; /** + * Used by OutputScroller callback to request that the output window scroll + * to a particular location. + */ + static final int CMD_SCROLL = 12; + + /** * Array of IDs for checking legal values and generating a string representing the event. */ private static final int[] IDS = new int[] { @@ -123,6 +129,7 @@ CMD_RESET, CMD_SET_TOOLBAR_ACTIONS, CMD_DETACH, + CMD_SCROLL, }; /** @@ -140,7 +147,8 @@ "STREAM_CLOSED", //NOI18N "RESET", //NOI18N "SET_TOOLBAR_ACTIONS", //NOI18N - "DETACH" //NOI18N + "DETACH", //NOI18N + "SCROLL", //NOI18N }; /** Index: core/output2/src/org/netbeans/core/output2/Lines.java =================================================================== RCS file: /cvs/core/output2/src/org/netbeans/core/output2/Lines.java,v retrieving revision 1.4 diff -u -r1.4 Lines.java --- core/output2/src/org/netbeans/core/output2/Lines.java 1 Jul 2006 08:51:58 -0000 1.4 +++ core/output2/src/org/netbeans/core/output2/Lines.java 14 Aug 2006 19:42:18 -0000 @@ -290,4 +290,6 @@ * @return True if there is still an open stream which may write to the backing storage and no error has occured */ boolean isGrowing(); + + NbIO getIO(); } Index: core/output2/src/org/netbeans/core/output2/OutWriter.java =================================================================== RCS file: /cvs/core/output2/src/org/netbeans/core/output2/OutWriter.java,v retrieving revision 1.33 diff -u -r1.33 OutWriter.java --- core/output2/src/org/netbeans/core/output2/OutWriter.java 1 Jul 2006 08:51:58 -0000 1.33 +++ core/output2/src/org/netbeans/core/output2/OutWriter.java 14 Aug 2006 19:42:19 -0000 @@ -569,5 +569,9 @@ protected void handleException (Exception e) { OutWriter.this.handleException(e); } + + public NbIO getIO() { + return OutWriter.this.owner; + } } } Index: core/output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java =================================================================== RCS file: /cvs/core/output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java,v retrieving revision 1.10 diff -u -r1.10 AbstractOutputTab.java --- core/output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java 1 Jul 2006 08:52:00 -0000 1.10 +++ core/output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java 14 Aug 2006 19:42:19 -0000 @@ -286,5 +286,8 @@ getOutputPane().lockScroll(); getOutputPane().ensureCaretPosition(); } - + + public void scrollTo (int line) { + getOutputPane().sendCaretToLine(line, true); + } } Index: core/output2/test/unit/src/org/netbeans/core/output2/ScrollerTest.java =================================================================== RCS file: core/output2/test/unit/src/org/netbeans/core/output2/ScrollerTest.java diff -N core/output2/test/unit/src/org/netbeans/core/output2/ScrollerTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/output2/test/unit/src/org/netbeans/core/output2/ScrollerTest.java 14 Aug 2006 19:42:19 -0000 @@ -0,0 +1,106 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.core.output2; + +import java.awt.BorderLayout; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import junit.framework.TestCase; +import org.netbeans.core.output2.ui.AbstractOutputPane; +import org.netbeans.modules.openide.io.ScrollerAccessor; +import org.openide.windows.OutputEvent; +import org.openide.windows.OutputListener; +import org.openide.windows.OutputScroller; + +/** + * Test scrolling behavior when a scroll request is run. + * + * @author Tim Boudreau + */ +public class ScrollerTest extends TestCase { + + public ScrollerTest(String testName) { + super(testName); + } + + public void testScrollBehavior() throws Exception { + System.out.println("testScrollBehavior"); + Object o = OutputScroller.class; + assertNotNull (ScrollerAccessor.DEFAULT); + + OL ol = new OL(); + for (int i = 0; i < 200; i++) { + io.getOut().println("This line doesn't have a listener"); + if (i == 100) { + io.getOut().println ("This line does have a listener", ol, false); + } + } + Thread.currentThread().sleep (1000); + win.repaint(); + OutputTab tab = win.getTabForIO(io); + Thread.currentThread().sleep (1000); + AbstractOutputPane pane = tab.getOutputPane(); + int currLine = pane.getCaretLine(); + boolean val = ol.requestScroll(); + assertTrue (val); + Thread.currentThread().sleep(1000); + win.validate(); + win.repaint(); + Thread.currentThread().sleep(500); + int newCurrLine = pane.getCaretLine(); + assertFalse (currLine == newCurrLine); + assertEquals (101, newCurrLine); + Thread.currentThread().sleep(5000); + } + + private JFrame jf; + private OutputWindow win; + private NbIOProvider provider; + private NbIO io; + protected void setUp() throws Exception { + jf = new JFrame(); + win = new OutputWindow(); + OutputWindow.DEFAULT = win; + jf.getContentPane().setLayout (new BorderLayout()); + jf.getContentPane().add (win, BorderLayout.CENTER); + jf.setBounds (20, 20, 700, 300); + provider = new NbIOProvider(); + io = (NbIO) provider.getIO ("Test", false); + SwingUtilities.invokeAndWait (new Shower()); + Thread.currentThread().sleep(200); + } + + public class Shower implements Runnable { + public void run() { + jf.setVisible(true); + } + } + + private class OL extends OutputScroller implements OutputListener { + public void outputLineSelected(OutputEvent ev) { + } + + public void outputLineAction(OutputEvent ev) { + } + + public void outputLineCleared(OutputEvent ev) { + } + } +}