In vaadin application I use CropField addon to crop user's avatar. The problem is that whenever I try to test it, selection area is always stick to the top of the cropfield. Everything was fine on one page but when I copied exactly that piece of code to another page the problem has occured. Do you have any ideas why?
NativeButton nb = new NativeButton("Click on me");
layout.addComponent(nb);
nb.addListener(new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
final Window window = new Window();
window.setModal(true);
DivLayout cropContent = new DivLayout();
window.setContent(cropContent);
final CropField cropField = new CropField(new ExternalResource("http://upload.wikimedia.org/wikipedia/commons/1/1e/Stonehenge.jpg"));
cropField.setSelectionAspectRatio(1);
cropContent.addComponent(cropField);
//cropField.setImmediate(true);
NativeButton btClose = new NativeButton("Close");
btClose.addListener(new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
getMyApplication().getMainWindow().removeWindow(window);
}
});
cropContent.addComponent(btClose);
getMyApplication().getMainWindow().addWindow(window);
}
});
Related
I have the following problem:
My method opens a JDialog with a bunch of buttons (only one in example code). I want to click a button and thereby choose an ImageIcon for my method to return. But the Method does not wait for me to click a button. It opens the window and then returns an empty ImageIcon.
public class Kartenauswahl {
ImageIcon bandit;
public ImageIcon auswahlfenster() {
int bwidth = new Integer(150);
int bheight = new Integer(225);
bandit = new ImageIcon("cover/Bandit.jpe");
bandit.setImage(bandit.getImage().getScaledInstance(bwidth,bheight,Image.SCALE_DEFAULT));
final JDialog kartenwahl = new JDialog();
kartenwahl.setTitle("Kartenwahl");
kartenwahl.setSize(1500,1000);
kartenwahl.setVisible(true);
kartenwahl.setLayout(new FlowLayout());
ImageIcon returnicon= new ImageIcon();
final JButton b1 = new JButton(); //just to get the Icon out of the void loop
JButton B1 = new JButton(bandit); //this is going to be the button I want to click to choose the ImageIcon which is returned
B1.setContentAreaFilled(false);
B1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
b1.setIcon(bandit);
kartenwahl.dispose();
}
});
kartenwahl.add(B1);
returnicon = (ImageIcon) b1.getIcon();
return returnicon;
}
}
Question: can I bind the return statement to a condition? Like "only return after I clicked that Button B1"?
Hi sorry for the long wait. I have written an custom JDialog that should work for you.
public class CustomDialog extends JDialog {
JButton[] buttons;
ImageIcon selectedImageIcon;
public CustomDialog() {
setSize(500, 500);
setLayout(new GridLayout(4, 6));
ActionListener actionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
selectedImageIcon = ((ImageIcon) ((JButton) e.getSource()).getIcon());
dispose();
}
};
buttons = new JButton[24];
for(int i = 0; i < 24; i++) {
buttons[i] = new JButton(new ImageIcon("path_to_your_image_file"));
buttons[i].addActionListener(actionListener);
add(buttons[i]);
}
setVisible(true);
}
public ImageIcon getSelectedImageIcon() {
return selectedImageIcon;
}
}
The initial size is not that important the GridLayout is. you mentioned that you would need 24 buttons so I created an grid with 4 rows and 6 columns.
Then I create the buttons in a loop and adding the same Listener to set the selection icon with the icon of the pressed button. Afterwards I dispose the screen triggering an windowClosed event.
You could simply create this Dialog from your main class and wait for the response like so:
public class main {
public static void main(String[] args) {
CustomDialog customDialog = new CustomDialog();
customDialog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
ImageIcon icon = customDialog.getSelectedImageIcon();
//do something with your icon
}
});
}
}
Don't forget to mark this answer as correct if it fixes your problem.
Have a good one!
I'm trying to emulate normal browser behaviour in my vaadin grid, which includes middle mouse click to open in a new tab:
addItemClickListener(e -> {
boolean newTab = e.getMouseEventDetails().getButton() == MouseEventDetails.MouseButton.MIDDLE || e.getMouseEventDetails().isCtrlKey();
//open in window or new tab
});
However, the middle mouse button is not registered by vaadin. How could I get this to work?
That feature was included in vaadin-grid (which goes into Vaadin 10) and will not work in Vaadin 8.
For Vaadin 8, you can either intercept the event with some client-side extension, or use a ComponentRenderer for adding a Panel to each component (which works, but is not ideal because it degrades performance):
grid.addColumn(item->{
Panel p = new Panel(item.getName());
p.setStyleName(ValoTheme.PANEL_BORDERLESS);
p.addClickListener(ev->{
System.out.println(ev.getButtonName());
});
return p;
}).setRenderer(new ComponentRenderer());
A client-side extension, on the other hand, allows listening to javascript events (such as MouseEvent) and triggering a server event in response. Creating a extension is quite a complex topic (since it uses a part of the API that is normally hidden from the developer) but it allows direct access to rendered DOM, which is not possible otherwise.
The following resources from the documentation may give you a starting point:
Creating a component extension (which describes a simple extension with Java code only) and Integrating JavaScript Components and Extension (which explains how to add native JavaScript code to your extension).
How I solved the problem in my specific case:
Server side:
public class MyGrid<T> extends Grid<T> {
public MyGrid(String caption, DataProvider<T, ?> dataProvider) {
super(caption, dataProvider);
MiddleClickExtension.extend(this);
}
public static class MiddleClickExtension<T> extends AbstractGridExtension<T> {
private MiddleClickExtension(MyGrid<T> grid) {
super.extend(grid);
registerRpc((rowKey, columnInternalId, details) -> grid.fireEvent(
new ItemClick<>(grid, grid.getColumnByInternalId(columnInternalId), grid.getDataCommunicator().getKeyMapper().get(rowKey), details)),
MiddleClickGridExtensionConnector.Rpc.class);
}
public static void extend(MyGrid<?> grid) {
new MiddleClickExtension<>(grid);
}
#Override
public void generateData(Object item, JsonObject jsonObject) {
}
#Override
public void destroyData(Object item) {
}
#Override
public void destroyAllData() {
}
#Override
public void refreshData(Object item) {
}
}
}
Client side:
#Connect(MyGrid.MiddleClickExtension.class)
public class MiddleClickGridExtensionConnector extends AbstractExtensionConnector {
#Override
protected void extend(ServerConnector target) {
getParent().getWidget().addDomHandler(event -> {
if (event.getNativeButton() == NativeEvent.BUTTON_MIDDLE) {
event.preventDefault();
CellReference<JsonObject> cell = getParent().getWidget().getEventCell();
getRpcProxy(Rpc.class).middleClick(cell.getRow().getString(DataCommunicatorConstants.KEY), getParent().getColumnId(cell.getColumn()),
MouseEventDetailsBuilder.buildMouseEventDetails(event.getNativeEvent(), event.getRelativeElement()));
}
}, MouseDownEvent.getType());
}
#Override
public GridConnector getParent() {
return (GridConnector) super.getParent();
}
public interface Rpc extends ServerRpc {
void middleClick(String rowKey, String columnInternalId, MouseEventDetails details);
}
}
I know that it is really easy to create a FileDownloader and call extend with a Button. But how do I start a download without the Button?
In my specific situation right now I have a ComboBox and the file I'd like to send to the user is generated after changing its value, based on the input. The file should be sent immediately without waiting for another click. Is that easily possible?
Thanks
raffael
I found a solution myself. Actually two.
The first one uses the deprecated method Page.open()
public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();
public DownloadComponent() {
cb.addValueChangeListener(this);
cb.setNewItemsAllowed(true);
cb.setImmediate(true);
cb.setNullSelectionAllowed(false);
setCompositionRoot(cb);
}
#Override
public void valueChange(ValueChangeEvent event) {
String val = (String) event.getProperty().getValue();
FileResource res = new FileResource(new File(val));
Page.getCurrent().open(res, null, false);
}
}
The javadoc here mentions some memory and security problems as reason for marking it deprecated
In the second I try to go around this deprecated method by registering the resource in the DownloadComponent. I'd be glad if a vaadin expert comments this solution.
public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();
private static final String MYKEY = "download";
public DownloadComponent() {
cb.addValueChangeListener(this);
cb.setNewItemsAllowed(true);
cb.setImmediate(true);
cb.setNullSelectionAllowed(false);
setCompositionRoot(cb);
}
#Override
public void valueChange(ValueChangeEvent event) {
String val = (String) event.getProperty().getValue();
FileResource res = new FileResource(new File(val));
setResource(MYKEY, res);
ResourceReference rr = ResourceReference.create(res, this, MYKEY);
Page.getCurrent().open(rr.getURL(), null);
}
}
Note: I do not really allow the user to open all my files on the server and you should not do that either. It is just for demonstration.
Here is my work-around. It works like a charm for me. Hope it will help you.
Create a button and hide it by Css (NOT by code: button.setInvisible(false))
final Button downloadInvisibleButton = new Button();
downloadInvisibleButton.setId("DownloadButtonId");
downloadInvisibleButton.addStyleName("InvisibleButton");
In your theme, add this rule to hide the downloadInvisibleButton:
.InvisibleButton {
display: none;
}
When the user clicks on menuItem: extend the fileDownloader to the downloadInvisibleButton, then simulate the click on the downloadInvisibleButton by JavaScript.
menuBar.addItem("Download", new MenuBar.Command() {
#Override
public void menuSelected(MenuBar.MenuItem selectedItem) {
FileDownloader fileDownloader = new FileDownloader(...);
fileDownloader.extend(downloadInvisibleButton);
//Simulate the click on downloadInvisibleButton by JavaScript
Page.getCurrent().getJavaScript()
.execute("document.getElementById('DownloadButtonId').click();");
}
});
My browser (webview) starts with an HTML page
FILEJAVA.class.getResource ("FILEHTML.html"). ToExternalForm ()
Whenever I access the google, I want to know whether the browser check, if the network has proxy (proxy'm working manual)
So that the browser shows a dialog to enter User name and password.
You can use ProxySelector to check proxy. See next example:
public class DetectProxy extends Application {
private Pane root;
#Override
public void start(final Stage stage) throws URISyntaxException {
root = new VBox();
List<Proxy> proxies = ProxySelector.getDefault().select(new URI("http://google.com"));
final Proxy proxy = proxies.get(0); // ignoring multiple proxies to simplify code snippet
if (proxy.type() != Proxy.Type.DIRECT) {
// you can change that to dialog using separate Stage
final TextField login = new TextField("login");
final PasswordField pwd = new PasswordField();
Button btn = new Button("Submit");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
System.setProperty("http.proxyUser", login.getText());
System.setProperty("http.proxyPassword", pwd.getText());
showWebView();
}
});
root.getChildren().addAll(login, pwd, btn);
} else {
showWebView();
}
stage.setScene(new Scene(root, 600, 600));
stage.show();
}
private void showWebView() {
root.getChildren().clear();
WebView webView = new WebView();
final WebEngine webEngine = webView.getEngine();
root.getChildren().addAll(webView);
webEngine.load("http://google.com");
}
public static void main(String[] args) {
launch();
}
}
authentification may require additional code in some cases, see Authenticated HTTP proxy with Java for details.
I have a BlackBerry application that needs to take pictures from the camera and send them to a server. In order to do this i invoke the native camera application and listen to the filesystem. Once an image is captured and saved as a new jpeg file i get notified, resume foreground control and go about my business. The problem starts occurring after the first time this cycle is completed because now when i decide to call the camera application again it is already opened, and now the user is seeing a thumbnail of the last picture that was taken and several buttons allowing him to manipulate/manage it. naturally what i want the user to see is a preview of what the camera is "seeing" before he snaps another photo as he did before.
I have thought of various ways to solve this including killing the camera app each time (I understand this cannot be done programatically?), sending CameraArguments when invoking the app (which appears to be useless), and now i was thinking a solution could be as simple generating a "Back" key event before switching back to my app which would theoretically dismiss the annoying edit screen. Could this really be done? and if not is there any other possible solution you may think of?
A kind of hack...
start Camera App
in TimerTask check if Camera App started and if it need to be closed (some flag)
if yes, invoke it(so it will became active) and push ESC keypress event injection to close it
Take a look at this:
class Scr extends MainScreen {
boolean killCameraApp = false;
final String mCameraModuleName = "net_rim_bb_camera";
final CameraArguments args = new CameraArguments();
public Scr() {
super();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (isCameraRunning() && killCameraApp) {
getApplication().invokeAndWait(callCamera);
getApplication().invokeAndWait(killCamera);
}
}
}, 0, 100);
}
Runnable callCamera = new Runnable() {
public void run() {
callCamera();
}
};
Runnable killCamera = new Runnable() {
public void run() {
injectKey(Characters.ESCAPE);
killCameraApp = false;
}
};
private boolean isCameraRunning() {
boolean result = false;
ApplicationManager appMan =
ApplicationManager.getApplicationManager();
ApplicationDescriptor[] appDes = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
result = mCameraModuleName.equalsIgnoreCase(appDes[i]
.getModuleName());
if (result)
break;
}
return result;
}
private void callCamera() {
Invoke.invokeApplication(Invoke.APP_TYPE_CAMERA,
new CameraArguments());
}
private void injectKey(char key) {
KeyEvent inject = new KeyEvent(KeyEvent.KEY_DOWN, key, 0);
inject.post();
}
protected void makeMenu(Menu menu, int instance) {
menu.add(new MenuItem("start camera", 0, 0) {
public void run() {
callCamera();
killCameraApp = false;
}
});
menu.add(new MenuItem("kill app", 0, 0) {
public void run() {
killCameraApp = true;
}
});
super.makeMenu(menu, instance);
}
}
EDIT: Don't forget to set permissions for device release:
Options => Advanced Options => Applications => [Your Application] =>Edit Default permissions =>Interactions =>key stroke Injection