Package org.openquark.gems.client.valueentry

Source Code of org.openquark.gems.client.valueentry.StringValueEditor$StringValueEditorProvider

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * 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.
*     * Neither the name of Business Objects 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.
*/


/*
* StringValueEditor.java
* Creation date: (02/03/01 10:20:15 AM)
* By: Michael Cheng
*/
package org.openquark.gems.client.valueentry;

import java.awt.Adjustable;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.KeyEvent;

import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.openquark.cal.valuenode.ListOfCharValueNode;
import org.openquark.cal.valuenode.ListValueNode;
import org.openquark.cal.valuenode.LiteralValueNode;
import org.openquark.cal.valuenode.ValueNode;


/**
* The ValueEditor used to edit the String type and the [Char] type.
* Creation date: (02/03/01 10:20:15 AM)
* @author Michael Cheng
*/
class StringValueEditor extends ValueEditor {

    private static final long serialVersionUID = 6253045166403650749L;

    /**
     * A custom value editor provider for the StringValueEditor.
     */
    public static class StringValueEditorProvider extends ValueEditorProvider<StringValueEditor> {

        public StringValueEditorProvider(ValueEditorManager valueEditorManager) {
            super(valueEditorManager);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean canHandleValue(ValueNode valueNode, SupportInfo providerSupportInfo) {
            return valueNode instanceof ListOfCharValueNode ||
                  (valueNode instanceof LiteralValueNode &&
                    valueNode.getTypeExpr().sameType(getValueEditorManager().getValueNodeBuilderHelper().getPreludeTypeConstants().getStringType()));
        }
       
        /**
         * @see org.openquark.gems.client.valueentry.ValueEditorProvider#getEditorInstance(ValueEditorHierarchyManager, ValueNode)
         */
        @Override
        public StringValueEditor getEditorInstance(ValueEditorHierarchyManager valueEditorHierarchyManager,
                                             ValueNode valueNode) {
           
            StringValueEditor editor = new StringValueEditor(valueEditorHierarchyManager);
            editor.setOwnerValueNode(valueNode);
            return editor;
        }
       
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean usableForOutput() {
            return true;
        }
    }

    /**
     * Very similar to ValueEditorKeyListener, with the exception that
     * Alt + Enter is required for a commit, instead of just Enter.
     */
    public class StringValueEditorKeyListener extends ValueEditorKeyListener {
        @Override
        public void keyPressed(KeyEvent evt) {

            if ((evt.getKeyCode() == KeyEvent.VK_ENTER) && evt.isAltDown()) {
                handleCommitGesture();
                evt.consume(); // Don't want the control with the focus to perform its action.

            } else if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) {
                handleCancelGesture();
                evt.consume();
            }
        }
    }

    /**
     * This listener grows the text field up to a maximum size
     * if the user enters additional text.
     */
    private class StringValueEditorDocumentListener implements DocumentListener {
       
