de.huxhorn.lilith.swing.preferences.PreferencesDialog.java Source code

Java tutorial

Introduction

Here is the source code for de.huxhorn.lilith.swing.preferences.PreferencesDialog.java

Source

/*
 * Lilith - a log event viewer.
 * Copyright (C) 2007-2016 Joern Huxhorn
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.huxhorn.lilith.swing.preferences;

import de.huxhorn.lilith.data.eventsource.EventWrapper;
import de.huxhorn.lilith.data.eventsource.SourceIdentifier;
import de.huxhorn.lilith.data.logging.LoggingEvent;
import de.huxhorn.lilith.prefs.LilithPreferences;
import de.huxhorn.lilith.swing.ApplicationPreferences;
import de.huxhorn.lilith.swing.LilithKeyStrokes;
import de.huxhorn.lilith.swing.MainFrame;
import de.huxhorn.sulky.conditions.Condition;
import de.huxhorn.sulky.swing.KeyStrokes;
import groovy.ui.Console;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.ListCellRenderer;
import javax.swing.SwingConstants;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PreferencesDialog extends JDialog {
    private static final long serialVersionUID = 8313102215860746241L;

    public enum Panes {
        General, StartupShutdown, Windows, Sounds, Sources, SourceLists, SourceFiltering, Conditions, LoggingLevels, AccessStatus, Troubleshooting
    }

    public enum Actions {
        reinitializeDetailsViewFiles
    }

    private final Logger logger = LoggerFactory.getLogger(PreferencesDialog.class);

    private ApplicationPreferences applicationPreferences;
    private MainFrame mainFrame;

    private JComboBox<Panes> comboBox;
    private DefaultComboBoxModel<Panes> comboBoxModel;
    private CardLayout cardLayout;
    private JPanel content;

    private GeneralPanel generalPanel;
    private StartupShutdownPanel startupShutdownPanel;
    private WindowsPanel windowsPanel;
    private SoundsPanel soundsPanel;
    private SourcesPanel sourcesPanel;
    private SourceListsPanel sourceListsPanel;
    private ConditionsPanel conditionsPanel;
    private LoggingLevelPanel loggingLevelPanel;
    private AccessStatusTypePanel accessStatusTypePanel;

    private Map<String, String> sourceNames;
    private Map<String, Set<String>> sourceLists;
    private SourceFilteringPanel sourceFilteringPanel;
    private String blackListName;
    private String whiteListName;
    private LilithPreferences.SourceFiltering sourceFiltering;

    public PreferencesDialog(MainFrame mainFrame) {
        super(mainFrame, "Preferences");
        this.mainFrame = mainFrame;
        this.applicationPreferences = mainFrame.getApplicationPreferences();
        createUI();
    }

    public ApplicationPreferences getApplicationPreferences() {
        return applicationPreferences;
    }

    public MainFrame getMainFrame() {
        return mainFrame;
    }

    private void createUI() {
        generalPanel = new GeneralPanel(this);
        startupShutdownPanel = new StartupShutdownPanel(this);
        windowsPanel = new WindowsPanel(this);
        soundsPanel = new SoundsPanel(this);
        sourcesPanel = new SourcesPanel(this);
        sourceListsPanel = new SourceListsPanel(this);
        sourceFilteringPanel = new SourceFilteringPanel(this);
        conditionsPanel = new ConditionsPanel(this);
        loggingLevelPanel = new LoggingLevelPanel(this);
        accessStatusTypePanel = new AccessStatusTypePanel(this);
        TroubleshootingPanel troubleshootingPanel = new TroubleshootingPanel(this);

        comboBoxModel = new DefaultComboBoxModel<>();
        for (Panes current : Panes.values()) {
            comboBoxModel.addElement(current);
        }
        comboBox = new JComboBox<>(comboBoxModel);
        comboBox.setRenderer(new MyComboBoxRenderer());
        comboBox.setEditable(false);
        comboBox.addItemListener(new ComboItemListener());

        cardLayout = new CardLayout();
        content = new JPanel(cardLayout);
        content.setPreferredSize(new Dimension(600, 500));

        content.add(generalPanel, Panes.General.toString());
        content.add(startupShutdownPanel, Panes.StartupShutdown.toString());
        content.add(windowsPanel, Panes.Windows.toString());
        content.add(soundsPanel, Panes.Sounds.toString());
        content.add(sourcesPanel, Panes.Sources.toString());
        content.add(sourceListsPanel, Panes.SourceLists.toString());
        content.add(sourceFilteringPanel, Panes.SourceFiltering.toString());
        content.add(conditionsPanel, Panes.Conditions.toString());
        content.add(loggingLevelPanel, Panes.LoggingLevels.toString());
        content.add(accessStatusTypePanel, Panes.AccessStatus.toString());
        content.add(troubleshootingPanel, Panes.Troubleshooting.toString());

        // Main buttons
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        OkAction okAction = new OkAction();
        buttonPanel.add(new JButton(okAction));
        buttonPanel.add(new JButton(new ApplyAction()));
        buttonPanel.add(new JButton(new ResetAction()));
        CancelAction cancelAction = new CancelAction();
        buttonPanel.add(new JButton(cancelAction));

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(comboBox, BorderLayout.NORTH);
        contentPane.add(content, BorderLayout.CENTER);
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
        KeyStrokes.registerCommand(content, okAction, "OK_ACTION");
        KeyStrokes.registerCommand(buttonPanel, okAction, "OK_ACTION");
        KeyStrokes.registerCommand(content, cancelAction, "CANCEL_ACTION");
        KeyStrokes.registerCommand(buttonPanel, cancelAction, "CANCEL_ACTION");
    }

    private void initUI() {
        generalPanel.initUI();
        startupShutdownPanel.initUI();
        windowsPanel.initUI();
        soundsPanel.initUI();
        sourceNames = applicationPreferences.getSourceNames();
        if (sourceNames == null) {
            sourceNames = new HashMap<>();
        } else {
            sourceNames = new HashMap<>(sourceNames);
        }
        sourceLists = applicationPreferences.getSourceLists();
        conditionsPanel.initUI();
        sourcesPanel.initUI();
        sourceListsPanel.initUI();
        sourceFilteringPanel.initUI();
        loggingLevelPanel.initUI();
        accessStatusTypePanel.initUI();
    }

    public Map<String, String> getSourceNames() {
        return sourceNames;
    }

    public void setSourceNames(Map<String, String> sourceNames) {
        this.sourceNames = sourceNames;
        sourcesPanel.initUI();
        sourceListsPanel.initUI();
    }

    public void setSourceName(String oldIdentifier, String newIdentifier, String sourceName) {
        if (sourceNames.containsKey(oldIdentifier)) {
            sourceNames.remove(oldIdentifier);
        }
        sourceNames.put(newIdentifier, sourceName);
        sourcesPanel.initUI();
        sourceListsPanel.initUI();
    }

    public void setSourceList(String oldName, String newName, List<Source> sourceList) {
        if (sourceLists.containsKey(oldName)) {
            sourceLists.remove(oldName);
        }
        Set<String> newList = new HashSet<>();
        for (Source s : sourceList) {
            newList.add(s.getIdentifier());
        }
        sourceLists.put(newName, newList);
        sourceListsPanel.initUI();
        sourceFilteringPanel.initUI();
    }

    /**
     *
     * @param name the name of the source list
     * @return the source list of the given name or an empty List
     */
    public List<Source> getSourceList(String name) {
        Set<String> srcList = sourceLists.get(name);
        if (srcList != null) {
            List<Source> result = new ArrayList<>();
            for (String current : srcList) {
                Source s = new Source();
                s.setIdentifier(current);
                s.setName(getSourceName(current));
                result.add(s);
            }
            Collections.sort(result);
            return result;
        }
        return new ArrayList<>();
    }

    private String getSourceName(String identifier) {
        String result = sourceNames.get(identifier);
        if (result == null) {
            result = identifier;
        }
        return result;
    }

    private void saveSettings() {
        generalPanel.saveSettings();
        startupShutdownPanel.saveSettings();
        windowsPanel.saveSettings();
        soundsPanel.saveSettings();
        conditionsPanel.saveSettings();
        loggingLevelPanel.saveSettings();
        accessStatusTypePanel.saveSettings();
        applicationPreferences.setSourceNames(sourceNames);
        applicationPreferences.setSourceLists(sourceLists);
        applicationPreferences.setBlackListName(blackListName);
        applicationPreferences.setWhiteListName(whiteListName);
        applicationPreferences.setSourceFiltering(sourceFiltering);
    }

    private void resetSettings() {
        // just reinit from preferences, nobody would expect anything else...
        initUI();
    }

    public void setVisible(boolean visible) {
        if (visible != isVisible()) {
            if (visible) {
                initUI();
            }
            super.setVisible(visible);
        }
    }

    public List<String> getSourceListNames() {
        return new ArrayList<>(sourceLists.keySet());
    }

    public void removeSourceList(String sourceListName) {
        if (sourceLists.containsKey(sourceListName)) {
            sourceLists.remove(sourceListName);
            sourceListsPanel.initUI();
            sourceFilteringPanel.initUI();
        }
    }

    public String getBlackListName() {
        if (blackListName == null) {
            blackListName = applicationPreferences.getBlackListName();
        }
        return blackListName;
    }

    public String getWhiteListName() {
        if (whiteListName == null) {
            whiteListName = applicationPreferences.getWhiteListName();
        }
        return whiteListName;
    }

    public LilithPreferences.SourceFiltering getSourceFiltering() {
        if (sourceFiltering == null) {
            sourceFiltering = applicationPreferences.getSourceFiltering();
        }
        return sourceFiltering;
    }

    public void setSourceFiltering(LilithPreferences.SourceFiltering sourceFiltering) {
        this.sourceFiltering = sourceFiltering;
    }

    public void setBlackListName(String blackListName) {
        this.blackListName = blackListName;
    }

    public void setWhiteListName(String whiteListName) {
        this.whiteListName = whiteListName;
    }

    public void setShowingTipOfTheDay(boolean showingTipOfTheDay) {
        startupShutdownPanel.setShowingTipOfTheDay(showingTipOfTheDay);
    }

    public void setCheckingForUpdate(boolean checkingForUpdate) {
        startupShutdownPanel.setCheckingForUpdate(checkingForUpdate);
    }

    public void setCheckingForSnapshot(boolean checkingForSnapshot) {
        startupShutdownPanel.setCheckingForSnapshot(checkingForSnapshot);
    }

    private class OkAction extends AbstractAction {
        private static final long serialVersionUID = 3395474960394431088L;

        OkAction() {
            super("Ok");
            KeyStroke accelerator = LilithKeyStrokes.getKeyStroke(LilithKeyStrokes.ENTER);
            putValue(Action.ACCELERATOR_KEY, accelerator);
            putValue(Action.MNEMONIC_KEY, KeyEvent.VK_O);
        }

        public void actionPerformed(ActionEvent e) {
            saveSettings();
            setVisible(false);
        }
    }

    private class ApplyAction extends AbstractAction {
        private static final long serialVersionUID = -4047672339764590549L;

        ApplyAction() {
            super("Apply");
            putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A);
        }

        public void actionPerformed(ActionEvent e) {
            saveSettings();
        }
    }

    private class ResetAction extends AbstractAction {
        private static final long serialVersionUID = -7109027518233905200L;

        ResetAction() {
            super("Reset");
            putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
        }

        public void actionPerformed(ActionEvent e) {
            resetSettings();
        }
    }

    private class CancelAction extends AbstractAction {
        private static final long serialVersionUID = 6933499606501725571L;

        CancelAction() {
            super("Cancel");
            KeyStroke accelerator = LilithKeyStrokes.getKeyStroke(LilithKeyStrokes.ESCAPE);
            putValue(Action.ACCELERATOR_KEY, accelerator);
            putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C);
        }

        public void actionPerformed(ActionEvent e) {
            setVisible(false);
        }
    }

    public void editSourceName(String sourceIdentifier) {
        showPane(Panes.Sources);
        sourcesPanel.editSourceName(sourceIdentifier);
    }

    public void executeAction(Actions action) {
        if (logger.isInfoEnabled())
            logger.info("Execute action {}.", action);
        if (action == null) {
            return;
        }
        switch (action) {
        case reinitializeDetailsViewFiles:
            reinitializeDetailsViewFiles();
            break;
        }
    }

    public void showPane(Panes pane) {
        if (pane == null) {
            return;
        }
        cardLayout.show(content, pane.toString());
        if (!pane.equals(comboBox.getSelectedItem())) {
            comboBox.setSelectedItem(pane);
        }
        if (!isVisible()) {
            mainFrame.showPreferencesDialog();
        }
    }

    public void reinitializeDetailsViewFiles() {
        String dialogTitle = "Reinitialize details view files?";
        String message = "This resets all details view related files, all manual changes will be lost!\nReinitialize details view right now?";
        int result = JOptionPane.showConfirmDialog(this, message, dialogTitle, JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE);
        // TODO: add "Show in Finder/Explorer" button if running on Mac/Windows
        if (JOptionPane.OK_OPTION != result) {
            return;
        }

        applicationPreferences.initDetailsViewRoot(true);
    }

    public void reinitializeGroovyConditions() {
        String dialogTitle = "Reinitialize example groovy conditions?";
        String message = "This overwrites all example groovy conditions. Other conditions are not changed!\nReinitialize example groovy conditions right now?";
        int result = JOptionPane.showConfirmDialog(this, message, dialogTitle, JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE);
        // TODO: add "Show in Finder/Explorer" button if running on Mac/Windows
        if (JOptionPane.OK_OPTION != result) {
            return;
        }

        applicationPreferences.installExampleConditions();
    }

    public void reinitializeGroovyClipboardFormatters() {
        String dialogTitle = "Reinitialize example groovy clipboard formatters?";
        String message = "This overwrites all example groovy clipboard formatters. Other clipboard formatters are not changed!\nReinitialize example groovy clipboard formatters right now?";
        int result = JOptionPane.showConfirmDialog(this, message, dialogTitle, JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE);
        // TODO: add "Show in Finder/Explorer" button if running on Mac/Windows
        if (JOptionPane.OK_OPTION != result) {
            return;
        }

        applicationPreferences.installExampleClipboardFormatters();
    }

    public void deleteAllLogs() {
        String dialogTitle = "Delete all log files?";
        String message = "This deletes *all* log files, even the Lilith logs and the global logs!\nDelete all log files right now?";
        int result = JOptionPane.showConfirmDialog(this, message, dialogTitle, JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE);
        // TODO: add "Show in Finder/Explorer" button if running on Mac/Windows
        if (JOptionPane.OK_OPTION != result) {
            return;
        }

        mainFrame.deleteAllLogs();
    }

    public void editDetailsFormatter() {
        Console console = new Console();
        File messageViewRoot = applicationPreferences.getDetailsViewRoot();
        File messageViewGroovyFile = new File(messageViewRoot, ApplicationPreferences.DETAILS_VIEW_GROOVY_FILENAME);

        EventWrapper<LoggingEvent> eventWrapper = new EventWrapper<>(
                new SourceIdentifier("identifier", "secondaryIdentifier"), 17, new LoggingEvent());
        console.setVariable("eventWrapper", eventWrapper);

        console.setCurrentFileChooserDir(messageViewRoot);
        String text = "";
        if (!messageViewGroovyFile.isFile()) {
            applicationPreferences.initDetailsViewRoot(true);
        }
        if (messageViewGroovyFile.isFile()) {
            InputStream is;
            try {
                is = new FileInputStream(messageViewGroovyFile);
                List lines = IOUtils.readLines(is, StandardCharsets.UTF_8);
                boolean isFirst = true;
                StringBuilder textBuffer = new StringBuilder();
                for (Object o : lines) {
                    String s = (String) o;
                    if (isFirst) {
                        isFirst = false;
                    } else {
                        textBuffer.append("\n");
                    }
                    textBuffer.append(s);
                }
                text = textBuffer.toString();
            } catch (IOException e) {
                if (logger.isInfoEnabled()) {
                    logger.info("Exception while reading '" + messageViewGroovyFile.getAbsolutePath() + "'.", e);
                }
            }
        } else {
            if (logger.isWarnEnabled())
                logger.warn("Failed to initialize detailsView file '{}'!", messageViewGroovyFile.getAbsolutePath());
        }
        console.run(); // initializes everything

        console.setScriptFile(messageViewGroovyFile);
        JTextPane inputArea = console.getInputArea();
        //inputArea.setText(text);
        Document doc = inputArea.getDocument();
        try {
            doc.remove(0, doc.getLength());
            doc.insertString(0, text, null);
        } catch (BadLocationException e) {
            if (logger.isWarnEnabled())
                logger.warn("Exception while setting source!", e);
        }
        console.setDirty(false);
        inputArea.setCaretPosition(0);
        inputArea.requestFocusInWindow();
    }

    public void editCondition(Condition condition) {
        showPane(Panes.Conditions);
        conditionsPanel.editCondition(condition);
    }

    private static class MyComboBoxRenderer implements ListCellRenderer<Panes> {
        private JLabel label;

        MyComboBoxRenderer() {
            label = new JLabel();
            label.setOpaque(true);
            label.setHorizontalAlignment(SwingConstants.LEFT);
            label.setVerticalAlignment(SwingConstants.CENTER);
        }

        @Override
        public Component getListCellRendererComponent(JList<? extends Panes> list, Panes value, int index,
                boolean isSelected, boolean cellHasFocus) {
            if (isSelected) {
                label.setBackground(list.getSelectionBackground());
                label.setForeground(list.getSelectionForeground());
            } else {
                label.setBackground(list.getBackground());
                label.setForeground(list.getForeground());
            }

            String title = null;

            if (value != null) {
                switch (value) {
                case General:
                    title = "General";
                    break;
                case StartupShutdown:
                    title = "Startup & Shutdown";
                    break;
                case Windows:
                    title = "Windows";
                    break;
                case Sounds:
                    title = "Sounds";
                    break;
                case Sources:
                    title = "Sources";
                    break;
                case SourceLists:
                    title = "Source Lists";
                    break;
                case SourceFiltering:
                    title = "Source Filtering";
                    break;
                case Conditions:
                    title = "Conditions";
                    break;
                case LoggingLevels:
                    title = "Logging levels";
                    break;
                case AccessStatus:
                    title = "Access status types";
                    break;
                case Troubleshooting:
                    title = "Troubleshooting";
                    break;
                }
            }
            label.setText(title);
            label.setToolTipText(title);

            return label;
        }
    }

    private class ComboItemListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            Object item = comboBoxModel.getSelectedItem();
            if (item instanceof Panes) {
                Panes pane = (Panes) item;
                showPane(pane);
            }
        }
    }
}