All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.ui.OptionsDialog Maven / Gradle / Ivy

/*
 * 02/27/2004
 *
 * OptionsDialog.java - Generic dialog for displaying options you can change in
 * an application, similar to those found in many Microsoft Windows apps.
 * Copyright (C) 2004 Robert Futrell
 * http://fifesoft.com/rtext
 * Licensed under a modified BSD license.
 * See the included license file for details.
 */
package org.fife.ui;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Enumeration;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.JTextComponent;
import javax.swing.tree.*;


/**
 * An options dialog similar to those found in many Microsoft Windows
 * applications.  An OptionsDialog contains a list on its left-hand
 * side containing options categories; clicking on a category displays all
 * options related to that category.

* * Using this class along with {@link OptionsDialogPanel} will provide you * with a framework for creating an Options dialog with error checking and * instant-Apply functionality. * * @author Robert Futrell * @version 0.8 * @see org.fife.ui.OptionsDialogPanel */ public class OptionsDialog extends EscapableDialog implements ActionListener, TreeSelectionListener, PropertyChangeListener { /** * The panels the use can display. */ private OptionsDialogPanel[] optionsPanels; private JTree optionTree; private DefaultTreeModel treeModel; private DefaultMutableTreeNode root; private JScrollPane optionTreeScrollPane; private JButton okButton; private JButton applyButton; private JButton cancelButton; private JPanel currentOptionPanel; private CardLayout currentOptionPanelLayout; private TitledPanel titledPanel; /** * Creates a new options dialog with no options panels. * * @param owner The parent of this dialog. */ public OptionsDialog(Frame owner) { this(owner, new OptionsDialogPanel[0]); } /** * Creates a new options dialog with the specified array of option * panels. * * @param owner The parent of this dialog. * @param optionsPanels The option panels to add to this options dialog. * Note that this array MUST have at least one panel in it; * otherwise, this constructor will throw a * NullPointerException. * @see OptionsDialogPanel */ public OptionsDialog(Frame owner, OptionsDialogPanel[] optionsPanels) { super(owner); ComponentOrientation orientation = ComponentOrientation. getOrientation(getLocale()); ResourceBundle msg = ResourceBundle.getBundle("org.fife.ui.UI"); // Create the options tree and its scroll pane. root = new DefaultMutableTreeNode(msg.getString("Options")); treeModel = new DefaultTreeModel(root); optionTree = new JTree(treeModel) { public void updateUI() { super.updateUI(); // Must set new cell renderer each time lnf changes as // DefaultTreeCellRenderer is "buggy" in that it caches // colors, fonts, icons, etc. setCellRenderer(createTreeCellRenderer()); } }; optionTree.setSelectionModel(new RTreeSelectionModel()); optionTree.setCellRenderer(createTreeCellRenderer()); optionTree.setShowsRootHandles(true); optionTree.setRootVisible(false); //optionTree.setSelectionRow(0); // Must call this later. optionTree.addTreeSelectionListener(this); optionTreeScrollPane = new RScrollPane(optionTree); optionTreeScrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); JPanel indexPanel = new JPanel(new GridLayout(1,1)); indexPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,5)); indexPanel.add(optionTreeScrollPane); // Create a panel to hold the current options panel. currentOptionPanelLayout = new CardLayout(); currentOptionPanel = new JPanel(currentOptionPanelLayout); setOptionsPanels(optionsPanels); // Create a panel with buttons. JPanel buttonPanel = new JPanel(); buttonPanel.setBorder(new BevelDividerBorder(SwingConstants.TOP, 15)); JPanel temp = new JPanel(new GridLayout(1,3, 5,0)); okButton = new JButton(msg.getString("OK")); okButton.setActionCommand("OK"); okButton.addActionListener(this); cancelButton = new JButton(msg.getString("Cancel")); cancelButton.setActionCommand("Cancel"); cancelButton.addActionListener(this); applyButton = new JButton(msg.getString("Apply")); applyButton.setActionCommand("Apply"); applyButton.addActionListener(this); applyButton.setEnabled(false); // Until they make a change. temp.add(okButton); temp.add(cancelButton); temp.add(applyButton); buttonPanel.add(temp); // Create a panel containing the two above panels. JPanel rightPanel = new JPanel(); rightPanel.setLayout(new BorderLayout()); titledPanel = new TitledPanel("Temporary", currentOptionPanel, TitledPanel.LINE_BORDER); titledPanel.setBorder(UIUtil.getEmpty5Border()); rightPanel.add(titledPanel); rightPanel.add(buttonPanel, BorderLayout.SOUTH); // Put everything into a neat little package. JPanel contentPane =new ResizableFrameContentPane(new BorderLayout()); contentPane.setBorder(UIUtil.getEmpty5Border()); contentPane.add(indexPanel, BorderLayout.LINE_START); contentPane.add(rightPanel); setContentPane(contentPane); getRootPane().setDefaultButton(okButton); setTitle(msg.getString("Options")); setModal(true); applyComponentOrientation(orientation); pack(); } /** * Listens for action events in this dialog. */ public void actionPerformed(ActionEvent e) { String actionCommand = e.getActionCommand(); if (actionCommand.equals("Cancel")) { this.setVisible(false); } else if (actionCommand.equals("OK")) { boolean result = doApply((Frame)getParent()); if (result==true) this.setVisible(false); } else if (actionCommand.equals("Apply")) { doApply((Frame)getParent()); } } /** * Adds an options panel, and any child panels, to this options dialog. * * @param panel The options panel to add. */ private void addOptionPanel(OptionsDialogPanel panel) { panel.addPropertyChangeListener(this); currentOptionPanel.add(panel, createKeyForPanel(panel)); for (int i=0; iensureValidInputs on all option panels; then it actually * applies the changes to the application. If all inputs were valid, then * the Apply button is disabled and the "unsaved changes" flag for all * Options panels is cleared. If there was a problem in any of the * inputs, an error dialog is displayed. * * @param owner The parent frame that was specified in the constructor. * @return true if all options checked out okay and the apply * was successful; false if at least one option * wasn't valid (and thus the Options dialog needs to stay up). */ public final boolean doApply(Frame owner) { // Ensure that all of the changes specified are valid. If one isn't, // scold the user, shift focus to it and bail out. int numPanels = optionsPanels.length; for (int i=0; i0) optionTree.setSelectionRow(0); // Must do this so child nodes of (hidden) root are visible. optionTree.expandPath(new TreePath(root)); pack(); } /** * Selects the options panel with the specified name. * * @param name The name of the panel. * @return Whether the panel was selected. This will only be * false if name is not the name of an * options panel added to this dialog. */ public boolean setSelectedOptionsPanel(String name) { DefaultMutableTreeNode root = (DefaultMutableTreeNode)optionTree. getModel().getRoot(); return setSelectedOptionsPanelImpl(name, root); } /** * Makes the specified panel visible. * * @param panel The panel to make visible. * @param selectInTree Whether the tree node should be selected as well. * This is here so this method can be called in response to a tree * node being clicked, as well as other times (when the tree needs * to be updated as well as the panel). */ private void setSelectedOptionsPanel(OptionsDialogPanel panel, boolean selectInTree) { if (selectInTree) { // Select the proper node in the tree. It must be visible for this // to work, so we first expand all nodes. UIUtil.expandAllNodes(optionTree); for (int i=0; ioptionsPanels.length) panel = optionsPanels.length-1; // Show the next panel. if (currentPanel!=panel) { optionTree.setSelectionRow(panel); } */ } /** * This method is overridden to ensure that all nodes in the tree are * expanded (as if they're not, the size of the window and its widgets * may be incorrect; not enough room for the tree). * * @param visible Whether or not this dialog should be visible. */ public void setVisible(boolean visible) { if (visible) { UIUtil.expandAllNodes(optionTree); // Set the preferred size of the scroll pane so that it stays the // same size no matter what nodes they click on/hide. If we // don't do this, the JScrollPane resizes when you click on nodes // to show the entire displayed node - annoying! Dimension size = optionTree.getPreferredScrollableViewportSize(); size.width += 45; // Just in case a scrollbar is there. optionTreeScrollPane.setPreferredSize(size); pack(); } // Initially select the first node. int[] selectedRows = optionTree.getSelectionRows(); if (selectedRows==null || selectedRows.length==0) { optionTree.setSelectionRow(0); } super.setVisible(visible); } /** * Listens for the user to select values in the tree. */ public void valueChanged(TreeSelectionEvent e) { // Be careful and check for nulls as we support branch nodes not // actually containing an option panel. TreePath path = optionTree.getSelectionPath(); if (path==null) return; Object obj = path.getLastPathComponent(); if (obj==null) return; obj = ((DefaultMutableTreeNode)obj).getUserObject(); if (!(obj instanceof OptionsDialogPanel)) return; OptionsDialogPanel panel = (OptionsDialogPanel)obj; setSelectedOptionsPanel(panel, false); } /** * Renderer for the tree view. */ private static class OptionTreeCellRenderer extends DefaultTreeCellRenderer{ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean focused) { super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, focused); DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; Object obj = node.getUserObject(); if (obj instanceof OptionsDialogPanel) { OptionsDialogPanel panel = (OptionsDialogPanel)obj; setIcon(panel.getIcon()); } else { setIcon(null); } return this; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy