All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.valkyriercp.sample.simple.ui.ContactView Maven / Gradle / Ivy

/*
 * Copyright 2002-2006 the original author or authors.
 * 
 * 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.
 */
package org.valkyriercp.sample.simple.ui;

import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.swing.TextComponentMatcherEditor;
import org.valkyriercp.application.PageComponentContext;
import org.valkyriercp.application.event.LifecycleApplicationEvent;
import org.valkyriercp.application.support.AbstractView;
import org.valkyriercp.binding.value.ValueModel;
import org.valkyriercp.command.ActionCommandExecutor;
import org.valkyriercp.command.SecuredActionCommandExecutor;
import org.valkyriercp.command.support.AbstractActionCommandExecutor;
import org.valkyriercp.command.support.ActionCommand;
import org.valkyriercp.command.support.CommandGroup;
import org.valkyriercp.command.support.GlobalCommandIds;
import org.valkyriercp.dialog.ConfirmationDialog;
import org.valkyriercp.list.ListSelectionValueModelAdapter;
import org.valkyriercp.list.ListSingleSelectionGuard;
import org.valkyriercp.sample.simple.domain.Contact;
import org.valkyriercp.sample.simple.domain.ContactDataStore;
import org.valkyriercp.util.PopupMenuMouseListener;
import org.valkyriercp.widget.table.PropertyColumnTableDescription;
import org.valkyriercp.widget.table.glazedlists.GlazedListTableWidget;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;