        public void insertUpdate (DocumentEvent e) {
           
            // We can't resize the text are while the document insert hasn't completed.
            // Doing the resize at this time can cause problems with text layout for the area.
            // Therefore we invoke the resize once AWT events have finished processing.
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    resetSize();
                }
            });
        }

        public void changedUpdate (DocumentEvent e) {
        }
       
        public void removeUpdate (DocumentEvent e) {  
        }
    }
   
    /**
     * This constant is the maximum number of lines the editor will
     * display by default when first being shown and is also the maximum
     * number of lines it will grow to when the user enters text.
     */
    public static final int DEFAULT_MAXIMUM_LINES = 40;

    /** The default maximum width in pixels the editor will display or grow to. */
    public static final int DEFAULT_MAXIMUM_WIDTH = 600;

    /** True if the user manually resizes this editor. */
    private boolean userHasResized = false;

    /** The scroll pane that contains the text area. */
    private JScrollPane ivjJScrollPane1 = null;
   
    /** The text area for editing the text. */
    private JTextArea ivjTextArea = null;   
   
    /**
     * StringValueEditor constructor comment.
     * @param valueEditorHierarchyManager
     */
    protected StringValueEditor(ValueEditorHierarchyManager valueEditorHierarchyManager) {
        super(valueEditorHierarchyManager);
        initialize();
    }
   
    /**
     * {@inheritDoc}
     */
    @Override
    protected void commitValue() {

        String stringValue = getTextArea().getText();
        ValueNode valueNode = getValueNode();

        if (valueNode instanceof ListOfCharValueNode ||
            valueNode instanceof ListValueNode) {       // TEMP (?): Lists of Chars are collapsed to ListOfChars

            ValueNode returnVN = new ListOfCharValueNode(stringValue, getValueNode().getTypeExpr());
            replaceValueNode(returnVN, true);

        } else if (valueNode instanceof LiteralValueNode){
            ValueNode returnVN = new LiteralValueNode(stringValue, getValueNode().getTypeExpr());
            replaceValueNode(returnVN, true);

        } else {
            throw new IllegalStateException("This value node cannot be handled by the string editor: " + valueNode.getClass());
        }
       
        valueEditorManager.associateInfo(getOwnerValueNode(), new ValueEditor.Info(getSize()));

        notifyValueCommitted();
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public Component getDefaultFocusComponent() {
        return getTextArea();
    }

    /**
     * Return the JScrollPane1 property value.
     * @return JScrollPane
     */
    private JScrollPane getScrollPane() {
        if (ivjJScrollPane1 == null) {
            try {
                ivjJScrollPane1 = new JScrollPane();
                ivjJScrollPane1.setName("ScrollPane");
                ivjJScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
                ivjJScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
                getScrollPane().setViewportView(getTextArea());
            } catch (Throwable ivjExc) {
                handleException(ivjExc);
            }
        }
        return ivjJScrollPane1;
    }
   
    /**
     * Return the TextArea property value.
     * @return JTextArea
     */
    private JTextArea getTextArea() {
        if (ivjTextArea == null) {
            try {
                ivjTextArea = new JTextArea();
                ivjTextArea.setName("TextArea");
                ivjTextArea.setLineWrap(false);
                ivjTextArea.setWrapStyleWord(true);
                ivjTextArea.setBounds(0, 0, 160, 120);
            } catch (Throwable ivjExc) {
                handleException(ivjExc);
            }
        }
        return ivjTextArea;
    }
   
    /**
     * Called whenever the part throws an exception.
     * @param exception Throwable
     */
    private void handleException(Throwable exception) {

        /* Uncomment the following lines to print uncaught exceptions to stdout */
        System.out.println("--------- UNCAUGHT EXCEPTION ---------");
        exception.printStackTrace(System.out);
    }
   
    /**
     * Initialize the class.
     * Note: Extra Set-up Code has been added.
     */
    private void initialize() {
        try {
            setName("StringValueEditor");
            setLayout(new BorderLayout());
            add(getScrollPane(), "Center");
        } catch (Throwable ivjExc) {
            handleException(ivjExc);
        }

        // Make sure that this StringValueEditor handles user's commit or cancel input.
        getTextArea().addKeyListener(new StringValueEditorKeyListener());

        // Set default cursor for components that should have only ever have default cursors
        // (Mouse pointer changes near the edge of the border.
        getScrollPane().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }
   
    /**
     * @see org.openquark.gems.client.valueentry.ValueEditor#setInitialValue()
     */
    @Override
    public void setInitialValue() {

        String stringVal = null;
        if (getValueNode() instanceof ListOfCharValueNode) {
            stringVal = ((ListOfCharValueNode)getValueNode()).getStringValue();
        } else if (getValueNode() instanceof LiteralValueNode) {
            stringVal = ((LiteralValueNode)getValueNode()).getStringValue();           
        } else {
            stringVal = getValueNode().getTextValue();
        }
       
        getTextArea().setText(stringVal);
        getTextArea().setCaretPosition(0);
       
        resetSize();
        setResizable(true);
       
        getTextArea().getDocument().addDocumentListener(new StringValueEditorDocumentListener ());
    }
   
    /**
     * @see org.openquark.gems.client.valueentry.ValueEditor#userHasResized()
     */
    @Override
    protected void userHasResized() {
        // If the user does resize the editor we want to enable line wrapping.
        getTextArea().setLineWrap(true);
        userHasResized = true;
    }
 
    /**
     * Sets the size of the editor depending on the preferred size of the text area.
     */
    private void resetSize () {

        boolean isEditable = isEditable();
        int lineHeight = getTextArea().getFontMetrics(getTextArea().getFont()).getHeight();
        Dimension borders = getBorderSize();
        Dimension bestSize = getTextArea().getPreferredSize();
       
        // Always set a reasonable minimum size.
        setMinResizeDimension(new Dimension (100, lineHeight + borders.height));       
       
        // Don't resize the editor if the user manually picked a size they like.
        if (userHasResized) {
            return;
        }
       
        // Restore the saved size if there is any.
        ValueEditor.Info info = valueEditorManager.getInfo(getOwnerValueNode());
        if (info != null) {
            userHasResized = true;
            getTextArea().setLineWrap(true);
            setSize(info.getEditorSize());
            return;
        }
       
        bestSize.height += borders.height;
        bestSize.width += borders.width;

        // Give the text area a dummy default size. Do this so that the BasicTextUI
        // will return a sensible value for the preferred size of the text area.
        getTextArea().setSize(DEFAULT_MAXIMUM_WIDTH, DEFAULT_MAXIMUM_LINES * lineHeight);

        if (isEditable) {
            setMaxResizeDimension(null);
        } else {
            setMaxResizeDimension(bestSize);
        }

        // Compare the new sizes with the current size
        // If they are bigger then we want to grow the editor
        Dimension currentSize = getSize();
        int newHeight = getSize().height;
        int newWidth = getSize().width;

        if (!isEditable || bestSize.height > currentSize.height) {
            newHeight = Math.min (bestSize.height, DEFAULT_MAXIMUM_LINES * lineHeight);
        }
           
        if (!isEditable || bestSize.width > currentSize.width) {
            newWidth = Math.min (bestSize.width, DEFAULT_MAXIMUM_WIDTH);
        }
       
        if (isEditable) {
            // Make sure the editor has a reasonable size if it is editable and the text is small
            newHeight = Math.max(newHeight, lineHeight * 10);
            newWidth = Math.max(newWidth, 300);
        }
       
        // If there are lines longer than the maximum size we grow to, then enable line
        // wrapping. This causes the preferred size of the text area to change, so we
        // have to reset the size again after we do this.
        if (bestSize.width > DEFAULT_MAXIMUM_WIDTH && !getTextArea().getLineWrap()) {
            getTextArea().setLineWrap(true);
            resetSize();
            return;
        }

        // Pick the new size so that we don't accidentally go to a smaller
        // size than we are now. Sometimes the new size ca be smaller if the
        // user erases characters and enters new characters that are narrower.
        setSize (new Dimension (Math.max (newWidth, currentSize.width),
                                Math.max (newHeight, currentSize.height)));       
       
        revalidate();
    }
   
    /**
     * Calculates the total dimension of all borders around the text area of
     * the value editor. The size for the value editor should include the size
     * intended for the text area plus the size of the total border.
     *
     * @return a dimension with the total border height and width
     */
    private Dimension getBorderSize() {
       
        // The border of the scrollpane.
        Insets insets = getScrollPane().getInsets();
        int borderHeight = insets.top + insets.bottom;
        int borderWidth = insets.left + insets.right;       

        // The border of the value editor itself.
        insets = getInsets();               
        borderHeight += insets.top + insets.bottom;
        borderWidth += insets.left + insets.right;
       
        // The size of the scrollbars.
        JScrollBar scrollbar = new JScrollBar(Adjustable.HORIZONTAL);
        borderHeight += scrollbar.getPreferredSize().height;
        scrollbar = new JScrollBar(Adjustable.VERTICAL);
        borderWidth += scrollbar.getPreferredSize().width;       

        // Add 5 pixels to the width for good looks
        borderWidth += 5;
       
        return new Dimension (borderWidth, borderHeight);
    }
   
    /**
     * Set the editable status of this StringValueEditor, and make any
     * necessary internal adjustments.
     */
    @Override
    public void setEditable(boolean editable) {
        super.setEditable(editable);
        getTextArea().setEditable(editable);
        getTextArea().setForeground(editable ? Color.black : Color.gray);
    }
}
TOP

Related Classes of org.openquark.gems.client.valueentry.StringValueEditor$StringValueEditorProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.