is there a way to programmatically perform a Button Press Event i.e for the TAB-Button in Vaadin? I have to write a test for a ShortCutListener, which listens to ShortCut ShortCutAction.KeyEvent.TAB.
I have tried something like that:
Button button = new Button();
button.addShortcutListener(new ShortcutListener("ShortCut", ShortcutAction.KeyCode.TAB, null) {
private static final long serialVersionUID = 1L;
#Override
public void handleAction(Object sender, Object target) {
System.out.println("Click!");
}
});
button.setClickShortcut(ShortcutAction.KeyCode.TAB, null);
button.click();
If what you want is triggering the click event when pressing the tab key, you could do the following:
Button button = new Button();
button.addClickListener(new Button.ClickListener() {
private static final long serialVersionUID = 1L;
#Override
public void buttonClick(final ClickEvent event) {
System.out.println("Click!");
}
});
button.setClickShortcut(ShortcutAction.KeyCode.TAB);
button.click();
Using a Vaadin Button to do something useful on a key press is probably not a good idea, except if the keypress is a shortcut to clicking on the button (which the setClickShortcut method lets you define).
If you want to do something specific on a keypress, something that is different from what your buttons do, you should define an action handler on your Window or Panel, as Vaadin recommends.
Related
How would I programmatically click a Swing JButton in a way that would register all the relevant action/mouse events and be visible to the user (i.e. they'd see the button being pressed as if they actually clicked it)?
The button is in the same application I'm running; I'm not trying to control a button in another application. I suppose I could directly inject events into the queue, but I'd prefer to avoid that approach if possible, and doing it that way wouldn't show a visible click.
I see the java.awt.Robot class offers methods to move the mouse and click the mouse, but not to make it click a particular button.
Have you tried using doClick()?
If doClick() is not what you want, you can move the mouse really to the button and press it:
public void click(AbstractButton button, int millis) throws AWTException
{
Point p = button.getLocationOnScreen();
Robot r = new Robot();
r.mouseMove(p.x + button.getWidth() / 2, p.y + button.getHeight() / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try { Thread.sleep(millis); } catch (Exception e) {}
r.mouseRelease(InputEvent.BUTTON1_MASK);
}
Even though the asker was satisfied with button.doClick(), I was looking for something like what happens after setting a mnemonic, i.e. with button.setMnemonic(KeyEvent.VK_A). You can actually hold down ALT + A without anything happening (except the visual change). And upon release of the key A (with or without ALT), the button fires an ActionEvent.
I found that I can get the ButtonModel (see Java 8 API) with button.getModel(), then visually press the button with model.setPressed(true); model.setArmed(true); (both are changed by mnemonics), and visually release the button by setting both to false. And when model.setPressed(false) is called while the button is both pressed and armed, the button fires an ActionEvent automatically (calling model.setArmed(false) only changes the button visually).
[Quote from ButtonModel Java API documentation]
A button is triggered, and an ActionEvent is fired, when the mouse is released while the model is armed [...]
To make the application react to key presses when the button is visible (without the containing window or the button needing to be the focus owner, i.e. when another component in the window is focussed) I used key bindings (see the Official Java Tutorial).
Working code: Press SHIFT + A to visually press the button (in contrast to pressing ALT with the key after the mnemonic is set with button.setMnemonic()). And release the key to print the action command ("button") on the console.
// MnemonicCode.java
import javax.swing.*;
import java.awt.event.*;
public class MnemonicCode extends JFrame
{
public MnemonicCode(int keyCode)
{
JButton button = new JButton("button");
getContentPane().add(button);
addMnemonicToButton(button,keyCode);
button.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e)
{
System.out.println(e.getActionCommand());
}
});
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) throws Exception
{
MnemonicCode bp = new MnemonicCode(KeyEvent.VK_A);
}
void addMnemonicToButton(JButton button,int keyCode)
{
int shiftMask = InputEvent.SHIFT_DOWN_MASK;
// signature: getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)
KeyStroke keyPress = KeyStroke.getKeyStroke(keyCode,shiftMask,false);
KeyStroke keyReleaseWithShift = KeyStroke.getKeyStroke(keyCode,shiftMask,true);
// get maps for key bindings
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = button.getActionMap();
// add key bindings for pressing and releasing the button
inputMap.put(keyPress,"press"+keyCode);
actionMap.put("press"+keyCode, new ButtonPress(button));
inputMap.put(keyReleaseWithShift,"releaseWithShift"+keyCode);
actionMap.put("releaseWithShift"+keyCode, new ButtonRelease(button));
///*
// add key binding for releasing SHIFT before A
// if you use more than one modifier it gets really messy
KeyStroke keyReleaseAfterShift = KeyStroke.getKeyStroke(keyCode,0,true);
inputMap.put(keyReleaseAfterShift,"releaseAfterShift"+keyCode);
actionMap.put("releaseAfterShift"+keyCode, new ButtonRelease(button));
//*/
}
class ButtonPress extends AbstractAction
{
private JButton button;
private ButtonModel model;
ButtonPress(JButton button)
{
this.button = button;
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
// visually press the button
model.setPressed(true);
model.setArmed(true);
button.requestFocusInWindow();
}
}
class ButtonRelease extends AbstractAction
{
private ButtonModel model;
ButtonRelease(JButton button)
{
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
if (model.isPressed()) {
// visually release the button
// setPressed(false) also makes the button fire an ActionEvent
model.setPressed(false);
model.setArmed(false);
}
}
}
}
You could always simulate it by firing an action event with it as the source.
http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html
To fire it, create the action event above, and whatever listener you want just call
ActionEvent e = new ActionEvent(myButton,1234,"CommandToPeform");
myListener.actionPerformed(e);
From: http://download.oracle.com/javase/6/docs/api/javax/swing/JButton.html
/**
* Click a button on screen
*
* #param button Button to click
* #param millis Time that button will remain "clicked" in milliseconds
*/
public void click(AbstractButton button, int millis) {
b.doClick(millis);
}
Based on #Courteaux's answer, this method clicks the first cell in a JTable:
private void clickFirstCell() {
try {
jTable1.changeSelection(0, 0, false, false);
Point p = jTable1.getLocationOnScreen();
Rectangle cellRect = jTable1.getCellRect(0, 0, true);
Robot r = new Robot();
Point mouse = MouseInfo.getPointerInfo().getLocation();
r.mouseMove(p.x + cellRect.x + cellRect.width / 2,
p.y + cellRect.y + cellRect.height / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try {
Thread.sleep(50);
} catch (Exception e) {
}
r.mouseRelease(InputEvent.BUTTON1_MASK);
r.mouseMove(mouse.x, mouse.y);
} catch (AWTException ex) {
}
}
I have created an SWT text editor and also have implemented the cut, copy and paste features but now I need to implement CTRL + BACKSPACE, to delete the preceding word, and CTRL + DEL, to delete the proceeding word.
The code which copied text
private class Copy implements SelectionListener{
public void widgetSelected(SelectionEvent event) {
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
copySelectedMessages();
}
private void copySelectedMessages(){
//StringBuffer stringCopied =new StringBuffer();
String textData = editor.getSelectionText();
//TextTransfer textTransfer = TextTransfer.getInstance();
System.out.println("you hv selected"+textData);
//Clipboard clipboard = new Clipboard(Display.getDefault());
TextTransfer transfer = TextTransfer.getInstance();
clipboard.setContents(new Object[] { textData }, new TextTransfer[] { transfer });
}
});
}
}
The code for the editor
editor = new StyledText( this, SWT.MULTI | SWT.V_SCROLL );
editor.setLayoutData( new GridData(GridData.FILL_BOTH) );
editor.setFont( new Font(Display.getDefault(),"Cambria", 10, SWT.NORMAL) );
The listener
proceeding.addSelectionListener(new proceed());
private class proceed implements SelectionListener{
public void widgetSelected(SelectionEvent event) {
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
// Code to check for CTRL + backspace and CTRL + delete
}
});
}
So now how can CTRL+BACKSPACE and CTRL+ DELETEfunctionality can be implemented in SWT.
addSelectionListener() is the wrong method to use here; use addKeyListener() and then a KeyAdapter to process the events.
java2s has an example: http://www.java2s.com/Code/JavaAPI/org.eclipse.swt.custom/StyledTextaddKeyListenerKeyListenerkey.htm
or here for a more complete one: http://www.java2s.com/Tutorial/Java/0280__SWT/Asimpleeditor.htm
Your code to implement "copy to clipboard" is not necessary since StyledText already implements this. Just call the copy() method. The second example shows how to install a global listener for Ctrl+C via a menu item.
As for how to delete the next or previous word, call st.invokeAction() with ST.DELETE_WORD_NEXT or ST.DELETE_WORD_PREVIOUS (org.eclipse.swt.custom.ST).
By default, those actions are bound to Ctrl+BackSpace and Ctrl+Delete. But again, those keys only trigger the action when the widget has the focus. If you want to enable them no matter which widget in the window has the focus, then create a menu item.
I have such code
printWindow = new BrowserWindowOpener(invoicesBeanService.getHTMLStream()); printWindow.setFeatures("menubar=no,location=no,toolbar=no,resizable=no,scrollbars=yes,status=no,width=900");
printWindow.extend(this.button_2);
How can I detect close event of BrowserWindowOpener when I close the popup window?
Add click listener to the button
Button button_2 = new Button("Close");
button_2.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
public void buttonClick(ClickEvent event) {
close();
}
});
printWindow.extend(button_2);
layout.addComponent(button_2);
Basically what I am trying to do here is handle click events which panel is suppose to appear to depending on which button is click. For example, if we click button one, the corresponding panel will pop up. But the panel and click event does not know anything about each other. I believe its called anonymous class. I am having trouble trying to implement this. What would be a good way to implement this?
This is my button click event class
public class buttonHandle extends Composite {
private static buttonHandleUiBinder uiBinder = GWT
.create(buttonHandleUiBinder.class);
#UiField Button button;
#UiField Button button_1;
interface buttonHandleUiBinder extends UiBinder<Widget, buttonHandle> {
}
public buttonHandle() {
initWidget(uiBinder.createAndBindUi(this));
}
#UiHandler("button")
void onButtonClick(ClickEvent event) {
}
#UiHandler("button_1")
void onButton_1Click(ClickEvent event) {
}
}
This is the class where I am trying to add a new button everytime a button is clicked
public class PanelHandle extends Composite {
private AbsolutePanel absolutePanel = new AbsolutePanel();
public PanelHandle() {
initWidget(absolutePanel);
absolutePanel.setSize("1027px", "636px");
Label lblHello = new Label("Hello");
absolutePanel.add(lblHello, 47, 80);
Label lblHello_1 = new Label("Hello");
absolutePanel.add(lblHello_1, 232, 249);
// TODO Auto-generated constructor stub
}
public void buttonOne()
{
this.absolutePanel.clear();
Button but1 = new Button("button one");
this.absolutePanel.add(but1);
}
}
I tried something like this, but it does not update the panel with a new button
private PanelHandle pHandle = new PanelHandle();
private static buttonHandleUiBinder uiBinder = GWT
.create(buttonHandleUiBinder.class);
#UiField Button button;
#UiField Button button_1;
interface buttonHandleUiBinder extends UiBinder<Widget, buttonHandle> {
}
public buttonHandle() {
initWidget(uiBinder.createAndBindUi(this));
}
#UiHandler("button")
void onButtonClick(ClickEvent event) {
Window.alert("hello buttone clicked");
pHandle.buttonOne();
}
#UiHandler("button_1")
void onButton_1Click(ClickEvent event) {
}
}
So far I tried to call the method in my PanelHandle class, but I am encountering errors such stack overflow. In another method I tried, I am unable to update the panel when I add.
I am using a button here instead of panel just for testing until I understand the logic.
Thank You for you help!
Create an own (gwt)event when a button is clicked. You can fire your own event wherever you want. Fill the event with the information you need.
Next add the class which have to handle this event to the gwt eventbus. If a event is fired, your handle class catch the event and work with the data from the event.
This could be helpful: How to use the GWT EventBus
How do I show a AJAX "Message Box" in GWT? I know I can use the Window.alert() function, but that's too ugly/annoying. Is there a built-in function for?
Thank you!
Yvan
Here is simple implementation of custom alert widget (modify it to what you want):
public static DialogBox alertWidget(final String header, final String content) {
final DialogBox box = new DialogBox();
final VerticalPanel panel = new VerticalPanel();
box.setText(header);
panel.add(new Label(content));
final Button buttonClose = new Button("Close",new ClickHandler() {
#Override
public void onClick(final ClickEvent event) {
box.hide();
}
});
// few empty labels to make widget larger
final Label emptyLabel = new Label("");
emptyLabel.setSize("auto","25px");
panel.add(emptyLabel);
panel.add(emptyLabel);
buttonClose.setWidth("90px");
panel.add(buttonClose);
panel.setCellHorizontalAlignment(buttonClose, HasAlignment.ALIGN_RIGHT);
box.add(panel);
return box;
}
And use it like (note center() method at the end, it actually shows the widget):
CustomWidgets.alertWidget("Adding account failed",
"System failed to add this account. Please chceck your settings properly.").center();
You can use DialogBox instead.