package org.openpnp.gui;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.prefs.Preferences;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import org.openpnp.gui.support.JTextLogWriter;
import org.pmw.tinylog.Configurator;
import org.pmw.tinylog.Level;
public class LogPanel extends JPanel {
private JTextArea text;
private JTextLogWriter writer;
private Preferences prefs = Preferences.userNodeForPackage(LogPanel.class);
private static final String PREF_LOG_LEVEL = "LogPanel.logLevel";
private static final String PREF_LOG_LEVEL_DEF = Level.INFO.toString();
private static final String PREF_LOG_LINE_LIMIT = "LogPanel.lineLimit";
private static final int PREF_LOG_LINE_LIMIT_DEF = 1000;
HashMap<String, Integer> lineLimits = new HashMap<String, Integer>() {
{
put("100", 100);
put("1000", 1000);
put("10000", 10000);
put("Unlimited", -1);
}
};
public LogPanel() {
setLayout(new BorderLayout(0, 0));
JToolBar toolBar = new JToolBar();
add(toolBar, BorderLayout.NORTH);
JButton btnLineLimit = new JButton("Line Limit");
toolBar.add(btnLineLimit);
JButton btnLogLevel = new JButton("Log Level");
toolBar.add(btnLogLevel);
text = new JTextArea();
text.setFont(new Font("Monospaced", Font.PLAIN, 13));
text.setEditable(false);
text.setLineWrap(true);
add(new JScrollPane(text), BorderLayout.CENTER);
writer = new JTextLogWriter(text);
writer.setLineLimit(prefs.getInt(PREF_LOG_LINE_LIMIT, PREF_LOG_LINE_LIMIT_DEF));
// This weird check is here because I mistakenly reused the same config key when
// switching from slf to tinylog. This meant that some users had an int based
// value in the key rather than the string. This caused initialization failures.
Level level = null;
try {
level = Level.valueOf(prefs.get(PREF_LOG_LEVEL, PREF_LOG_LEVEL_DEF));
}
catch (Exception e) {
}
if (level == null ) {
level = Level.INFO;
}
Configurator
.currentConfig()
.level(level)
.activate();
Configurator
.currentConfig()
.addWriter(writer)
.activate();
JPopupMenu lineLimitPopupMenu = createLineLimitMenu();
btnLineLimit.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
lineLimitPopupMenu.show(e.getComponent(), e.getX(), e.getY());
}
});
JPopupMenu logLevelPopupMenu = createLogLevelMenu();
btnLogLevel.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
logLevelPopupMenu.show(e.getComponent(), e.getX(), e.getY());
}
});
}
private JPopupMenu createLineLimitMenu() {
ButtonGroup buttonGroup = new ButtonGroup();
JPopupMenu menu = new JPopupMenu();
lineLimits.forEach((label, limit) -> {
JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(label);
menuItem.setActionCommand(limit.toString());
menuItem.addActionListener(setLineLimitAction);
if (limit == prefs.getInt(PREF_LOG_LINE_LIMIT, PREF_LOG_LINE_LIMIT_DEF)) {
menuItem.setSelected(true);
}
buttonGroup.add(menuItem);
menu.add(menuItem);
});
return menu;
}
private JPopupMenu createLogLevelMenu() {
ButtonGroup buttonGroup = new ButtonGroup();
JRadioButtonMenuItem menuItem;
JPopupMenu menu = new JPopupMenu();
for (Level level : Level.values()) {
menuItem = new JRadioButtonMenuItem(level.toString());
if (level.toString().equals(prefs.get(PREF_LOG_LEVEL, PREF_LOG_LEVEL_DEF))) {
menuItem.setSelected(true);
}
menuItem.addActionListener(setThresholdAction);
buttonGroup.add(menuItem);
menu.add(menuItem);
}
return menu;
}
private Action setThresholdAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();
prefs.put(PREF_LOG_LEVEL, s);
Level level = Level.valueOf(s);
Configurator
.currentConfig()
.level(level)
.activate();
}
};
private Action setLineLimitAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
int lineLimit = Integer.parseInt(e.getActionCommand());
prefs.putInt(PREF_LOG_LINE_LIMIT, lineLimit);
writer.setLineLimit(lineLimit);
}
};
}