📄 genericobjecteditor.java
字号:
/* * 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 2 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * GenericObjectEditor.java * Copyright (C) 2002 Len Trigg, Xin Xu, Richard Kirkby * */package weka.gui;import weka.gui.PropertySheetPanel;import weka.gui.SelectedTagEditor;import weka.gui.FileEditor;import weka.gui.PropertyDialog;import weka.core.OptionHandler;import weka.core.Utils;import weka.core.Tag;import weka.core.SelectedTag;import weka.core.SerializedObject;import weka.core.Utils;import java.awt.BorderLayout;import java.awt.Component;import java.awt.Dimension;import java.awt.FontMetrics;import java.awt.GridLayout;import java.awt.Window;import java.awt.Frame;import java.awt.event.MouseEvent;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeSupport;import java.beans.PropertyEditor;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.Properties;import java.util.StringTokenizer;import java.util.Vector;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JMenuBar;import javax.swing.JMenu;import javax.swing.JMenuItem;import javax.swing.JPopupMenu;import javax.swing.event.MenuListener;import javax.swing.event.MenuEvent;import javax.swing.event.MouseInputAdapter;import javax.swing.JTree;import javax.swing.tree.TreeSelectionModel;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.TreePath;import javax.swing.event.TreeExpansionListener;import javax.swing.event.TreeExpansionEvent;import javax.swing.event.TreeSelectionListener;import javax.swing.event.TreeSelectionEvent;/** * A PropertyEditor for objects that themselves have been defined as * editable in the GenericObjectEditor configuration file, which lists * possible values that can be selected from, and themselves configured. * The configuration file is called "GenericObjectEditor.props" and * may live in either the location given by "user.home" or the current * directory (this last will take precedence), and a default properties * file is read from the weka distribution. For speed, the properties * file is read only once when the class is first loaded -- this may need * to be changed if we ever end up running in a Java OS ;-). * * @author Len Trigg (trigg@cs.waikato.ac.nz) * @author Xin Xu (xx5@cs.waikato.ac.nz) * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 1.1.1.1 $ */public class GenericObjectEditor implements PropertyEditor, CustomPanelSupplier { /** The object being configured */ protected Object m_Object; /** Holds a copy of the current object that can be reverted to if the user decides to cancel */ protected Object m_Backup; /** Handles property change notification */ protected PropertyChangeSupport m_Support = new PropertyChangeSupport(this); /** The Class of objects being edited */ protected Class m_ClassType; /** The model containing the list of names to select from */ protected HierarchyPropertyParser m_ObjectNames; /** The GUI component for editing values, created when needed */ protected GOEPanel m_EditorComponent; /** True if the GUI component is needed */ protected boolean m_Enabled = true; /** The name of the properties file */ protected static String PROPERTY_FILE = "weka/gui/GenericObjectEditor.props"; /** Contains the editor properties */ protected static Properties EDITOR_PROPERTIES; /** The tree node of the current object so we can re-select it for the user */ protected DefaultMutableTreeNode m_treeNodeOfCurrentObject; /** The property panel created for the objects */ protected PropertyPanel m_ObjectPropertyPanel; protected boolean m_canChangeClassInDialog; /** Loads the configuration property file */ static { // Allow a properties file in the current directory to override try { EDITOR_PROPERTIES = Utils.readProperties(PROPERTY_FILE); java.util.Enumeration keys = (java.util.Enumeration)EDITOR_PROPERTIES.propertyNames(); if (!keys.hasMoreElements()) { throw new Exception("Failed to read a property file for the " +"generic object editor"); } } catch (Exception ex) { JOptionPane.showMessageDialog(null, "Could not read a configuration file for the generic object\n" +"editor. An example file is included with the Weka distribution.\n" +"This file should be named \"" + PROPERTY_FILE + "\" and\n" +"should be placed either in your user home (which is set\n" + "to \"" + System.getProperties().getProperty("user.home") + "\")\n" + "or the directory that java was started from\n", "GenericObjectEditor", JOptionPane.ERROR_MESSAGE); } } /** * Creates a popup menu containing a tree that is aware * of the screen dimensions. */ public class JTreePopupMenu extends JPopupMenu { /** The tree */ JTree m_tree; /** The scroller */ JScrollPane m_scroller; /** * Constructs a new popup menu. * * @param tree the tree to put in the menu */ public JTreePopupMenu(JTree tree) { m_tree = tree; JPanel treeView = new JPanel(); treeView.setLayout(new BorderLayout()); treeView.add(m_tree, BorderLayout.NORTH); m_scroller = new JScrollPane(treeView); m_scroller.setPreferredSize(new Dimension(300, 400)); add(m_scroller); } /** * Displays the menu, making sure it will fit on the screen. * * @param invoker the component thast invoked the menu * @param x the x location of the popup * @param y the y location of the popup */ public void show(Component invoker, int x, int y) { super.show(invoker, x, y); // calculate available screen area for popup java.awt.Point location = getLocationOnScreen(); java.awt.Dimension screenSize = getToolkit().getScreenSize(); int maxWidth = (int) (screenSize.getWidth() - location.getX()); int maxHeight = (int) (screenSize.getHeight() - location.getY()); // if the part of the popup goes off the screen then resize it Dimension scrollerSize = m_scroller.getPreferredSize(); int height = (int) scrollerSize.getHeight(); int width = (int) scrollerSize.getWidth(); if (width > maxWidth) width = maxWidth; if (height > maxHeight) height = maxHeight; // commit any size changes m_scroller.setPreferredSize(new Dimension(width, height)); revalidate(); pack(); } } /** * Handles the GUI side of editing values. */ public class GOEPanel extends JPanel { /** The component that performs classifier customization */ protected PropertySheetPanel m_ChildPropertySheet; /** The name of the current class */ protected JLabel m_ClassNameLabel; /** Open object from disk */ protected JButton m_OpenBut; /** Save object to disk */ protected JButton m_SaveBut; /** ok button */ protected JButton m_okBut; /** cancel button */ protected JButton m_cancelBut; /** The filechooser for opening and saving object files */ protected JFileChooser m_FileChooser; /** Creates the GUI editor component */ public GOEPanel() { m_Backup = copyObject(m_Object); m_ClassNameLabel = new JLabel("None"); m_ClassNameLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); m_ChildPropertySheet = new PropertySheetPanel(); m_ChildPropertySheet.addPropertyChangeListener (new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { m_Support.firePropertyChange("", null, null); } }); m_OpenBut = new JButton("Open..."); m_OpenBut.setToolTipText("Load a configured object"); m_OpenBut.setEnabled(true); m_OpenBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Object object = openObject(); if (object != null) { // setValue takes care of: Making sure obj is of right type, // and firing property change. setValue(object); // Need a second setValue to get property values filled in OK. // Not sure why. setValue(object); } } }); m_SaveBut = new JButton("Save..."); m_SaveBut.setToolTipText("Save the current configured object"); m_SaveBut.setEnabled(true); m_SaveBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { saveObject(m_Object); } }); m_okBut = new JButton("OK"); m_okBut.setEnabled(true); m_okBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { m_Backup = copyObject(m_Object); if ((getTopLevelAncestor() != null) && (getTopLevelAncestor() instanceof Window)) { Window w = (Window) getTopLevelAncestor(); w.dispose(); } } }); m_cancelBut = new JButton("Cancel"); m_cancelBut.setEnabled(true); m_cancelBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (m_Backup != null) { m_Object = copyObject(m_Backup); // To fire property change m_Support.firePropertyChange("", null, null); m_ObjectNames = getClassesFromProperties(); updateObjectNames(); updateChildPropertySheet(); } if ((getTopLevelAncestor() != null) && (getTopLevelAncestor() instanceof Window)) { Window w = (Window) getTopLevelAncestor(); w.dispose(); } } }); setLayout(new BorderLayout()); if (m_canChangeClassInDialog) { JButton chooseButton = createChooseClassButton(); JPanel top = new JPanel(); top.setLayout(new BorderLayout()); top.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); top.add(chooseButton, BorderLayout.WEST); top.add(m_ClassNameLabel, BorderLayout.CENTER); add(top, BorderLayout.NORTH); } else { add(m_ClassNameLabel, BorderLayout.NORTH); } add(m_ChildPropertySheet, BorderLayout.CENTER); // Since we resize to the size of the property sheet, a scrollpane isn't // typically needed // add(new JScrollPane(m_ChildPropertySheet), BorderLayout.CENTER); JPanel okcButs = new JPanel(); okcButs.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); okcButs.setLayout(new GridLayout(1, 4, 5, 5)); okcButs.add(m_OpenBut); okcButs.add(m_SaveBut); okcButs.add(m_okBut); okcButs.add(m_cancelBut); add(okcButs, BorderLayout.SOUTH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -