Editable Label class
package com.java2s.gwt.client; import com.google.gwt.user.client.*; import com.google.gwt.user.client.ui.*; import com.google.gwt.core.client.*; public class GWTClient implements EntryPoint{ public void onModuleLoad() { EditableLabel label = new EditableLabel("editable label",true); label.setText("click to edit me"); RootPanel.get().add(label); } } /* * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This code is part of the GWT Widget Library */ /** * Editable Label class, funcionality displays a Label UI * Element until clicked on, then if element is set to be * editable (default) then an editable area and Buttons are * displayed instead. * * If the Label is not set to be word wrapped (default) then * the editable area is a Text Box and clicking the OK button * or hitting return key in the TextBox will display the Label with * the updated text. * * If the Label is set to be word wrapped, using the setWordWrap(boolean) * method, then the editable area is a Text Area and clicking the OK * button will display the Label with the updated text. * * In both cases, clicking Cancel button or hitting Escape key in the * TextBox/TextArea then the Label is displayed with original text. * * @author Adam Tacy * @version 0.0.2 * * Changes since version 0.0.1 * + made cancelLabelChange public [ref request id: 1518134] * + made originalText have default value of empty string [to support ref request id: 1518134] * *End* */ class EditableLabel extends Composite implements HasWordWrap, HasText, HasHorizontalAlignment, SourcesClickEvents, SourcesChangeEvents, SourcesMouseEvents { /** * TextBox element to enable text to be changed if Label is not word wrapped */ private TextBox changeText; /** * TextArea element to enable text to be changed if Label is wordwrapped */ private TextArea changeTextArea; /** * Label element, which is initially is diplayed. */ private Label text; /** * String element that contains the original text of a * Label prior to it being edited. */ private String originalText; /** * Simple button to confirm changes */ private Widget confirmChange; /** * Simple button to cancel changes */ private Widget cancelChange; /** * Flag to indicate that Label is in editing mode. */ private boolean isEditing = false; /** * Flag to indicate that label can be edited. */ private boolean isEditable = true; ChangeListenerCollection changeListeners; /** * Default String value for OK button */ private String defaultOkButtonText = "OK"; /** * Default String value for Cancel button */ private String defaultCancelButtonText = "Cancel"; /** * Allows the setting of the isEditable flag, marking * the label as editable or not. * * @param flag True or False value depending if the Label is to be editable or not */ public void setEditable (boolean flag) { isEditable = flag; } /** * Returns the value of the isEditable flag. * * @return */ public boolean isFieldEditable () { return isEditable; } /** * Returns the value of the isEditing flag, allowing outside * users to see if the Label is being edited or not. * * @return */ public boolean isInEditingMode () { return isEditing; } /** * Change the displayed label to be a TextBox and copy label * text into the TextBox. * */ private void changeTextLabel () { if (isEditable) { // Set up the TextBox originalText = text.getText(); // Change the view from Label to TextBox and Buttons text.setVisible(false); confirmChange.setVisible(true); cancelChange.setVisible(true); if (text.getWordWrap()){ // If Label word wrapped use the TextArea to edit changeTextArea.setText(originalText); changeTextArea.setVisible(true); changeTextArea.setFocus(true); } else { // Otherwise use the TextBox to edit. changeText.setText(originalText); changeText.setVisible(true); changeText.setFocus(true); } //Set instance as being in editing mode. isEditing = true; } } /** * Restores visibility of Label and hides the TextBox and Buttons * */ private void restoreVisibility () { // Change appropriate visibilities text.setVisible(true); confirmChange.setVisible(false); cancelChange.setVisible(false); if(text.getWordWrap()){ // If Label is word wrapped hide the TextArea changeTextArea.setVisible(false); } else { // Otherwise hide the TextBox changeText.setVisible(false); } // Set isEditing flag to false as we are no longer editing isEditing = false; } /** * Sets the Label text to the new value, restores the * display and calls the update method. * */ private void setTextLabel () { if(text.getWordWrap()){ // Set the Label to be the text in the Text Box text.setText(changeTextArea.getText()); } else { // Set the Label to be the text in the Text Box text.setText(changeText.getText()); } // Set the object back to display label rather than TextBox and Buttons restoreVisibility(); // Call the update method provided in the Constructor // (this could be anything from alerting the user through to // Making an AJAX call to store the data. //updater.onChange(this); if (changeListeners!=null)changeListeners.fireChange(this); } /** * Sets the Label text to the original value, restores the display. * */ public void cancelLabelChange () { // Set the Label text back to what it was originally text.setText(originalText); // Set the object back to display Label rather than TextBox and Buttons restoreVisibility(); } /** * Creates the Label, the TextBox and Buttons. Also associates * the update method provided in the constructor with this instance. * * @param labelText The value of the initial Label. * @param visibleLength The visible length (width) of the TextBox/TextArea. * @param maxLength The maximum length of text in the TextBox. * @param maxHeight The maximum number of visible lines of the TextArea * @param okButtonText The text diplayed in the OK button. * @param cancelButtonText The text displayed in the Cancel button. */ private void createEditableLabel (String labelText, String okButtonText, String cancelButtonText) { // Put everything in a VerticalPanel FlowPanel instance = new FlowPanel(); // Create the Label element and add a ClickListener to call out Change method when clicked text = new Label(labelText); text.setStyleName("editableLabel-label"); text.addClickListener(new ClickListener() { public void onClick (Widget sender) { changeTextLabel(); } }); // Create the TextBox element used for non word wrapped Labels // and add a KeyboardListener for Return and Esc key presses changeText = new TextBox(); changeText.setStyleName("editableLabel-textBox"); changeText.addKeyboardListener(new KeyboardListenerAdapter() { public void onKeyPress (Widget sender, char keyCode, int modifiers) { // If return then save, if Esc cancel the change, otherwise do nothing switch (keyCode) { case 13: setTextLabel(); break; case 27: cancelLabelChange(); break; } } }); // Create the TextAre element used for word-wrapped Labels // and add a KeyboardListener for Esc key presses (not return in this case) changeTextArea = new TextArea(); changeTextArea.setStyleName("editableLabel-textArea"); changeTextArea.addKeyboardListener(new KeyboardListenerAdapter() { public void onKeyPress (Widget sender, char keyCode, int modifiers) { // If Esc then cancel the change, otherwise do nothing switch (keyCode) { case 27: cancelLabelChange(); break; } } }); // Set up Confirmation Button confirmChange = createConfirmButton(okButtonText); if (!(confirmChange instanceof SourcesClickEvents)) { throw new RuntimeException("Confirm change button must allow for click events"); } ((SourcesClickEvents) confirmChange).addClickListener(new ClickListener() { public void onClick (Widget sender) { setTextLabel(); } }); // Set up Cancel Button cancelChange = createCancelButton(cancelButtonText); if (!(cancelChange instanceof SourcesClickEvents)) { throw new RuntimeException("Cancel change button must allow for click events"); } ((SourcesClickEvents)cancelChange).addClickListener(new ClickListener() { public void onClick (Widget sender) { cancelLabelChange(); } }); // Put the buttons in a panel FlowPanel buttonPanel = new FlowPanel(); buttonPanel.setStyleName("editableLabel-buttonPanel"); buttonPanel.add(confirmChange); buttonPanel.add(cancelChange); // Add panels/widgets to the widget panel instance.add(text); instance.add(changeText); instance.add(changeTextArea); instance.add(buttonPanel); // Set initial visibilities. This needs to be after // adding the widgets to the panel because the FlowPanel // will mess them up when added. text.setVisible(true); changeText.setVisible(false); changeTextArea.setVisible(false); confirmChange.setVisible(false); cancelChange.setVisible(false); // Assume that this is a non word wrapped Label unless explicitly set otherwise text.setWordWrap(false); // Set the widget that this Composite represents initWidget(instance); } /** * @param cancelButtonText */ protected Widget createCancelButton (String cancelButtonText) { Button result = new Button(); result.setStyleName("editableLabel-buttons"); result.addStyleName("editableLabel-cancel"); result.setText(cancelButtonText); return result; } /** * @param okButtonText */ protected Widget createConfirmButton (String okButtonText) { Button result = new Button(); result.setStyleName("editableLabel-buttons"); result.addStyleName("editableLabel-confirm"); result.setText(okButtonText); return result; } /** * Set the word wrapping on the label (if word wrapped then the editable * field becomes a TextArea, if not then the editable field is a TextBox. * @param b Boolean value, true means Label is word wrapped, false means it is not. */ public void setWordWrap(boolean b) { text.setWordWrap(b); } /** * Return whether the Label is word wrapped or not. */ public boolean getWordWrap() { return text.getWordWrap(); } /** * Return the text value of the Label */ public String getText() { return text.getText(); } /** * Set the text value of the Label */ public void setText(String newText) { text.setText(newText); } /** * Sets the number of visible lines for a word-wrapped editable label. * @param number Number of visible lines. * @throws RuntimeException if the editable label is not word-wrapped. */public void setVisibleLines(int number){ if (text.getWordWrap()){ changeTextArea.setVisibleLines(number); } else { throw new RuntimeException("Cannnot set number of visible lines for a non word-wrapped Editable Label"); } } /** * Get the number of Visible Lines of editable area of a word-wrapped editable Label. * @return Number of Visible Lines. * @throws RuntimeException If the Label is not word-wrapped. */ public int getVisibleLines(){ if (text.getWordWrap()){ return changeTextArea.getVisibleLines(); } else { throw new RuntimeException("Editable Label that is not word-wrapped has no number of Visible Lines"); } } /** * Set maximum length of editable area. * @param length Length of editable area. */ public void setMaxLength(int length){ if (text.getWordWrap()){ changeTextArea.setCharacterWidth(length); } else { changeText.setMaxLength(length); } } /** * Get maximum length of editable area. * @return maximum length of editable area. */ public int getMaxLength(){ if (text.getWordWrap()){ return changeTextArea.getCharacterWidth(); } else { return changeText.getMaxLength(); } } /** * Set the visible length of the editable area. * @throws RuntimeExcpetion If editable label is word wrapped. */ public void setVisibleLength(int length){ if (text.getWordWrap()){ throw new RuntimeException("Cannnot set visible length for a word-wrapped Editable Label"); } else { changeText.setVisibleLength(length); } } /** * Get the visible length of the editable area. * @return Visible length of editable area if not a word wrapped label. * @throws RuntimeExcpetion If editable label is word wrapped. */ public int getVisibleLength(){ if (text.getWordWrap()){ throw new RuntimeException("Cannnot get visible length for a word-wrapped Editable Label"); } else { return changeText.getVisibleLength(); } } /** * Constructor that changes default text for buttons and allows the setting of the wordwrap property directly. * * @param labelText The initial text of the label. * @param onUpdate Handler object for performing actions once label is updated. * @param okText Text for use in overiding the default OK button text. * @param cancelText Text for use in overiding the default CANCEL button text. * @param wordWrap Boolean representing if the label should be word wrapped or not */ public EditableLabel (String labelText, String okText, String cancelText, boolean wordWrap) { createEditableLabel(labelText, okText, cancelText); text.setWordWrap(wordWrap); } /** * Constructor that uses default text values for buttons and sets the word wrap property. * * @param labelText The initial text of the label. * @param onUpdate Handler object for performing actions once label is updated. * @param wordWrap Boolean representing if the label should be word wrapped or not */ public EditableLabel (String labelText, boolean wordWrap) { createEditableLabel(labelText, defaultOkButtonText, defaultCancelButtonText); text.setWordWrap(wordWrap); } /** * Constructor that changes default button text. * * @param labelText The initial text of the label. * @param onUpdate Handler object for performing actions once label is updated. * @param okText Text for use in overiding the default OK button text. * @param cancelText Text for use in overiding the default CANCEL button text. */ public EditableLabel (String labelText, String okText, String cancelText) { createEditableLabel(labelText, okText, cancelText); } /** * Constructor that uses default text values for buttons. * * @param labelText The initial text of the label. * @param onUpdate Handler object for performing actions once label is updated. */ public EditableLabel (String labelText) { createEditableLabel(labelText, defaultOkButtonText, defaultCancelButtonText); } public HorizontalAlignmentConstant getHorizontalAlignment() { return text.getHorizontalAlignment(); } public void setHorizontalAlignment(HorizontalAlignmentConstant align) { text.setHorizontalAlignment(align); } public void addClickListener(ClickListener listener) { this.text.addClickListener(listener); } public void removeClickListener(ClickListener listener) { this.text.removeClickListener(listener); } public void addMouseListener(MouseListener listener) { this.text.addMouseListener(listener); } public void removeMouseListener(MouseListener listener) { this.text.removeMouseListener(listener); } public void addChangeListener(ChangeListener listener) { if (changeListeners == null){ changeListeners = new ChangeListenerCollection(); } changeListeners.add(listener); } public void removeChangeListener(ChangeListener listener) { if (changeListeners != null){ changeListeners.remove(listener);; } } }