ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 01.01.2026

Просмотров: 2664

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Advanced Web Application Topics

often causes more warnings from its child components. A good rule of thumb is to work on the upper-level problems first and only after that worry about the warnings from the children.

Figure 11.3. Debug Window Showing the Result of Analyze layouts.

11.3.3. Custom Layouts

CustomLayout components can not be analyzed in the same way as other layouts. For custom layouts, the Analyze layouts button analyzes all contained relative-sized components and checks if any relative dimension is calculated to zero so that the component will be invisible. The error log will display a warning for each of these invisible components. It would not be meaningful to emphasize the component itself as it is not visible, so when you select such an error, the parent layout of the component is emphasized if possible.

11.3.4. Debug Functions for Component Developers

You can take advantage of the debug mode when developing client-side components. The static function ApplicationConnection.getConsole() will return a reference to a VConsole object which contains logging methods such as log(String msg) and error(String msg). These functions will print messages to the Debug Window and Firebug console in the same way as other debugging functionalities of Vaadin do. No messages will be printed if the Debug Window is not open or if the application is running in production mode.

11.4. Request Handlers

Request handlers are useful for catching request parameters or generating dynamic content, such as HTML, images, PDF, or other content. You can provide HTTP content easily also with stream resources, as described in Section 4.4.5, “Stream Resources”. The stream resources, however, are only usable from within a Vaadin application, such as in an Image component. Request handlers allow responding to HTTP requests made with the application URL, including GET or POST parameters. You could also use a separate servlet to generate dynamic content, but a request handler is associated with the Vaadin session and it can easily access all the session data.

To handle requests, you need to implement the RequestHandler interface. The handleRequest() method gets the session, request, and response objects as parameters.

If the handler writes a response, it must return true. This stops running other possible request handlers. Otherwise, it should return false so that another handler could return a response. Eventually, if no other handler writes a response, a UI will be created and initialized.

In the following example, we catch requests for a sub-path in the URL for the servlet and write a plain text response. The servlet path consists of the context path and the servlet (sub-)path.

Custom Layouts

289


Advanced Web Application Topics

Any additional path is passed to the request handler in the pathInfo of the request. For example, if the full path is /myapp/myui/rhexample, the path info will be /rhexample. Also, request parameters are available.

VaadinSession.getCurrent().addRequestHandler( new RequestHandler() {

@Override

public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response)

throws IOException {

if ("/rhexample".equals(request.getPathInfo())) { response.setContentType("text/plain"); response.getWriter().append(

"Here's some dynamically generated content.\n"+ "Time: " + (new Date()).toString());

return true; // We wrote a response } else

return false; // No response was written

}

});

//Find out the base bath for the servlet String servletPath = VaadinServlet.getCurrent()

.getServletContext().getContextPath() + VaadinServletService

.getCurrentServletRequest().getServletPath();

//Display the page in a popup window

Link open = new Link("Click to Show the Page",

new ExternalResource(servletPath + "/rhexample"), "_blank", 500, 350, BorderStyle.DEFAULT);

layout.addComponent(open);

11.5. Shortcut Keys

Vaadin provides simple ways for defining shortcut keys for field components and a default button, and a lower-level generic shortcut key binding API based on actions.

11.5.1. Click Shortcuts for Default Buttons

You can add or set a click shortcut to a button to set it as "default" button; pressing the defined key, typically Enter, in any component in the window causes a click event for the button.

You can define a click shortcut with the setClickShortcut() shorthand method:

// Have an OK button and set it as the default button Button ok = new Button("OK"); ok.setClickShortcut(KeyCode.ENTER); ok.addStyleName("primary");

The primary style name highlights a button to show the default button status; usually with a bolder font than usual, depending on the theme. The result can be seen in Figure 11.4, “Default Button with Click Shortcut”.

Figure 11.4. Default Button with Click Shortcut

290

Shortcut Keys

Advanced Web Application Topics

11.5.2. Field Focus Shortcuts

You can define a shortcut key that sets the focus to a field component (any component that inherits AbstractField) by adding a FocusShortcut as a shortcut listener to the field.

// A field with Alt+N bound to it

TextField name = new TextField("Name (Alt+N)"); name.addShortcutListener(

new AbstractField.FocusShortcut(name, KeyCode.N, ModifierKey.ALT));

layout.addComponent(name);

// A field with Alt+A bound to it

TextField address = new TextField("Address (Alt+A)"); address.addShortcutListener(

new AbstractField.FocusShortcut(address, KeyCode.A, ModifierKey.ALT));

layout.addComponent(address);

The constructor of the FocusShortcut takes the field component as its first parameter, followed by the key code, and an optional list of modifier keys, as listed in Section 11.5.4, “Supported Key Codes and Modifier Keys”.

11.5.3. Generic Shortcut Actions

