package hirondelle.stocks.preferences;
import java.util.*;
import java.util.logging.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import hirondelle.stocks.util.Consts;
import hirondelle.stocks.util.ui.UiConsts;
import hirondelle.stocks.util.ui.UiUtil;
import hirondelle.stocks.util.Util;
public final class LoggingPreferencesEditor implements PreferencesEditor {
@Override public int getMnemonic() {
return MNEMONIC;
}
@Override public String getTitle() {
return TITLE;
}
@Override public JComponent getUI() {
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.add(getLogFileUI()) ;
content.add(getLogLevelUI());
UiUtil.alignAllX(content, UiUtil.AlignX.LEFT);
return content;
}
@Override public void matchGuiToDefaultPreferences() { }
@Override public void savePreferences() { }
public File getLogConfigFile(){
File result = null;
String locationFromProperty = System.getProperty("java.util.logging.config.file");
if (locationFromProperty == null ) {
String rawJreHome= System.getProperty("java.home");
File jreHome = new File(rawJreHome);
File lib = new File(jreHome, "lib");
result = new File(lib, "logging.properties");
}
else {
result = new File(locationFromProperty);
}
assert result.exists();
return result;
}
private static final String TITLE = "Logging";
private static final int MNEMONIC = KeyEvent.VK_L;
private static final String EXPLANATION =
"Temporarily override the configured log level for all known loggers and handlers."+
" (Setting the log level here will affect only the currently " +
"running program. To change settings more permanently, edit " +
"the above-named log file.)"
;
private JComboBox<Level> fLogLevel;
private static final Logger fLogger = Util.getLogger(LoggingPreferencesEditor.class);
private static java.util.List<Level> LEVELS;
static {
LEVELS = new ArrayList<>();
LEVELS.add(Level.OFF);
LEVELS.add(Level.FINEST);
LEVELS.add(Level.FINER);
LEVELS.add(Level.FINE);
LEVELS.add(Level.CONFIG);
LEVELS.add(Level.INFO);
LEVELS.add(Level.WARNING);
LEVELS.add(Level.SEVERE);
}
private void refreshLogFile(){
LogManager logManager = LogManager.getLogManager();
try {
logManager.readConfiguration();
OptionPaneExceptionHandler.attachToRootLogger();
}
catch (IOException ex){
fLogger.log(
Level.SEVERE, "Cannot re-read logging config file. Please verify file name.", ex
);
}
}
private JComponent getLogFileUI(){
JPanel content = new JPanel();
content.setBorder( BorderFactory.createTitledBorder("Logging Config File") );
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.add(getLocation());
content.add(Box.createVerticalStrut(UiConsts.ONE_SPACE));
content.add(getRefresh()) ;
content.add(Box.createVerticalStrut(UiConsts.ONE_SPACE));
UiUtil.alignAllX(content, UiUtil.AlignX.CENTER);
return content;
}
private JComponent getLocation(){
return UiUtil.getStandardTextArea(getLogConfigFile().toString());
}
private JComponent getRefresh(){
JButton refresh = new JButton("Refresh Now");
refresh.setMnemonic(KeyEvent.VK_R);
refresh.setToolTipText("Refreshes the above logging config file");
refresh.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e){
refreshLogFile();
}
});
return refresh;
}
private JComponent getLogLevelUI(){
JPanel content = new JPanel();
content.setBorder(BorderFactory.createTitledBorder("Temporary Log Level"));
content.setLayout( new BoxLayout(content, BoxLayout.Y_AXIS) );
content.add( getExplanation() );
content.add( Box.createVerticalStrut(UiConsts.ONE_SPACE) );
content.add( getLogLevel() );
content.add( Box.createVerticalStrut(UiConsts.ONE_SPACE) );
UiUtil.alignAllX(content, UiUtil.AlignX.CENTER);
return content;
}
private JComponent getExplanation(){
return UiUtil.getStandardTextArea(EXPLANATION);
}
private JComponent getLogLevel(){
DefaultComboBoxModel<Level> levelsModel = new DefaultComboBoxModel<Level>(
LEVELS.toArray(new Level[0])
);
fLogLevel = new JComboBox<Level>(levelsModel);
fLogLevel.setToolTipText("Select an item to immediately update logging levels");
fLogLevel.addActionListener( new ActionListener() {
@Override public void actionPerformed(ActionEvent event) {
changeGlobalLoggingLevels();
}
});
fLogLevel.setMaximumSize(new Dimension(100,50));
return fLogLevel;
}
private void changeGlobalLoggingLevels(){
Level targetLevel = (Level)fLogLevel.getSelectedItem();
Logger rootLogger = Logger.getLogger(Consts.EMPTY_STRING);
for(Handler handler: rootLogger.getHandlers()){
if ( ! (handler instanceof OptionPaneExceptionHandler) ) {
handler.setLevel(targetLevel);
}
}
rootLogger.setLevel(targetLevel);
java.util.List<String> loggerNames = Collections.list(
LogManager.getLogManager().getLoggerNames()
);
for(String loggerName : loggerNames){
Logger logger = LogManager.getLogManager().getLogger(loggerName);
logger.setLevel(targetLevel);
}
}
}