Replaced application-wide preferences automatic configuration URL textfield with editable combobox remembering 10 most-recently used configuration URLs
- added a browse button to build the configuration file URL
- manually changing or browsing to an entry and pressing 'ok' button automatically loads the configuration
- list is persisted & restored on Chainsaw restart
- MRU count: 10
git-svn-id: https://svn.apache.org/repos/asf/logging/chainsaw/trunk@833850 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModel.java b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModel.java
index d7d06a7..bf5f94d 100644
--- a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModel.java
+++ b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModel.java
@@ -18,6 +18,7 @@
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
+import java.util.Vector;
/**
@@ -50,13 +51,15 @@
/**
* If not 'empty', this property will be used as the URL to load log4j configuration at startup
*/
- private String configurationURL="";
-
+ private Vector configurationURLs=new Vector();
+
+ private String configurationURL = "";
/**
* this means for Receivers that require optional jars that can't be delivered
* by the Web start classloader, we need to be able to remove the SecurityManager in place
*/
private boolean okToRemoveSecurityManager = false;
+ private static final int CONFIGURATION_URL_ENTRY_COUNT = 10;
/**
* @param listener
@@ -185,6 +188,7 @@
setShowSplash(model.isShowSplash());
setToolTipDisplayMillis(model.getToolTipDisplayMillis());
setCyclicBufferSize(model.getCyclicBufferSize());
+ setConfigurationURLs(model.getConfigurationURLs());
setConfigurationURL(model.getConfigurationURL());
setLastUsedVersion(model.getLastUsedVersion());
setOkToRemoveSecurityManager(model.isOkToRemoveSecurityManager());
@@ -234,6 +238,14 @@
return statusBar;
}
+ public Vector getConfigurationURLs() {
+ return configurationURLs;
+ }
+
+ public void setConfigurationURLs(Vector urls) {
+ configurationURLs = urls;
+ }
+
/**
* @param statusBar The statusBar to set.
*/
@@ -333,9 +345,20 @@
*/
public final void setConfigurationURL(String configurationURL)
{
+ //don't add empty entries
+ if (configurationURL == null || configurationURL.trim().equals("")) {
+ return;
+ }
Object oldValue = this.configurationURL;
- this.configurationURL = configurationURL;
- firePropertyChange("configurationURL", oldValue, this.configurationURL);
+ //add entry to MRU list
+ if (!configurationURLs.contains(configurationURL)) {
+ if (configurationURLs.size() == CONFIGURATION_URL_ENTRY_COUNT) {
+ configurationURLs.remove(CONFIGURATION_URL_ENTRY_COUNT - 1);
+ }
+ configurationURLs.add(0, configurationURL);
+ }
+ this.configurationURL = configurationURL;
+ firePropertyChange("configurationURL", oldValue, this.configurationURL);
}
/**
* @return Returns the lastUsedVersion.
diff --git a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
index c581f7f..26201ed 100644
--- a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
+++ b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
@@ -17,11 +17,14 @@
package org.apache.log4j.chainsaw;
+import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.net.MalformedURLException;
import java.net.URL;
import java.util.Dictionary;
import java.util.Enumeration;
@@ -31,9 +34,13 @@
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
+import javax.swing.DefaultComboBoxModel;
import javax.swing.InputVerifier;
+import javax.swing.JButton;
import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
import javax.swing.JComponent;
+import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
@@ -67,7 +74,7 @@
private JTextField identifierExpression;
private JTextField toolTipDisplayMillis;
private JTextField cyclicBufferSize;
- private final JTextField configurationURL = new JTextField(35);
+ private JComboBox configurationURL;
private final Logger logger;
ApplicationPreferenceModelPanel(ApplicationPreferenceModel model) {
@@ -77,7 +84,7 @@
getOkButton().addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
- uncommittedPreferenceModel.setConfigurationURL(configurationURL.getText());
+ uncommittedPreferenceModel.setConfigurationURL((String)configurationURL.getSelectedItem());
uncommittedPreferenceModel.setIdentifierExpression(
identifierExpression.getText());
try {
@@ -409,6 +416,11 @@
private void initComponents() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ configurationURL = new JComboBox(new DefaultComboBoxModel(committedPreferenceModel.getConfigurationURLs()));
+ configurationURL.setEditable(true);
+ configurationURL.setPrototypeDisplayValue("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+ configurationURL.setPreferredSize(new Dimension(375, 25));
+
identifierExpression = new JTextField(20);
toolTipDisplayMillis = new JTextField(8);
cyclicBufferSize = new JTextField(8);
@@ -470,11 +482,50 @@
p6.add(configurationURL);
add(p6);
- JPanel p7 = new JPanel(new FlowLayout(FlowLayout.LEFT));
- p7.add(
+ JButton browseButton = new JButton("Browse");
+ browseButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+
+ String defaultPath = ".";
+ if (configurationURL.getItemCount() > 0) {
+ File currentConfigurationPath = new File(configurationURL.getSelectedItem().toString()).getParentFile();
+ defaultPath = currentConfigurationPath.getPath();
+ //JFileChooser constructor will not navigate to this location unless we remove the prefixing protocol and slash
+ //at least on winxp
+ if (defaultPath.toLowerCase().startsWith("file:\\")) {
+ defaultPath = defaultPath.substring("file:\\".length());
+ }
+ }
+
+ JFileChooser chooser = new JFileChooser(defaultPath);
+ int result = chooser.showOpenDialog(ApplicationPreferenceModelPanel.this);
+ if (JFileChooser.APPROVE_OPTION == result) {
+ File f = chooser.getSelectedFile();
+ try
+ {
+ String newConfigurationFile = f.toURI().toURL().toExternalForm();
+ configurationURL.addItem(newConfigurationFile);
+ configurationURL.setSelectedItem(newConfigurationFile);
+ }
+ catch (MalformedURLException e1)
+ {
+ e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+ });
+
+ JPanel p7 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ p7.add(browseButton);
+ add(p7);
+
+ JPanel p8 = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ p8.add(
new JLabel(
"Cyclic buffer size change will apply the next time you start Chainsaw"));
- add(p7);
+ add(p8);
add(Box.createVerticalGlue());
@@ -484,12 +535,13 @@
public boolean verify(JComponent input)
{
try {
- new URL(configurationURL.getText());
+ new URL((String)configurationURL.getSelectedItem());
} catch (Exception e) {
return false;
}
return true;
}});
+ configurationURL.setSelectedItem(committedPreferenceModel.getConfigurationURL());
}
private void initSliderComponent() {
@@ -643,7 +695,7 @@
public void propertyChange(PropertyChangeEvent evt) {
String value = evt.getNewValue().toString();
- configurationURL.setText(value);
+ configurationURL.setSelectedItem(value);
}});
confirmExit.addActionListener(
new ActionListener() {
@@ -673,7 +725,7 @@
identifierExpression.setText(uncommittedPreferenceModel.getIdentifierExpression());
toolTipDisplayMillis.setText(uncommittedPreferenceModel.getToolTipDisplayMillis()+"");
cyclicBufferSize.setText(uncommittedPreferenceModel.getCyclicBufferSize() + "");
- configurationURL.setText(uncommittedPreferenceModel.getConfigurationURL());
+ configurationURL.setSelectedItem(uncommittedPreferenceModel.getConfigurationURL());
}
}
}
diff --git a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelSaver.java b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelSaver.java
index 81268bb..dff04af 100644
--- a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelSaver.java
+++ b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelSaver.java
@@ -4,14 +4,14 @@
import java.io.FileReader;
import java.io.FileWriter;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SettingsListener;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
-import com.thoughtworks.xstream.XStream;
-import com.thoughtworks.xstream.io.xml.DomDriver;
-
/**
* Helper class that helps delegate the work of loading and saving the values
* of the ApplicationPreferenceModel, allowing that class to remain a simple
@@ -37,8 +37,8 @@
public void loadSettings(LoadSettingsEvent event) {
XStream stream = new XStream(new DomDriver());
+ File file = getApplicationPreferenceXMLFile(SettingsManager.getInstance().getSettingsDirectory());
try {
- File file = getApplicationPreferenceXMLFile(SettingsManager.getInstance().getSettingsDirectory());
if (file.exists()) {
FileReader reader = new FileReader(file);
ApplicationPreferenceModel loadedModel = (ApplicationPreferenceModel) stream
@@ -49,8 +49,9 @@
} catch (Exception e) {
// TODO exception handling
e.printStackTrace();
+ //unable to process - delete file
+ file.delete();
}
-
}
public void saveSettings(SaveSettingsEvent event) {
diff --git a/src/main/java/org/apache/log4j/chainsaw/LogUI.java b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
index 610f0b8..0e17dfa 100644
--- a/src/main/java/org/apache/log4j/chainsaw/LogUI.java
+++ b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
@@ -373,6 +373,7 @@
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
+ e.printStackTrace();
logger.error("Uncaught exception in thread " + t, e);
}
});
@@ -405,7 +406,7 @@
}
}});
- if (config == null) {
+ if (config == null || config.trim().equals("")) {
logger.info("No auto-configuration file found within the ApplicationPreferenceModel");
} else {
logger.info("Using '" + config + "' for auto-configuration");