Shortcut keys can be defined as actions using the ShortcutAction class. ShortcutAction extends the generic Action class that is used for example in Tree and Table for context menus. Currently, the only classes that accept ShortcutActions are Window and Panel.

To handle key presses, you need to define an action handler by implementing the Handler interface. The interface has two methods that you need to implement: getActions() and handleAction().

The getActions() method must return an array of Action objects for the component, specified with the second parameter for the method, the sender of an action. For a keyboard shortcut, you use a ShortcutAction. The implementation of the method could be following:

//Have the unmodified Enter key cause an event Action action_ok = new ShortcutAction("Default key",

ShortcutAction.KeyCode.ENTER, null);

//Have the C key modified with Alt cause an event Action action_cancel = new ShortcutAction("Alt+C",

ShortcutAction.KeyCode.C,

new int[] { ShortcutAction.ModifierKey.ALT });

Action[] actions = new Action[] {action_cancel, action_ok};

public Action[] getActions(Object target, Object sender) { if (sender == myPanel)

return actions;

return null;

}

The returned Action array may be static or you can create it dynamically for different senders according to your needs.

The constructor of ShortcutAction takes a symbolic caption for the action; this is largely irrelevant for shortcut actions in their current implementation, but might be used later if implementors use them both in menus and as shortcut actions. The second parameter is the key code and the third

Field Focus Shortcuts

291


Advanced Web Application Topics

a list of modifier keys, which are listed in Section 11.5.4, “Supported Key Codes and Modifier Keys”.

The following example demonstrates the definition of a default button for a user interface, as well as a normal shortcut key, Alt+C for clicking the Cancel button.

public class DefaultButtonExample extends CustomComponent implements Handler {

//Define and create user interface components Panel panel = new Panel("Login");

FormLayout formlayout = new FormLayout(); TextField username = new TextField("Username"); TextField password = new TextField("Password"); HorizontalLayout buttons = new HorizontalLayout();

//Create buttons and define their listener methods. Button ok = new Button("OK", this, "okHandler");

Button cancel = new Button("Cancel", this, "cancelHandler");

//Have the unmodified Enter key cause an event

Action action_ok = new ShortcutAction("Default key",

ShortcutAction.KeyCode.ENTER, null);

// Have the C key modified with Alt cause an event Action action_cancel = new ShortcutAction("Alt+C",

ShortcutAction.KeyCode.C,

new int[] { ShortcutAction.ModifierKey.ALT });

public DefaultButtonExample() {

//Set up the user interface setCompositionRoot(panel); panel.addComponent(formlayout); formlayout.addComponent(username); formlayout.addComponent(password); formlayout.addComponent(buttons); buttons.addComponent(ok); buttons.addComponent(cancel);

//Set focus to username username.focus();

//Set this object as the action handler System.out.println("adding ah"); panel.addActionHandler(this);

System.out.println("start done.");

}

/**

*Retrieve actions for a specific component. This method

*will be called for each object that has a handler; in

*this example just for login panel. The returned action

*list might as well be static list.

*/

public Action[] getActions(Object target, Object sender) { System.out.println("getActions()");

return new Action[] { action_ok, action_cancel };

}

/**

*Handle actions received from keyboard. This simply directs

*the actions to the same listener methods that are called

*with ButtonClick events.

*/

public void handleAction(Action action, Object sender, Object target) {

292

Generic Shortcut Actions


Advanced Web Application Topics

if (action == action_ok) { okHandler();

}

if (action == action_cancel) { cancelHandler();

}

}

public void okHandler() {

// Do something: report the click formlayout.addComponent(new Label("OK clicked. "

+"User=" + username.getValue() + ", password="

+password.getValue()));

}

public void cancelHandler() {

// Do something: report the click formlayout.addComponent(new Label("Cancel clicked. User="

+username.getValue() + ", password="

+password.getValue()));

}

}

Notice that the keyboard actions can currently be attached only to Panels and Windows. This can cause problems if you have components that require a certain key. For example, multi-line TextField requires the Enter key. There is currently no way to filter the shortcut actions out while the focus is inside some specific component, so you need to avoid such conflicts.

11.5.4. Supported Key Codes and Modifier Keys

The shortcut key definitions require a key code to identify the pressed key and modifier keys, such as Shift, Alt, or Ctrl, to specify a key combination.

The key codes are defined in the ShortcutAction.KeyCode interface and are:

Keys A to Z

Normal letter keys

F1 to F12

Function keys

BACKSPACE, DELETE, ENTER, ESCAPE, INSERT, TAB

Control keys

NUM0 to NUM9

Number pad keys

ARROW_DOWN, ARROW_UP, ARROW_LEFT, ARROW_RIGHT

Arrow keys

HOME, END, PAGE_UP, PAGE_DOWN

Other movement keys

Modifier keys are defined in ShortcutAction.ModifierKey and are:

ModifierKey.ALT

Alt key

ModifierKey.CTRL

Ctrl key

Supported Key Codes and Modifier Keys

293