/* * Copyright (c) 2004-2007 by Michael Connor. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * o Neither the name of FormLayoutBuilder or Michael Connor nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * NewComponentDialog.java * * Created on March 24, 2005, 6:49 PM */ package org.mlc.swing.layout; import java.awt.Component; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.WindowConstants; import bsh.Interpreter; import com.jgoodies.forms.factories.Borders; import com.jgoodies.forms.factories.ButtonBarFactory; /** * When performing drag-and-drop from the component palette to the table, * this class is used to define or edit a component's settings. These * settings include the import, declaration, configuration lines which * will be used to generate the code for the component. The same settings * are used to create a 'preview' component to be shown in the preview * window. * * @author Michael Connor @version $Id$ @since Ptolemy II 7.1 */ @SuppressWarnings("serial") public class NewComponentDialog extends JPanel { JLabel componentNameLabel = new JLabel("Name"); JTextField componentNameTextField = new JTextField(); JLabel importsLabel = new JLabel("Imports"); JTextArea importsComponent = createTextArea(3, 40); JLabel declarationsLabel = new JLabel("Declarations"); JTextArea declarationsComponent = createTextArea(3, 40); JLabel configureLabel = new JLabel("Configure"); JTextArea configureComponent = createTextArea(4, 40); JLabel addToContainerLabel = new JLabel("Add"); JTextArea addToContainerComponent = createTextArea(3, 40); JLabel removeFromContainerLabel = new JLabel("Remove"); JTextArea removeFromContainerComponent = createTextArea(2, 40); JLabel previewLabel = new JLabel("Preview"); JScrollPane previewComponent = new JScrollPane(); JButton prevButton = new JButton("Preview"); JButton okButton = new JButton("OK"); JButton cancelButton = new JButton("Cancel"); Component buttonBar = ButtonBarFactory.buildRightAlignedBar(new JButton[] { prevButton, okButton, cancelButton }); ComponentDef componentDef; private String preview; Window myOwner; private boolean success = false; public boolean succeeded() { return success; } /** Creates a new instance of NewComponentDialog */ public NewComponentDialog(Window owner) { myOwner = owner; LayoutConstraintsManager layoutConstraintsManager = LayoutConstraintsManager .getLayoutConstraintsManager(this.getClass() .getResourceAsStream("editableLayoutConstraints.xml")); this.setBorder(Borders.DIALOG_BORDER); layoutConstraintsManager.setLayout("newComponentPanel", this); // here we add the controls to the container. you may // need to change the name of panel add(new JScrollPane(removeFromContainerComponent), "removeFromContainerComponent"); add(configureLabel, "configureLabel"); add(new JScrollPane(importsComponent), "importsComponent"); add(new JScrollPane(declarationsComponent), "declarationsComponent"); add(new JScrollPane(configureComponent), "configureComponent"); add(new JScrollPane(addToContainerComponent), "addToContainerComponent"); add(buttonBar, "buttonBar"); add(declarationsLabel, "declarationsLabel"); add(componentNameLabel, "componentNameLabel"); add(importsLabel, "importsLabel"); add(addToContainerLabel, "addToContainerLabel"); add(componentNameTextField, "componentNameTextField"); add(removeFromContainerLabel, "removeFromContainerLabel"); add(previewLabel, "previewLabel"); add(previewComponent, "previewComponent"); prevButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { doPreview(); } }); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { success = true; componentDef.add = getAdd(); componentDef.configure = getConfiguration(); componentDef.declarations = getDeclarations(); componentDef.name = componentNameTextField.getText().trim(); componentDef.imports = getImports(); UserPrefs.getPrefs().saveWinLoc("newcomp", myOwner); myOwner.setVisible(false); } }); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { success = false; UserPrefs.getPrefs().saveWinLoc("newcomp", myOwner); myOwner.setVisible(false); } }); } // class PreviewThread implements Runnable { // // boolean running = true; // // public void run() { // while (running) { // } // } // } /** Get an instance of the specified component. In FormLayoutMaker, this instance is placed in the preview panel. <p> For example, if the component is a JButton, this method is the equivalent of <code>new JButton(<i>text</i>)</code>. @return Component An instance of the component, null if there is a problem in the specification. [It is recommended that the 'Preview' button should be clicked before exiting the dialog.] */ public Component getInstance() { Component component = null; String script; if (preview == null || preview.length() == 0) { script = getImports() + "\n" + getDeclarations() + "\n" + getConfiguration(); } else { script = preview.trim(); } String componentName = componentNameTextField.getText(); script = script.replaceAll("\\$\\{name\\}", componentName); Interpreter interpreter = new Interpreter(); interpreter.setStrictJava(true); JPanel temporaryContainer = null; try { interpreter.set("container", temporaryContainer); interpreter.eval(script); component = (Component) interpreter.get(componentName); } catch (bsh.EvalError error) { System.out.println(error); } return component; } private void doPreview() { Component component = getInstance(); if (component == null) { return; } JPanel temporaryContainer = new JPanel(); temporaryContainer.add(component); if (temporaryContainer != null) { previewComponent.setViewportView(temporaryContainer); } } /** Get the component's name */ public String getComponentName() { return componentNameTextField.getText(); } public void setComponentName(String componentName) { componentNameTextField.setText(componentName); } /** Get the component's <imports> section. */ public String getImports() { return importsComponent.getText().trim(); } /** Get the component's <declarations> section. */ public String getDeclarations() { return declarationsComponent.getText().trim(); } /** Get the component's <configuration> section. */ public String getConfiguration() { return configureComponent.getText().trim(); } public String getAdd() { String res = addToContainerComponent.getText(); return cleanString(res); } public void setRemove(String remove) { removeFromContainerComponent.setText(remove); } public void setComponentDef(ComponentDef componentDef) { editComponentDef(componentDef.clone()); } public void editComponentDef(ComponentDef componentDef) { this.componentDef = componentDef; importsComponent.setText(cleanString(componentDef.imports)); declarationsComponent.setText(cleanString(componentDef.declarations)); configureComponent.setText(cleanString(componentDef.configure)); addToContainerComponent.setText(cleanString(componentDef.add)); removeFromContainerComponent.setText(cleanString(componentDef.remove)); preview = cleanString(componentDef.preview); } /** Cleans a string. Removes extra newlines. * * @param instr * @return A clean string. */ private String cleanString(String instr) { if (instr == null) { return instr; } // Java 1.5 library method // while ( res.contains("\n\n") ) // KBR 09/05/05 Reworked to deal with leading space for multiline // sections. String[] outstrs = instr.split("\n"); String outstr = ""; for (int i = 0; i < outstrs.length; i++) { String tmp = outstrs[i].trim(); outstr += tmp + (tmp.length() > 0 ? "\n" : ""); } return outstr; } private static JTextArea createTextArea(int rows, int cols) { JTextArea textArea = new JTextArea(rows, cols); //KBR linewrap makes longer sections hard to work with // textArea.setWrapStyleWord(true); // textArea.setLineWrap(true); return textArea; } /** * Creates and displays a dialog for editing a component's settings. See * {@link #doDialog(JFrame,ComponentDef)} for an example. */ public static NewComponentDialog editDialog(JFrame owner, ComponentDef componentDef) { JDialog dlg = new JDialog(owner, "Edit Component", true); UserPrefs.getPrefs().useSavedBounds("newcomp", dlg); dlg.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); NewComponentDialog panel = new NewComponentDialog(dlg); panel.editComponentDef(componentDef); panel.setComponentName(componentDef.name); dlg.getContentPane().add(panel); dlg.pack(); dlg.setVisible(true); return panel; } /** * Creates and displays a dialog for defining a new component's settings. The dialog should be used as follows: <code> NewComponentDialog dlg = NewComponentDialog.doDialog(frame, componentDef); if (dlg.succeeded()) { [do something with dlg.componentDef] } <code> */ public static NewComponentDialog doDialog(JFrame owner, ComponentDef componentDef) { JDialog dlg = new JDialog(owner, "New Component", true); UserPrefs.getPrefs().useSavedBounds("newcomp", dlg); dlg.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); NewComponentDialog panel = new NewComponentDialog(dlg); panel.setComponentDef(componentDef); panel.setComponentName("untitled"); dlg.getContentPane().add(panel); dlg.pack(); dlg.setVisible(true); return panel; } /** Unit testing. */ public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); NewComponentDialog dialog = new NewComponentDialog(frame); ComponentDef componentDef = new ComponentDef(); componentDef.imports = "import javax.swing.JLabel;"; componentDef.declarations = "JLabel ${name} = new JLabel(\"Hello World\");"; componentDef.configure = ""; componentDef.add = "${container}.add(${name}, \"${name}\");"; componentDef.remove = "${container}.remove($name);"; dialog.setComponentName("untitled"); dialog.setComponentDef(componentDef); frame.getContentPane().add(dialog); frame.pack(); frame.setVisible(true); } }