[prev in list] [next in list] [prev in thread] [next in thread]
List: apache-logging-general
Subject: svn commit: r595870 - in
From: sdeboy () apache ! org
Date: 2007-11-16 23:31:44
Message-ID: 20071116233144.ECAD21A9832 () eris ! apache ! org
[Download RAW message or body]
Author: sdeboy
Date: Fri Nov 16 15:31:40 2007
New Revision: 595870
URL: http://svn.apache.org/viewvc?rev=595870&view=rev
Log:
Scroll-to-bottom now works as expected:
- Click of the scroll to bottom button works for cyclic, filtered, etc
- Click on any row deselects scroll to bottom button and maintains selection as long \
as the row isn't filtered out or nuked from cyclic buffer
- Ensure that updates to the table model cause selection changes within the same call \
(table model update is on EDT, selection change is made while still \
in same call)
- Goto-line now scrolls to first column of row (was going to 2nd)
Much thanks to Jeff Kinzer for the help in getting selection working (and lots of \
testing!)
Modified:
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/JSortTable.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4 \
j/chainsaw/ChainsawCyclicBufferTableModel.java?rev=595870&r1=595869&r2=595870&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java \
(original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java \
Fri Nov 16 15:31:40 2007 @@ -28,6 +28,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.awt.EventQueue;
import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;
@@ -36,6 +37,7 @@
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
+import org.apache.log4j.chainsaw.helper.SwingHelper;
import org.apache.log4j.helpers.Constants;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.LoggingEvent;
@@ -135,7 +137,7 @@
}
}
} finally {
- SwingUtilities.invokeLater(new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
if (filteredList.size() > 0) {
if (previousSize == filteredList.size()) {
@@ -262,7 +264,7 @@
currentSortAscending));
}
- SwingUtilities.invokeLater(new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
fireTableRowsUpdated(0, Math.max(filteredList.size() - 1, 0));
}
@@ -295,7 +297,7 @@
uniqueRow = 0;
}
- SwingUtilities.invokeLater(new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
fireTableDataChanged();
}
@@ -445,7 +447,7 @@
return "";
}
- public boolean isAddRow(LoggingEvent e, boolean valueIsAdjusting) {
+ public boolean isAddRow(LoggingEvent e) {
boolean rowAdded = false;
Object id = e.getProperty(Constants.LOG4J_ID_KEY);
@@ -494,7 +496,7 @@
}
}
- if (!valueIsAdjusting) {
+ if (rowAdded) {
int lastAdded = getLastAdded();
fireTableEvent(lastAdded, lastAdded, 1);
}
@@ -506,16 +508,16 @@
int last = 0;
if (cyclic) {
- last = ((CyclicBufferList) filteredList).getLast();
+ last = ((CyclicBufferList) filteredList).getLast() - 1;
} else {
- last = filteredList.size();
+ last = filteredList.size() - 1;
}
- return last;
+ return Math.max(0, last);
}
public void fireTableEvent(final int begin, final int end, final int count) {
- SwingUtilities.invokeLater(new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
if (cyclic) {
if (!reachedCapacity) {
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java?rev=595870&r1=595869&r2=595870&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java \
(original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java \
Fri Nov 16 15:31:40 2007 @@ -17,13 +17,12 @@
package org.apache.log4j.chainsaw;
-import org.apache.log4j.rule.Rule;
-import org.apache.log4j.spi.LoggingEvent;
-
import java.beans.PropertyChangeListener;
-
import java.util.List;
+import org.apache.log4j.rule.Rule;
+import org.apache.log4j.spi.LoggingEvent;
+
/**
* To allow pluggable TableModel implementations for Chainsaw, this interface has \
been factored out. @@ -132,10 +131,9 @@
/**
* Adds a row to the model.
* @param e event
- * @param valueIsAdjusting
* @return flag representing whether or not the row is being displayed (not \
filtered)
*/
- boolean isAddRow(LoggingEvent e, boolean valueIsAdjusting);
+ boolean isAddRow(LoggingEvent e);
/**
* Fire appropriate table update events for the range.
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/JSortTable.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/JSortTable.java?rev=595870&r1=595869&r2=595870&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/JSortTable.java \
(original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/JSortTable.java \
Fri Nov 16 15:31:40 2007 @@ -23,10 +23,11 @@
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
-import javax.swing.SwingUtilities;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
+import org.apache.log4j.chainsaw.helper.SwingHelper;
+
/**
* A Sortable JTable implementation that allows a user to click on a
@@ -92,36 +93,23 @@
getTableHeader().resizeAndRepaint();
}
- public void scrollToRow(final int row, final int col) {
- SwingUtilities.invokeLater(
- new Runnable() {
- public void run() {
- if ((row > -1) && (row < getRowCount())) {
- try {
- setRowSelectionInterval(row, row);
- scrollRectToVisible(getCellRect(row, col +1, true));
- } catch (IllegalArgumentException iae) {
- }
- //ignore..out of bounds
- }
- }
- });
- }
-
- public void scrollToBottom(final int col) {
- SwingUtilities.invokeLater(
- new Runnable() {
- public void run() {
- int row = getRowCount() - 1;
-
+ public void scrollTo(final int row, final int col) {
+ SwingHelper.invokeOnEDT(new Runnable() {
+ public void run() {
+ if ((row > -1) && (row < getRowCount())) {
try {
setRowSelectionInterval(row, row);
- scrollRectToVisible(getCellRect(row, col + 1, true));
+ scrollRectToVisible(getCellRect(row, col, true));
} catch (IllegalArgumentException iae) {
+ //ignore..out of bounds
}
- //ignore..out of bounds
}
- });
+ }
+ });
+ }
+
+ public void scrollToRow(int row) {
+ scrollTo(row, columnAtPoint(getVisibleRect().getLocation()));
}
public boolean isSortedColumnAscending() {
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java?rev=595870&r1=595869&r2=595870&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java \
(original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java Fri \
Nov 16 15:31:40 2007 @@ -112,6 +112,9 @@
import javax.swing.table.TableColumnModel;
import javax.swing.text.Document;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
@@ -129,15 +132,13 @@
import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.chainsaw.xstream.TableColumnConverter;
+import org.apache.log4j.chainsaw.helper.SwingHelper;
import org.apache.log4j.helpers.Constants;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.LoggingEventFieldResolver;
-import com.thoughtworks.xstream.XStream;
-import com.thoughtworks.xstream.io.xml.DomDriver;
-
/**
* A LogPanel provides a view to a collection of LoggingEvents.<br>
@@ -533,7 +534,7 @@
boolean value = ((Boolean) evt.getNewValue()).booleanValue();
menuItemScrollBottom.setSelected(value);
if (value) {
- table.scrollToBottom(table.columnAtPoint(table.getVisibleRect().getLocation()));
+ scrollToBottom();
}
}
});
@@ -690,33 +691,42 @@
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent evt) {
+ if (((evt.getFirstIndex() == evt.getLastIndex())
+ && (evt.getFirstIndex() > 0)) || (evt.getValueIsAdjusting())) {
+ return;
+ }
+ boolean lastIndexOnLastRow = (evt.getLastIndex() == (table.getRowCount() \
- 1)); + boolean lastIndexSame = (previousLastIndex == \
evt.getLastIndex()); +
+ /*
+ * when scroll-to-bottom is active, here is what events look like:
+ * rowcount-1: 227, last: 227, previous last: 191..first: 191
+ *
+ * when the user has unselected the bottom row, here is what the events \
look like: + * rowcount-1: 227, last: 227, previous last: 227..first: 222
+ *
+ * note: previouslast is set after it is evaluated in the bypass scroll \
check + */
+ //System.out.println("rowcount: " + (table.getRowCount() - 1) + ", last: \
" + evt.getLastIndex() +", previous last: " + previousLastIndex + "..first: " + \
evt.getFirstIndex() + ", isadjusting: " + evt.getValueIsAdjusting()); +
+ boolean disableScrollToBottom = (lastIndexOnLastRow && lastIndexSame && \
previousLastIndex != evt.getFirstIndex()); + if (disableScrollToBottom && \
isScrollToBottom() && table.getRowCount() > 0) { + \
preferenceModel.setScrollToBottom(false); + }
+ previousLastIndex = evt.getLastIndex();
+ }
+ }
+ );
+
table.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
- if (
- ((evt.getFirstIndex() == evt.getLastIndex())
+ if (((evt.getFirstIndex() == evt.getLastIndex())
&& (evt.getFirstIndex() > 0)) || (evt.getValueIsAdjusting())) {
return;
}
- boolean lastIndexOnLastRow = (evt.getLastIndex() == (table.getRowCount() - \
1));
- boolean lastIndexSame = (previousLastIndex == evt.getLastIndex());
-
- /*
- * when scroll-to-bottom is active, here is what events look like:
- * rowcount-1: 227, last: 227, previous last: 191..first: 191
- *
- * when the user has unselected the bottom row, here is what the events \
look like:
- * rowcount-1: 227, last: 227, previous last: 227..first: 222
- *
- * note: previouslast is set after it is evaluated in the bypass scroll \
check
- */
- //System.out.println("rowcount: " + (table.getRowCount() - 1) + ", last: " \
+ evt.getLastIndex() +", previous last: " + previousLastIndex + "..first: " + \
evt.getFirstIndex() + ", isadjusting: " + evt.getValueIsAdjusting());
-
- boolean disableScrollToBottom = (lastIndexOnLastRow && lastIndexSame && \
previousLastIndex != evt.getFirstIndex());
- if (disableScrollToBottom && isScrollToBottom() && table.getRowCount() > \
0) {
- preferenceModel.setScrollToBottom(false);
- }
- previousLastIndex = evt.getLastIndex();
final ListSelectionModel lsm = (ListSelectionModel) evt.getSource();
@@ -798,8 +808,7 @@
}
detailDialog.setLocation(lowerPanel.getLocationOnScreen());
- SwingUtilities.invokeLater(
- new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
detailDialog.setVisible(true);
}
@@ -814,7 +823,7 @@
tableModel.addNewKeyListener(
new NewKeyListener() {
public void newKeyAdded(final NewKeyEvent e) {
- SwingUtilities.invokeLater(new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
// don't add the column if we already know about it, this could be if \
we've seen it before and saved the column preferences
//this may throw an illegalargexception - ignore it because we need to \
add only if not already added @@ -1347,6 +1356,10 @@
preferenceModel.setScrollToBottom(!preferenceModel.isScrollToBottom());
}
+ private void scrollToBottom() {
+ table.scrollToRow(tableModel.getRowCount() - 1);
+ }
+
/**
* Accessor
*
@@ -1376,51 +1389,60 @@
* @param ident identifier shared by events
* @param events list of LoggingEvent objects
*/
- public void receiveEventBatch(String ident, List events) {
- /*
- * if this panel is paused, we totally ignore events
- */
- if (isPaused()) {
- return;
- }
+ public void receiveEventBatch(String ident, final List events) {
- //table.getSelectionModel().setValueIsAdjusting(true);
- boolean rowAdded = false;
+ SwingHelper.invokeOnEDT(new Runnable() {
+ public void run() {
+ /*
+ * if this panel is paused, we totally ignore events
+ */
+ if (isPaused()) {
+ return;
+ }
- int first = tableModel.getLastAdded() + 1;
+ final int selectedRow = table.getSelectedRow();
+ final LoggingEvent selectedEvent;
+ if (selectedRow >= 0) {
+ selectedEvent = tableModel.getRow(selectedRow);
+ } else {
+ selectedEvent = null;
+ }
- for (Iterator iter = events.iterator(); iter.hasNext();) {
- LoggingEvent event = (LoggingEvent) iter.next();
+ boolean rowAdded = false;
- updateOtherModels(event);
+ for (Iterator iter = events.iterator(); iter.hasNext();) {
+ LoggingEvent event = (LoggingEvent) iter.next();
- boolean isCurrentRowAdded = tableModel.isAddRow(event, true);
- rowAdded = rowAdded ? true : isCurrentRowAdded;
- }
+ updateOtherModels(event);
- table.getSelectionModel().setValueIsAdjusting(false);
+ rowAdded = rowAdded || tableModel.isAddRow(event);
+ }
- //tell the model to notify the count listeners
- tableModel.notifyCountListeners();
+ //tell the model to notify the count listeners
+ tableModel.notifyCountListeners();
- if (rowAdded) {
- if (tableModel.isSortEnabled()) {
- tableModel.sort();
- }
+ if (rowAdded) {
+ if (tableModel.isSortEnabled()) {
+ tableModel.sort();
+ }
- tableModel.fireTableEvent(
- first, tableModel.getLastAdded(), events.size());
+ //always update detail pane (since we may be using a cyclic buffer which \
is full) + detailPaneUpdater.setSelectedRow(table.getSelectedRow());
+ }
- if (isScrollToBottom()) {
- table.scrollToBottom(
- table.columnAtPoint(table.getVisibleRect().getLocation()));
+ if (isScrollToBottom()) {
+ scrollToBottom();
+ } else if (selectedEvent != null) {
+ final int newIndex = tableModel.getRowIndex(selectedEvent);
+ if (newIndex >= 0) {
+ // Don't scroll, just maintain selection...
+ table.setRowSelectionInterval(newIndex, newIndex);
+ }
+ }
}
-
- //always update detail pane (since we may be using a cyclic buffer which is \
full)
- detailPaneUpdater.setSelectedRow(table.getSelectedRow());
- }
+ });
}
-
+
/**
* Load settings from the panel preference model
*
@@ -1676,7 +1698,7 @@
dockingAction.putValue(Action.NAME, "Dock");
dockingAction.putValue(Action.SMALL_ICON, ChainsawIcons.ICON_DOCK);
if (row > -1) {
- table.scrollToRow(row, \
table.columnAtPoint(table.getVisibleRect().getLocation())); + \
table.scrollToRow(row); }
}
@@ -1715,7 +1737,7 @@
* @param eventNumber
*/
void setSelectedEvent(int eventNumber){
- table.scrollToRow(eventNumber - 1, 0);
+ table.scrollTo(eventNumber - 1, 0);
}
/**
@@ -2053,7 +2075,7 @@
* Update the status bar with current selected row and row count
*/
private void updateStatusBar() {
- SwingUtilities.invokeLater(
+ SwingHelper.invokeOnEDT(
new Runnable() {
public void run() {
statusBar.setSelectedLine(
@@ -2113,8 +2135,7 @@
tableModel.find(findRule, table.getSelectedRow() + 1, true);
if (nextRow > -1) {
- table.scrollToRow(
- nextRow, table.columnAtPoint(table.getVisibleRect().getLocation()));
+ table.scrollToRow(nextRow);
findField.setToolTipText("Enter an expression");
}
} catch (IllegalArgumentException iae) {
@@ -2138,9 +2159,7 @@
tableModel.find(findRule, table.getSelectedRow() - 1, false);
if (previousRow > -1) {
- table.scrollToRow(
- previousRow,
- table.columnAtPoint(table.getVisibleRect().getLocation()));
+ table.scrollToRow(previousRow);
findField.setToolTipText("Enter an expression");
}
} catch (IllegalArgumentException iae) {
@@ -2165,7 +2184,7 @@
dockingAction.putValue(Action.NAME, "Undock");
dockingAction.putValue(Action.SMALL_ICON, ChainsawIcons.ICON_UNDOCK);
if (row > -1) {
- table.scrollToRow(row, \
table.columnAtPoint(table.getVisibleRect().getLocation())); + \
table.scrollToRow(row); }
}
@@ -2612,7 +2631,7 @@
try {
final Document doc = detail.getEditorKit().createDefaultDocument();
detail.getEditorKit().read(new StringReader(buf.toString()), doc, 0);
- SwingUtilities.invokeLater(new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
detail.setDocument(doc);
detail.setCaretPosition(0);
@@ -2627,7 +2646,7 @@
try {
final Document doc = detail.getEditorKit().createDefaultDocument();
detail.getEditorKit().read(new StringReader("<html>Nothing \
selected</html>"), doc, 0);
- SwingUtilities.invokeLater(new Runnable() {
+ SwingHelper.invokeOnEDT(new Runnable() {
public void run() {
detail.setDocument(doc);
detail.setCaretPosition(0);
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java?rev=595870&r1=595869&r2=595870&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java \
(original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java \
Fri Nov 16 15:31:40 2007 @@ -20,6 +20,7 @@
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
+import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
@@ -72,5 +73,13 @@
cancelButton.setAction(closeAction);
dialog.getRootPane().getActionMap().put(CANCEL_ACTION_KEY, closeAction);
+ }
+
+ public static void invokeOnEDT(Runnable runnable) {
+ if (EventQueue.isDispatchThread()) {
+ runnable.run();
+ } else {
+ EventQueue.invokeLater(runnable);
+ }
}
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic