blob: 7d07687377ad8ac21d87c72fc8f7d14ee04fe8e1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.ace.webui.vaadin;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ace.webui.NamedObject;
import org.apache.ace.webui.UIExtensionFactory;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
/**
* Provides a generic editor for repository objects.
*/
public abstract class EditWindow extends Window {
protected final TextField m_name;
protected final TextField m_description;
/**
* @param object
* @param factories
*/
public EditWindow(String caption, NamedObject object, List<UIExtensionFactory> factories) {
setModal(true);
setWidth("50em");
setCaption(caption);
m_name = new TextField("Name", object.getName());
m_name.setReadOnly(true);
m_name.setWidth("100%");
m_description = new TextField("Description", object.getDescription());
m_description.setWidth("100%");
initDialog(object, factories);
}
/**
* Shows this dialog on screen.
*
* @param window the parent window to show this dialog on, cannot be <code>null</code>.
*/
public void show(Window parent) {
if (getParent() != null) {
// window is already showing
parent.showNotification("Window is already open!");
}
else {
parent.addWindow(this);
}
setRelevantFocus();
}
/**
* Called when the {@link #onOk(String, String)} method failed with an exception.
*
* @param e the exception to handle, never <code>null</code>.
*/
protected abstract void handleError(Exception e);
/**
* @param object
* @param factories
*/
protected void initDialog(final NamedObject object, List<UIExtensionFactory> factories) {
VerticalLayout fields = new VerticalLayout();
fields.setSpacing(true);
fields.addComponent(m_name);
fields.addComponent(m_description);
TabSheet tabs = new TabSheet();
tabs.setHeight("350px");
tabs.setWidth("100%");
tabs.setVisible(!factories.isEmpty());
Map<String, Object> context = new HashMap<>();
context.put("object", object);
populateContext(context);
for (UIExtensionFactory factory : factories) {
try {
tabs.addTab(factory.create(context));
}
catch (Throwable ex) {
// We ignore extension factories that throw exceptions
// TODO: log this or something
ex.printStackTrace();
}
}
Button okButton = new Button("Ok", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
try {
onOk((String) m_name.getValue(), (String) m_description.getValue());
close();
}
catch (Exception e) {
handleError(e);
}
}
});
// Allow enter to be used to close this dialog with enter directly...
okButton.setClickShortcut(KeyCode.ENTER);
okButton.addStyleName("primary");
Button cancelButton = new Button("Cancel", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
close();
}
});
cancelButton.setClickShortcut(KeyCode.ESCAPE);
HorizontalLayout buttonBar = new HorizontalLayout();
buttonBar.setSpacing(true);
buttonBar.addComponent(okButton);
buttonBar.addComponent(cancelButton);
VerticalLayout layout = (VerticalLayout) getContent();
layout.setMargin(true);
layout.setSpacing(true);
layout.addComponent(fields);
layout.addComponent(tabs);
layout.addComponent(buttonBar);
// The components added to the window are actually added to the window's
// layout; you can use either. Alignments are set using the layout
layout.setComponentAlignment(buttonBar, Alignment.BOTTOM_RIGHT);
m_name.focus();
}
protected Map<String, Object> populateContext(Map<String, Object> context) {
return context;
}
/**
* Called when the user acknowledges this window by pressing Ok.
*
* @param name the value of the name field;
* @param description the value of the description field.
* @throws Exception in case the creation failed.
*/
protected abstract void onOk(String name, String description) throws Exception;
/**
* Sets the focus to the name field.
*/
private void setRelevantFocus() {
m_name.focus();
}
}