/**
 * This class provides the main view of the contacts. It provides a table showing the contact objects and a quick filter
 * field to narrow down the list of visible contacts. Several commands are tied to the selection of the contacts table
 * 

* By implementing special tag interfaces, this component will be automatically wired in to certain events of interest. *

    *
  • ApplicationListener - This component will be automatically registered as a listener for application * events.
  • *
* * @author Larry Streepy */ public class ContactView extends AbstractView { private GlazedListTableWidget widget; /** * The data store holding all our contacts. */ private ContactDataStore contactDataStore; /** * Handler for the "New Contact" action. */ private ActionCommandExecutor newContactExecutor = new NewContactExecutor(); /** * Handler for the "Properties" action. */ private SecuredActionCommandExecutor propertiesExecutor = new PropertiesExecutor(); /** * Handler for the "Delete" action. */ private SecuredActionCommandExecutor deleteExecutor = new DeleteExecutor(); /** * The text field allowing the user to filter the contents of the contact table. */ private JTextField filterField; /** * Default constructor. */ public ContactView() { super("contactView"); } /** * @return the contactDataStore */ protected ContactDataStore getContactDataStore() { return contactDataStore; } /** * @param contactDataStore the contactDataStore to set */ public void setContactDataStore(ContactDataStore contactDataStore) { this.contactDataStore = contactDataStore; } /** * Create the control for this view. This method is called by the platform in order to obtain the control to add to * the surrounding window and page. * * @return component holding this view */ protected JComponent createControl() { PropertyColumnTableDescription desc = new PropertyColumnTableDescription("contactViewTable", Contact.class); desc.addPropertyColumn("lastName").withMinWidth(150); desc.addPropertyColumn("firstName").withMinWidth(150); desc.addPropertyColumn("address.address1"); desc.addPropertyColumn("address.city"); desc.addPropertyColumn("address.state"); desc.addPropertyColumn("address.zip"); widget = new GlazedListTableWidget(Arrays.asList(contactDataStore.getAllContacts()), desc); JPanel table = new JPanel(new BorderLayout()); table.add(widget.getListSummaryLabel(), BorderLayout.NORTH); table.add(widget.getComponent(), BorderLayout.CENTER); table.add(widget.getButtonBar(), BorderLayout.SOUTH); CommandGroup popup = new CommandGroup(); popup.add((ActionCommand) getWindowCommandManager().getCommand("deleteCommand", ActionCommand.class)); popup.addSeparator(); popup.add((ActionCommand) getWindowCommandManager().getCommand("propertiesCommand", ActionCommand.class)); JPopupMenu popupMenu = popup.createPopupMenu(); widget.getTable().addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { // If the user right clicks on a row other than the selection, // then move the selection to the current row if (e.getButton() == MouseEvent.BUTTON3) { int rowUnderMouse = widget.getTable().rowAtPoint(e.getPoint()); if (rowUnderMouse != -1 && !widget.getTable().isRowSelected(rowUnderMouse)) { // Select the row under the mouse widget.getTable().getSelectionModel().setSelectionInterval(rowUnderMouse, rowUnderMouse); } } } @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() >= 2) { if (propertiesExecutor.isEnabled()) propertiesExecutor.execute(); } } }); widget.getTable().addMouseListener(new PopupMenuMouseListener(popupMenu)); ValueModel selectionHolder = new ListSelectionValueModelAdapter(widget.getTable().getSelectionModel()); new ListSingleSelectionGuard(selectionHolder, deleteExecutor); new ListSingleSelectionGuard(selectionHolder, propertiesExecutor); JPanel view = new JPanel(new BorderLayout()); view.add(widget.getTextFilterField(), BorderLayout.NORTH); view.add(table, BorderLayout.CENTER); return view; //"lastName", "firstName", "address.address1", "address.city", "address.state", "address.zip" // JPanel filterPanel = new JPanel(new BorderLayout()); // JLabel filterLabel = getComponentFactory().createLabel("nameAddressFilter.label"); // filterPanel.add(filterLabel, BorderLayout.WEST); // // String tip = getMessage("nameAddressFilter.caption"); // filterField = getComponentFactory().createTextField(); // filterField.setToolTipText(tip); // filterPanel.add(filterField, BorderLayout.CENTER); // filterPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // // contactTable = new ContactTableFactory().createContactTable(); // // JPanel view = new JPanel(new BorderLayout()); // JScrollPane sp = getComponentFactory().createScrollPane(contactTable.getControl()); // view.add(filterPanel, BorderLayout.NORTH); // view.add(sp, BorderLayout.CENTER); // return view; } /** * Register the local command executors to be associated with named commands. This is called by the platform prior * to making the view visible. */ protected void registerLocalCommandExecutors(PageComponentContext context) { context.register("newContactCommand", newContactExecutor); context.register(GlobalCommandIds.PROPERTIES, propertiesExecutor); applicationConfig.securityControllerManager().addSecuredObject(propertiesExecutor); context.register(GlobalCommandIds.DELETE, deleteExecutor); applicationConfig.securityControllerManager().addSecuredObject(deleteExecutor); } /** * Prepare the table holding all the Contact objects. This table provides pretty much all the functional operations * within this view. Prior to calling this method the setContactTable(ContactTable) will have already been * called as part of the context bean creation. */ private class ContactTableFactory { public ContactTable createContactTable() { ContactTable contactTable = new ContactTable(contactDataStore); // Get the table instance from our factory // Make a double click invoke the properties dialog and plugin the // context menu contactTable.setDoubleClickHandler(propertiesExecutor); // Construct and install our filtering list. This filter will allow the user // to simply type data into the txtFilter (JTextField). With the configuration // setup below, the text entered by the user will be matched against the values // in the lastName and address.address1 properties of the contacts in the table. // The GlazedLists filtered lists is used to accomplish this. EventList baseList = contactTable.getBaseEventList(); TextFilterator filterator = GlazedLists.textFilterator(new String[]{"lastName", "address.address1"}); FilterList filterList = new FilterList(baseList, new TextComponentMatcherEditor(filterField, filterator)); // Install the fully constructed (layered) list into the table contactTable.setFinalEventList(filterList); // Install the popup menu CommandGroup popup = new CommandGroup(); popup.add((ActionCommand) getWindowCommandManager().getCommand("deleteCommand", ActionCommand.class)); popup.addSeparator(); popup.add((ActionCommand) getWindowCommandManager().getCommand("propertiesCommand", ActionCommand.class)); contactTable.setPopupCommandGroup(popup); // Register to get notified when the filtered list changes contactTable.setStatusBar(getStatusBar()); // Ensure our commands are only active when something is selected. // These guard objects operate by inspecting a list selection model // (held within a ValueModel) and then either enabling or disabling the // guarded object (our executors) based on the configured criteria. // This configuration greatly simplifies the interaction between commands // that require a selection on which to operate. ValueModel selectionHolder = new ListSelectionValueModelAdapter(contactTable.getSelectionModel()); new ListSingleSelectionGuard(selectionHolder, deleteExecutor); new ListSingleSelectionGuard(selectionHolder, propertiesExecutor); return contactTable; } } /** * Private inner class to create a new contact. */ private class NewContactExecutor implements ActionCommandExecutor { public void execute() { new ContactPropertiesDialog(getContactDataStore()).showDialog(); } } /** * Private inner class to handle the properties form display. */ private class PropertiesExecutor extends AbstractActionCommandExecutor { public void execute() { for (Object selected : widget.getSelectedRows()) new ContactPropertiesDialog((Contact) selected, getContactDataStore()).showDialog(); } } /** * Private class to handle the delete command. Note that due to the configuration above, this executor is only * enabled when exactly one contact is selected in the table. Thus, we don't have to protect against being executed * with an incorrect state. */ private class DeleteExecutor extends AbstractActionCommandExecutor { private DeleteExecutor() { setAuthorities("ADMIN"); } public void execute() { String title = getApplicationConfig().messageResolver().getMessage("contact.confirmDelete.title"); String message = getApplicationConfig().messageResolver().getMessage("contact.confirmDelete.message"); ConfirmationDialog dlg = new ConfirmationDialog(title, message) { protected void onConfirm() { for (Object selected : widget.getSelectedRows()) { Contact contact = (Contact) selected; // Delete the object from the persistent store. getContactDataStore().delete(contact); // And notify the rest of the application of the change getApplicationConfig().applicationContext().publishEvent( new LifecycleApplicationEvent(LifecycleApplicationEvent.DELETED, contact)); } } }; dlg.showDialog(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy