2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
* Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
26
import weka.core.ClassDiscovery;
27
import weka.core.OptionHandler;
28
import weka.core.Utils;
30
import java.awt.BorderLayout;
31
import java.awt.Component;
32
import java.awt.Dimension;
33
import java.awt.Graphics;
34
import java.awt.Insets;
35
import java.awt.Rectangle;
36
import java.awt.Toolkit;
37
import java.awt.datatransfer.Clipboard;
38
import java.awt.datatransfer.StringSelection;
39
import java.awt.event.ActionEvent;
40
import java.awt.event.ActionListener;
41
import java.awt.event.MouseAdapter;
42
import java.awt.event.MouseEvent;
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyEditor;
47
import javax.swing.BorderFactory;
48
import javax.swing.JOptionPane;
49
import javax.swing.JPanel;
50
import javax.swing.JPopupMenu;
51
import javax.swing.JMenuItem;
54
* Support for drawing a property value in a component.
56
* @author Len Trigg (trigg@cs.waikato.ac.nz)
57
* @author Richard Kirkby (rkirkby@cs.waikato.ac.nz)
58
* @version $Revision: 1.13 $
60
public class PropertyPanel
63
/** for serialization */
64
static final long serialVersionUID = 5370025273466728904L;
66
/** The property editor */
67
private PropertyEditor m_Editor;
69
/** The currently displayed property dialog, if any */
70
private PropertyDialog m_PD;
72
/** Whether the editor has provided its own panel */
73
private boolean m_HasCustomPanel = false;
76
* Create the panel with the supplied property editor.
78
* @param pe the PropertyEditor
80
public PropertyPanel(PropertyEditor pe) {
86
* Create the panel with the supplied property editor,
87
* optionally ignoring any custom panel the editor can provide.
89
* @param pe the PropertyEditor
90
* @param ignoreCustomPanel whether to make use of any available custom panel
92
public PropertyPanel(PropertyEditor pe, boolean ignoreCustomPanel) {
96
if (!ignoreCustomPanel && m_Editor instanceof CustomPanelSupplier) {
97
setLayout(new BorderLayout());
98
add(((CustomPanelSupplier)m_Editor).getCustomPanel(), BorderLayout.CENTER);
99
m_HasCustomPanel = true;
101
createDefaultPanel();
106
* Creates the default style of panel for editors that do not
109
protected void createDefaultPanel() {
111
setBorder(BorderFactory.createEtchedBorder());
112
setToolTipText("Left-click to edit properties for this object, right-click/Alt+Shift+left-click for menu");
114
final Component comp = this;
115
addMouseListener(new MouseAdapter() {
116
public void mouseClicked(MouseEvent evt) {
117
if (evt.getClickCount() == 1) {
118
if ( (evt.getButton() == MouseEvent.BUTTON1) && !evt.isAltDown() && !evt.isShiftDown() ) {
119
showPropertyDialog();
121
else if ( (evt.getButton() == MouseEvent.BUTTON3)
122
|| ((evt.getButton() == MouseEvent.BUTTON1) && evt.isAltDown() && evt.isShiftDown()) ) {
123
JPopupMenu menu = new JPopupMenu();
126
if (m_Editor.getValue() != null) {
127
item = new JMenuItem("Show properties...");
128
item.addActionListener(new ActionListener() {
129
public void actionPerformed(ActionEvent e) {
130
showPropertyDialog();
135
item = new JMenuItem("Copy configuration to clipboard");
136
item.addActionListener(new ActionListener() {
137
public void actionPerformed(ActionEvent e) {
138
String str = m_Editor.getValue().getClass().getName();
139
if (m_Editor.getValue() instanceof OptionHandler)
140
str += " " + Utils.joinOptions(((OptionHandler) m_Editor.getValue()).getOptions());
141
StringSelection selection = new StringSelection(str.trim());
142
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
143
clipboard.setContents(selection, selection);
149
item = new JMenuItem("Enter configuration...");
150
item.addActionListener(new ActionListener() {
151
public void actionPerformed(ActionEvent e) {
152
String str = JOptionPane.showInputDialog(
154
"Configuration (<classname> [<options>])");
157
String[] options = Utils.splitOptions(str);
158
String classname = options[0];
162
Object.class, classname, options));
164
catch (Exception ex) {
165
ex.printStackTrace();
166
JOptionPane.showMessageDialog(
168
"Error parsing commandline:\n" + ex,
170
JOptionPane.ERROR_MESSAGE);
177
menu.show(comp, evt.getX(), evt.getY());
182
Dimension newPref = getPreferredSize();
183
newPref.height = getFontMetrics(getFont()).getHeight() * 5 / 4;
184
newPref.width = newPref.height * 5;
185
setPreferredSize(newPref);
187
m_Editor.addPropertyChangeListener(new PropertyChangeListener () {
188
public void propertyChange(PropertyChangeEvent evt) {
195
* Displays the property edit dialog for the panel.
197
public void showPropertyDialog() {
199
if (m_Editor.getValue() != null) {
201
int x = getLocationOnScreen().x;
202
int y = getLocationOnScreen().y;
203
m_PD = new PropertyDialog(m_Editor, x, y);
205
m_PD.setVisible(true);
207
// make sure that m_Backup is correctly initialized!
208
m_Editor.setValue(m_Editor.getValue());
213
* Cleans up when the panel is destroyed.
215
public void removeNotify() {
217
super.removeNotify();
225
* Paints the component, using the property editor's paint method.
227
* @param g the current graphics context
229
public void paintComponent(Graphics g) {
231
if (!m_HasCustomPanel) {
232
Insets i = getInsets();
233
Rectangle box = new Rectangle(i.left, i.top,
234
getSize().width - i.left - i.right - 1,
235
getSize().height - i.top - i.bottom - 1);
237
g.clearRect(i.left, i.top,
238
getSize().width - i.right - i.left,
239
getSize().height - i.bottom - i.top);
240
m_Editor.paintValue(g, box);