View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.log4j.chainsaw;
19  
20  import org.apache.log4j.chainsaw.helper.SwingHelper;
21  import org.apache.log4j.chainsaw.icons.ChainsawIcons;
22  
23  import javax.swing.*;
24  import javax.swing.tree.*;
25  import java.awt.*;
26  import java.awt.event.ActionListener;
27  import java.util.Enumeration;
28  import java.util.List;
29  
30  /**
31   * Some basic plumbing for Preference related dialogs.
32   *
33   * Sub classes have the following responsibilities:
34   *
35   * <ul>
36   * <li>Must call this this classes initComponents() method from
37   * within the sub-classes constructor, this method laysout the
38   * panel and calls the abstract createTreeModel method to initialise the
39   * tree of Panels.
40   * <li>Must override createTreeModel() method to return a TreeModel whose
41   * TreeNodes getUserObject() method will return a JComponent that is displayed
42   * as the selected editable Preference panel.  This JComponent's .toString() method is
43   * used as the title of the preference panel
44   * </ul>
45   *
46   * @author Paul Smith &lt;psmith@apache.org&gt;
47   */
48  public abstract class AbstractPreferencePanel extends JPanel {
49  
50      private final JLabel titleLabel = new JLabel("Selected Pref Panel");
51      private final JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
52      private final JPanel selectedPrefPanel = new JPanel(new BorderLayout(0, 3));
53      private final JButton okButton = new JButton(" OK ");
54      private final JButton cancelButton = new JButton(" Cancel ");
55      private ActionListener okCancelListener;
56      private Component currentlyDisplayedPanel = null;
57      private final JTree prefTree = new JTree();
58  
59      /**
60       * Setup and layout for the components
61       */
62      protected void initComponents() {
63          //		setBorder(BorderFactory.createLineBorder(Color.red));
64          setLayout(new BorderLayout(5, 5));
65          setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
66  
67          prefTree.setModel(createTreeModel());
68  
69          prefTree.setRootVisible(false);
70  
71          DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
72          renderer.setLeafIcon(ChainsawIcons.ICON_PREFERENCES);
73          prefTree.setCellRenderer(renderer);
74  
75          final JScrollPane treeScroll = new JScrollPane(prefTree);
76  
77          treeScroll.setPreferredSize(new Dimension(200, 240));
78  
79          titleLabel.setFont(titleLabel.getFont().deriveFont(16.0f));
80          titleLabel.setBorder(BorderFactory.createEtchedBorder());
81          titleLabel.setBackground(Color.white);
82          titleLabel.setOpaque(true);
83  
84          selectedPrefPanel.add(titleLabel, BorderLayout.NORTH);
85  
86          mainPanel.add(treeScroll, BorderLayout.WEST);
87          mainPanel.add(selectedPrefPanel, BorderLayout.CENTER);
88  
89          add(mainPanel, BorderLayout.CENTER);
90  
91          Box buttonBox = Box.createHorizontalBox();
92          List<JButton> buttons = SwingHelper.orderOKCancelButtons(okButton, cancelButton);
93          buttonBox.add(Box.createHorizontalGlue());
94          buttonBox.add(buttons.get(0));
95          buttonBox.add(Box.createHorizontalStrut(10));
96          buttonBox.add(buttons.get(1));
97  
98          add(buttonBox, BorderLayout.SOUTH);
99  
100         DefaultTreeSelectionModel treeSelectionModel =
101             new DefaultTreeSelectionModel();
102         treeSelectionModel.setSelectionMode(
103             TreeSelectionModel.SINGLE_TREE_SELECTION);
104         prefTree.setSelectionModel(treeSelectionModel);
105         prefTree.addTreeSelectionListener(
106             e -> {
107                 TreePath path = e.getNewLeadSelectionPath();
108                 DefaultMutableTreeNode node =
109                     (DefaultMutableTreeNode) path.getLastPathComponent();
110                 setDisplayedPrefPanel((JComponent) node.getUserObject());
111             });
112 
113         // ensure the first pref panel is selected and displayed
114         DefaultMutableTreeNode root =
115             (DefaultMutableTreeNode) prefTree.getModel().getRoot();
116         DefaultMutableTreeNode firstNode =
117             (DefaultMutableTreeNode) root.getFirstChild();
118         prefTree.setSelectionPath(new TreePath(firstNode.getPath()));
119     }
120 
121     /**
122      * @return tree model
123      */
124     protected abstract TreeModel createTreeModel();
125 
126     /**
127      * Ensures a specific panel is displayed in the spot where
128      * preferences can be selected.
129      *
130      * @param panel
131      */
132     protected void setDisplayedPrefPanel(JComponent panel) {
133         if (currentlyDisplayedPanel != null) {
134             selectedPrefPanel.remove(currentlyDisplayedPanel);
135         }
136 
137         selectedPrefPanel.add(panel, BorderLayout.CENTER);
138         currentlyDisplayedPanel = panel;
139         String title = panel.toString();
140         titleLabel.setText(title);
141         selectedPrefPanel.revalidate();
142         selectedPrefPanel.repaint();
143     }
144 
145     public void notifyOfLookAndFeelChange() {
146         SwingUtilities.updateComponentTreeUI(this);
147 
148         Enumeration enumeration = ((DefaultMutableTreeNode) prefTree.getModel().getRoot()).breadthFirstEnumeration();
149         while (enumeration.hasMoreElements()) {
150             DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
151             if (node.getUserObject() instanceof Component) {
152                 Component c = (Component) node.getUserObject();
153                 SwingUtilities.updateComponentTreeUI(c);
154             }
155         }
156     }
157 
158     public void setOkCancelActionListener(ActionListener l) {
159         this.okCancelListener = l;
160     }
161 
162     public void hidePanel() {
163         if (okCancelListener != null) {
164             okCancelListener.actionPerformed(null);
165         }
166     }
167 
168     /**
169      * @return Returns the cancelButton.
170      */
171     protected final JButton getCancelButton() {
172         return cancelButton;
173     }
174 
175     /**
176      * @return Returns the okButton.
177      */
178     protected final JButton getOkButton() {
179         return okButton;
180     }
181 }