001: /*
002: * Copyright (C) 2005 Jeff Tassin
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package com.jeta.swingbuilder.gui.properties;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Component;
023: import java.awt.Dimension;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.beans.BeanDescriptor;
027:
028: import javax.swing.BorderFactory;
029: import javax.swing.JButton;
030: import javax.swing.JLabel;
031: import javax.swing.JPanel;
032: import javax.swing.JTabbedPane;
033: import javax.swing.JTextField;
034:
035: import com.jeta.forms.gui.beans.DynamicBeanInfo;
036: import com.jeta.forms.gui.beans.JETABean;
037: import com.jeta.forms.gui.form.GridCellEvent;
038: import com.jeta.forms.gui.form.GridComponent;
039: import com.jeta.forms.gui.form.GridViewEvent;
040: import com.jeta.forms.gui.form.GridViewListener;
041: import com.jeta.forms.logger.FormsLogger;
042: import com.jeta.open.gui.framework.JETADialog;
043: import com.jeta.open.gui.framework.JETAPanel;
044: import com.jeta.open.gui.utils.JETAToolbox;
045: import com.jeta.open.i18n.I18N;
046: import com.jeta.swingbuilder.gui.utils.FormDesignerUtils;
047: import com.jeta.swingbuilder.resources.Icons;
048: import com.jgoodies.forms.layout.CellConstraints;
049: import com.jgoodies.forms.layout.FormLayout;
050:
051: /**
052: * The container for the property pane
053: *
054: * @author Jeff Tassin
055: */
056: public class PropertyPaneContainer extends JETAPanel implements
057: GridViewListener, PropertyEditorListener {
058: /**
059: * The main view for our frame
060: */
061: private PropertyPane m_advview;
062:
063: private PropertyPane m_basicview;
064:
065: private PropertyPane m_activeview;
066:
067: /**
068: * The current grid component that is visible in the property pane.
069: */
070: private GridComponent m_current_comp;
071:
072: private JTabbedPane m_tabpane;
073:
074: /**
075: * Displays the component name for the current bean
076: */
077: private JTextField m_name_field;
078:
079: /**
080: * Displays the classname for the current bean
081: */
082: private JTextField m_class_field;
083:
084: /**
085: * Button for launching the customizer dialog for a Java Bean - if that Java
086: * Bean has a customizer
087: */
088: private JButton m_customizer_btn;
089:
090: /**
091: * @param model
092: */
093: public PropertyPaneContainer() {
094: setLayout(new BorderLayout());
095: add(createView(), BorderLayout.CENTER);
096: }
097:
098: /**
099: * @param model
100: * @return
101: */
102: private void createTabPane() {
103: m_basicview = new PropertyPane(true);
104: m_activeview = m_basicview;
105: PropertyTableModel tmodel = m_basicview.getTableModel();
106: tmodel.addPropertyListener(this );
107:
108: m_advview = new PropertyPane(false);
109: tmodel = m_advview.getTableModel();
110: tmodel.addPropertyListener(this );
111:
112: m_tabpane = new JTabbedPane();
113: m_tabpane
114: .addTab(I18N.getLocalizedMessage("Basic"), m_basicview);
115: m_tabpane.addTab(I18N.getLocalizedMessage("All"), m_advview);
116: m_tabpane
117: .addChangeListener(new javax.swing.event.ChangeListener() {
118: public void stateChanged(
119: javax.swing.event.ChangeEvent e) {
120: PropertyPane ppane = getActiveView();
121: ppane.setBean(getBean());
122: }
123: });
124: }
125:
126: /**
127: * Top panel that displays the name and class of the current bean
128: */
129: private JPanel createNamePanel() {
130: JPanel panel = new JPanel();
131: FormLayout layout = new FormLayout("pref,2dlu,pref:grow",
132: "pref,2dlu,pref,4dlu");
133: panel.setLayout(layout);
134: CellConstraints cc = new CellConstraints();
135:
136: panel.add(new JLabel(I18N.getLocalizedDialogLabel("Name")), cc
137: .xy(1, 1));
138: m_name_field = new JTextField();
139: m_name_field.setEnabled(false);
140: panel.add(m_name_field, cc.xy(3, 1));
141:
142: panel.add(
143: new JLabel(I18N.getLocalizedDialogLabel("Component")),
144: cc.xy(1, 3));
145:
146: layout = new FormLayout("d:grow,24px", "fill:pref");
147: m_class_field = new JTextField();
148: m_class_field.setEditable(false);
149: JPanel cpanel = new JPanel(layout);
150:
151: m_customizer_btn = new JButton(FormDesignerUtils
152: .loadImage(Icons.EDIT_16));
153: m_customizer_btn
154: .setPreferredSize(new java.awt.Dimension(24, 16));
155: m_customizer_btn.addActionListener(new ActionListener() {
156: public void actionPerformed(ActionEvent evt) {
157: showCustomizerDialog();
158: }
159: });
160: m_customizer_btn.setToolTipText(I18N
161: .getLocalizedMessage("Bean Customizer"));
162: m_customizer_btn.setEnabled(false);
163:
164: cpanel.add(m_class_field, cc.xy(1, 1));
165: cpanel.add(m_customizer_btn, cc.xy(2, 1));
166:
167: panel.add(cpanel, cc.xy(3, 3));
168:
169: panel
170: .setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
171: 10));
172:
173: m_name_field.addActionListener(new ActionListener() {
174: public void actionPerformed(ActionEvent evt) {
175: updateBeanName();
176: }
177: });
178:
179: return panel;
180: }
181:
182: /**
183: * @param model
184: * @return
185: */
186: private Component createView() {
187: JPanel panel = new JPanel(new BorderLayout());
188: createTabPane();
189: panel.add(createNamePanel(), BorderLayout.NORTH);
190: panel.add(m_tabpane, BorderLayout.CENTER);
191: return panel;
192: }
193:
194: PropertyPane getActiveView() {
195: return (PropertyPane) m_tabpane.getSelectedComponent();
196: }
197:
198: JETABean getBean() {
199: if (m_current_comp == null)
200: return null;
201: return m_current_comp.getBean();
202: }
203:
204: /**
205: * @return the customizer for the current bean. Null is returned if the bean
206: * does not have a customizer.
207: */
208: private Class getCustomizer() {
209: JETABean bean = getBean();
210: if (bean != null) {
211: DynamicBeanInfo beaninfo = bean.getBeanInfo();
212: if (beaninfo != null) {
213: BeanDescriptor bd = beaninfo.getBeanDescriptor();
214: if (bd != null) {
215: return bd.getCustomizerClass();
216: }
217: }
218: }
219: return null;
220: }
221:
222: public Dimension getMinimumSize() {
223: return new Dimension(24, 24);
224: }
225:
226: /** GridViewListener implementation */
227: public void gridChanged(GridViewEvent evt) {
228: /**
229: * Handle case where the user has changed the bean name in the editor.
230: * We need to update the name field in this case.
231: */
232: if (GridCellEvent.COMPONENT_NAME_CHANGED.equals(evt
233: .getCommand())) {
234: GridComponent comp = evt.getComponent();
235: if (comp == m_current_comp) {
236: JETABean bean = comp.getBean();
237: updateNameField(bean == null ? "" : bean.getBeanName());
238: return;
239: }
240: }
241:
242: if (evt.getId() == GridViewEvent.EDIT_COMPONENT
243: || evt.getId() == GridViewEvent.CELL_SELECTED) {
244: GridComponent comp = evt.getComponent();
245: update(comp);
246: }
247:
248: }
249:
250: public void refreshView() {
251: getActiveView().cancelEditing();
252: getActiveView().getTableModel().fireTableDataChanged();
253: }
254:
255: /**
256: * Stops any editing in the property table
257: */
258: public void stopEditing() {
259: getActiveView().stopEditing();
260: updateBeanName();
261: }
262:
263: public void update(GridComponent comp) {
264: /**
265: * Handle the case where the user has typed a new name in the
266: * name_field. If the user then clicks on a different component in the
267: * editor, we want to update the name of the current component before
268: * doing anything else.
269: */
270: if (comp != m_current_comp) {
271: updateBeanName();
272: }
273:
274: m_current_comp = comp;
275: if (comp != null) {
276: JETABean bean = comp.getBean();
277: getActiveView().setBean(bean);
278:
279: if (bean == null) {
280: updateNameField(null);
281: m_class_field.setText("");
282: m_class_field.setToolTipText("");
283: } else {
284:
285: updateNameField(bean.getBeanName());
286: if (bean.getDelegate() != null) {
287: String classname = bean.getDelegate().getClass()
288: .getName();
289: m_class_field.setToolTipText(classname);
290:
291: int pos = classname.lastIndexOf(".");
292: if (pos >= 0) {
293: classname = classname.substring(pos + 1,
294: classname.length());
295: }
296: m_class_field.setText(classname);
297: }
298: }
299: } else {
300: updateNameField(null);
301: getActiveView().setBean(null);
302: }
303: m_customizer_btn.setEnabled(getCustomizer() != null);
304: }
305:
306: /**
307: * PropertyEditorListener Implementation
308: */
309: public void propertyChanged(PropertyEditorEvent evt) {
310: JETABean bean = getBean();
311: if (m_current_comp != null && evt.getBean() == bean) {
312: m_current_comp.fireGridCellEvent(new GridCellEvent(
313: GridCellEvent.CELL_CHANGED, m_current_comp));
314: }
315:
316: if (bean == null) {
317: updateNameField(null);
318: } else {
319: updateNameField(bean.getBeanName());
320: }
321: }
322:
323: /**
324: * Shows the customizerDialog for a java bean
325: */
326: private void showCustomizerDialog() {
327: try {
328: stopEditing();
329: Class ccustomizer = getCustomizer();
330: if (ccustomizer != null) {
331: Component comp = (Component) ccustomizer.newInstance();
332: JETAPanel panel = new JETAPanel(new BorderLayout());
333: panel.add(comp, BorderLayout.CENTER);
334: JETADialog dlg = (JETADialog) JETAToolbox.createDialog(
335: JETADialog.class, this , true);
336: dlg.setPrimaryPanel(panel);
337: dlg.setTitle(I18N
338: .getLocalizedMessage("Bean Customizer"));
339: Dimension sz = panel.getPreferredSize();
340: sz.width = Math.max(sz.width, 200);
341: sz.height = Math.max(sz.height, 75);
342: panel.setPreferredSize(sz);
343:
344: dlg.setSize(dlg.getPreferredSize());
345:
346: java.beans.Customizer custom = (java.beans.Customizer) comp;
347: custom.setObject(getBean().getDelegate());
348: custom
349: .addPropertyChangeListener(new java.beans.PropertyChangeListener() {
350: public void propertyChange(
351: java.beans.PropertyChangeEvent evt) {
352: m_current_comp
353: .fireGridCellEvent(new GridCellEvent(
354: GridCellEvent.CELL_CHANGED,
355: m_current_comp));
356: }
357: });
358: dlg.showCenter();
359: if (dlg.isOk()) {
360: m_current_comp
361: .fireGridCellEvent(new GridCellEvent(
362: GridCellEvent.CELL_CHANGED,
363: m_current_comp));
364: refreshView();
365: }
366: }
367: } catch (Exception e) {
368: FormsLogger.severe(e);
369: }
370: }
371:
372: /**
373: * Updates the name of the bean using the value entered in the name field
374: */
375: public void updateBeanName() {
376: updateBeanName(getBean());
377: }
378:
379: /**
380: * Updates the name of the bean using the value entered in the name field
381: */
382: private void updateBeanName(JETABean bean) {
383: if (bean != null) {
384: Component comp = bean.getDelegate();
385: if (comp != null) {
386: String bname = FormDesignerUtils.fastTrim(m_name_field
387: .getText());
388: if (!bname.equals(comp.getName()))
389: comp.setName(bname);
390: }
391: }
392: }
393:
394: private void updateNameField(String beanName) {
395: if (beanName == null) {
396: m_name_field.setText("");
397: m_name_field.setEnabled(false);
398: } else {
399: m_name_field.setText(beanName);
400: m_name_field.setEnabled(true);
401: }
402: }
403:
404: }
|