| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * @author Paul Smith <psmith@apache.org> |
| * |
| */ |
| package org.apache.log4j.chainsaw.components.tabbedpane; |
| |
| import com.owlike.genson.Genson; |
| 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 org.apache.logging.log4j.LogManager; |
| import org.apache.logging.log4j.Logger; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| |
| |
| /** |
| * The only reason this class is needed is because |
| * of a stupid 'issue' with the JTabbedPane. |
| * <p> |
| * If the currently selected tab is the first tab, |
| * and we insert a new tab at the front, then as |
| * far as the JTabbedPane is concerned, NO STATE has |
| * changed, as the currently selected tab index is still |
| * the same (even though the TAB is different - go figure) |
| * and therefore no ChangeEvent is generated and sent |
| * to listeners. Thanks very much Sun! |
| * <p> |
| * For more information on the issue: |
| * http://developer.java.sun.com/developer/bugParade/bugs/4253819.html |
| * |
| * @author Paul Smith <psmith@apache.org> |
| * @author Scott Deboy <sdeboy@apache.org> |
| */ |
| |
| public class ChainsawTabbedPane extends JTabbedPane implements SettingsListener { |
| private static Logger logger = LogManager.getLogger(ChainsawTabbedPane.class); |
| public SavableTabSetting tabSetting; |
| public static final String WELCOME_TAB = "Welcome"; |
| public static final String ZEROCONF = "Zeroconf"; |
| |
| /** |
| * Returns true if this TabbedPane has an instance of the WelcomePanel |
| * in it |
| * |
| * @return true/false |
| */ |
| public boolean containsWelcomePanel() { |
| return indexOfTab("Welcome") > -1; |
| } |
| |
| /** |
| * Our custom implementation of inserting a new tab, |
| * this method ALWAYS inserts it at the front because |
| * we get an ArrayIndexOutOfBoundsException otherwise |
| * under some JDK implementations. |
| * <p> |
| * This method also causes a fireStateChange() to be |
| * called so that listeners get notified of the event. |
| * See the class level comments for the reason why... |
| * |
| * @param name |
| * @param component |
| */ |
| public void addANewTab(String name, JComponent component, Icon icon, boolean switchToTab) { |
| super.insertTab(name, icon, component, null, getTabCount()); |
| |
| super.fireStateChanged(); |
| if (!"chainsaw-log".equals(name) && switchToTab) { |
| EventQueue.invokeLater(() -> setSelectedTab(getTabCount() - 1)); |
| } |
| } |
| |
| public void setSelectedTab(int index) { |
| if (getTabCount() >= index) { |
| setSelectedIndex(index); |
| } |
| |
| getSelectedComponent().setVisible(true); |
| getSelectedComponent().validate(); |
| super.fireStateChanged(); |
| } |
| |
| public void addANewTab( |
| String name, JComponent component, Icon icon, String tooltip) { |
| super.insertTab(name, icon, component, tooltip, getTabCount()); |
| super.fireStateChanged(); |
| } |
| |
| public void remove(Component component) { |
| super.remove(component); |
| super.fireStateChanged(); |
| } |
| |
| /** |
| * Saves the state of the currently active tabs to an XML file. |
| * Only considers the Welcome, Drag and Drop and chainsaw-log |
| * panels as they are the panel which are always running. Saves |
| * whether they are hidden or not.... |
| */ |
| public void saveSettings(SaveSettingsEvent event) { |
| File file = new File(SettingsManager.getSettingsDirectory(), "tab-settings.json"); |
| |
| int count = super.getTabCount(); |
| String title; |
| |
| SavableTabSetting setting = new SavableTabSetting(); |
| for (int i = 0; i < count; i++) { |
| title = super.getTitleAt(i); |
| switch (title) { |
| case WELCOME_TAB: |
| setting.setWelcome(true); |
| break; |
| case "chainsaw-log": |
| setting.setChainsawLog(true); |
| break; |
| case ZEROCONF: |
| setting.setZeroconf(true); |
| break; |
| } |
| } |
| |
| Genson genson = new Genson(); |
| String serialize = genson.serialize(setting); |
| |
| try (FileWriter writer = new FileWriter(file)) { |
| writer.write(serialize); |
| } catch (Exception e) { |
| logger.error("Could not write to tab-settings.json", e); |
| try { |
| Files.deleteIfExists(file.toPath()); |
| } catch (IOException ex) { |
| logger.error("Could not clean up file tab-settings.json", ex); |
| } |
| } |
| } |
| |
| /** |
| * Loads the saved tab setting by reading the XML file. |
| * If the file doesn't exist, all three panels should be |
| * shown as the default setting.... |
| */ |
| |
| public void loadSettings(LoadSettingsEvent event) { |
| File file = new File(SettingsManager.getSettingsDirectory(), "tab-settings.json"); |
| Genson genson = new Genson(); |
| |
| try { |
| if (file.exists()) { |
| String json = Files.readAllLines(file.toPath()).get(0); |
| tabSetting = genson.deserialize(json, SavableTabSetting.class); |
| } else { |
| tabSetting = new SavableTabSetting(); |
| tabSetting.setWelcome(true); |
| tabSetting.setChainsawLog(true); |
| tabSetting.setZeroconf(true); |
| } |
| } catch (Exception e) { |
| logger.error("Could not read from tab-settings.json", e); |
| try { |
| Files.deleteIfExists(file.toPath()); |
| } catch (IOException ex) { |
| logger.error("Could not clean up file tab-settings.json", ex); |
| } |
| } |
| } |
| } |