How to know which text string is selected by user in JavaFX TextArea - textarea

I need to allow the user to highlight text (select a range with the mouse), then I want to give them the ability to apply some setting to that text form a drop down right click menu.
I know the latter part. But how do I get which text string is selected from a Text Area in JavafX?
Also, would I be able to apply different styles to different strings?

Use getSelectedText() to get the selected text.
The answer to your second question is yes.
The getSelectedText() method can be used like I have done here:
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TextAreaDemo extends Application
{
#Override
public void start(Stage stage)
{
final TextArea textArea = new TextArea("Text Sample");
textArea.setPrefSize(200, 40);
textArea.setOnContextMenuRequested(new EventHandler<Event>()
{
#Override
public void handle(Event arg0)
{
System.out.println("selected text:"
+ textArea.getSelectedText());
}
});
VBox vBox = new VBox();
vBox.getChildren().addAll(textArea);
stage.setScene(new Scene(vBox, 300, 250));
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
Once you launch this application, it shows a TextArea with some text (Text Sample). I selected some part of the text and did a right click. It printed the selected text. Does this fit your requirement?

Related

Vaadin checkbox is not correctly rendered

Using Vaadin 14.0.13 without compatibility mode.
I use a view to create a Dialog with dynamic content:
#Route("")
public class MainView extends VerticalLayout {
public MainView(DialogContentProvider contentProvider) {
this.add(new Button("Click me!", event -> new Dialog(contentProvider.create()).open()));
}
}
The contentProvider is an interface
public interface DialogContentProvider {
Component create();
}
with this implementation:
public class CheckBoxContentProvider implements DialogContentProvider {
#Override
public Component create() {
return new Checkbox("My checkbox", true);
}
}
instantiated by Spring Boot (version 2.2.1.RELEASE) with a bean:
#Bean
public DialogContentProvider contentProvier() {
return new CheckBoxContentProvider();
}
When I click on the button, the dialog is opened but the checkbox haven't the box:
The source code is on github: https://github.com/gronono/bug-vaadin-checkbox
I don't understand why and how I can fix it. If I include the checkbox creation inside the main view, it works fine:
#Route("")
public class MainView extends VerticalLayout {
public MainView(DialogContentProvider contentProvider) {
// this.add(new Button("Click me!", event -> new Dialog(contentProvider.create()).open()));
this.add(new Button("Click me!", event -> new Dialog(new Checkbox("My checkbox", true)).open()));
}
}
This sound an awful lot like this (related github issue)
Basically, this happens when you don't have any View that uses a Checkbox directly, but through other means like reflection or in your case the contentProvider, because in no view of your app there is any import statement of Checkbox (--> therefore, vaadins scan during the installation will not detect usages of Checkbox, so it will not download npm stuff for checkbox).
in the github it says this will be fixed in 14.1
If you need a fix now, for me it worked when I declared a field of that type in any view with a #Route. That field doesn't have to be used.
#Route("")
public class MainView extends VerticalLayout {
private Checkbox unusedCheckbox; // this line fixes it.
public MainView(DialogContentProvider contentProvider) {
this.add(new Button("Click me!", event -> new Dialog(contentProvider.create()).open()));
}
}
Addendum: This is not related to the Checkbox component specifically, it happens with any vaadin component that isn't initially scanned in a route, but used anyway through reflective-, provider-, or generic means.
Edit: You can also work around this currently by adding a #Route(registerAtStartup = false) to your provider that uses the Checkbox directly. This will make vaadins scan see the checkbox usage (therefore importing its npm package), but will not actually register the provider as a real route..
Another way which I prefer if you need this for multiple components is to create a new View with a #Route(registerAtStartup = false) which only defines private variables for each component that you'll need in the application (and arent already used directly in some view of yours). This has the advantage of all these component usage definitions in one place, and once the official fix is released, you need only to delete one class and the deprecated workaround is gone.
#Route(registerAtStartup = false)
public class ComponentImportView extends VerticalLayout {
private Checkbox checkBox;
private Upload upload;
private ProgressBar progressBar;
}

Expanding a component in a PopupView - Vaadin

I am using Vaadin 8.5.1 with the Vaading Desiin combination with Spring Boot 2.0.4.
Currently I am trying to add a PopupView at the bottom of the page which opens on button click. In the Popup there is a vertical layout including two components: a HorizontalSplitPanel and a Button. The PopupView should have the width of the current BrowserWindow and one third of the height.
The HorizontalSplitPanel should use all the space in the popup, which is not needed for the button.
What I did:
#SpringComponent
#UIScope
public class View extends VerticalLayout implements Observer {
private final PopupContentView popupContentView;
private PopupView popup;
#Autowired
public View(PopupContentView popupContentView) {
this.popupContentView = popupContentView;
}
#PostConstruct
void init() {
button.addClickListener(clickEvent -> openPopup());
}
private void openPopup() {
if (popup == null) {
setSizeOfPopUp();
// popup will adjust automatically to size of content
popup = new PopupView(null, popupContentView);
popup.addPopupVisibilityListener(event -> {
if (event.isPopupVisible()) {
popupContentView.build(this::submitted);
}
});
popup.setHideOnMouseOut(false);
this.addComponent(popup);
}
popup.setPopupVisible(true);
}
private void setSizeOfPopUp() {
if (popupContentView != null) {
popupContentView.setWidth(Page.getCurrent().getBrowserWindowWidth(), Unit.PIXELS);
popupContentView.setHeight(((float) Page.getCurrent().getBrowserWindowHeight()) / 3, Unit.PIXELS);
}
}
private void submitted() {
// do some stuff
}
#Override
public void update(Observable observable, Object o) {
if (observable instanceof BrowserWindowResizeListenerObservable) {
setSizeOfPopUp();
}
}
}
#Service
public class BrowserWindowResizeListenerObservable extends Observable implements Page.BrowserWindowResizeListener {
#Override
public void browserWindowResized(Page.BrowserWindowResizeEvent browserWindowResizeEvent) {
this.setChanged();
this.notifyObservers();
}
}
#SpringComponent
#UIScope
public class PopupContentView extends VerticalLayout {
private SubmitCallback submitCallback;
private Button submitBtn;
#PostConstruct
void init() {
super.init();
}
void build(#NotNull SubmitCallback) {
removeAllComponents();
this.addComponent(horizontalSplitPanel);
this.addComponent(submitBtn);
this.setExpandRatio(horizontalSplitPanel, 1.0f);
this.submitCallback = callback;
}
private void submit() {
submitCallback.submit(someContent);
}
#FunctionalInterface
public interface SubmitCallback {
void submit(SomeContent someContent);
}
}
As you can see, I have a main view, a view for the content and a listener class.
What I want to happen is that the popup is visible on button click and contains the content view with the panel and the submit button. The panel takes the rest of the space, which is not needed for the button. and the popup is fully filled with content.
What actually happens is that the panel takes the full space of the popup and the button will be shown below the popup.
However, when I resize the window and the resizing event gets fired, everything is fine and the button is no longer below the popup.
It seems to be that the padding and the margin (which are the HTML implementation of the expand ratio in Vaadin) are calculated at an earlier stage and get triggered again when resizing the window. However, I have no clue when and what I need to do, to trigger it.
Does anyone have an idea, how can fix this?
EDIT:
When I have a Tree component or a DateField component in the PopupView and then expand a tree element or change the value of the DateField by selecting a value from the Date popup, the resizing is done correctly and everything is fine.
I think in your case the method of checking Browser window size and calculating target pixel size is too complex for your case. I would recommend just to set the width of the popup to be 100% and height to be 33%, like component.setHeight("33%"), yes you can use percentages for width and height instead of pixels. Then sizing is done by CSS, and it will react faster to browser window sizing without server round trip.

JavaFX: Tooltip - Can't get tooltip's to show at all

I'm in the middle of a project where i'm supposed to write a login system using JavaFX 2.0.
And right now i'm trying to write a tooltip with a connection to the password field, but the tooltip NEVER shows at all.. I'm using the FXML-LoginDemo project from the 'javafx-samples-2.0.3'. And then I tried to use: http://docs.oracle.com/javafx/2.0/ui_controls/tooltip.htm#BABHCHGG example 19.1.
If you need more code to see this problem please say so.. because I don't really know where the problem is..
Here's my code so far:
package demo;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
/**
* Login Controller.
*/
public class LoginController {
#FXML private TextField userId;
#FXML private PasswordField password;
#FXML private Label errorMessage;
#FXML final Tooltip tooltip = new Tooltip();
#FXML protected void processLogin(ActionEvent event) {
tooltip.setText("\nYour password must be\n at least 8 characters in length\n");
password.setTooltip(tooltip);
if(!App.getInstance().userLogging(userId.getText(), password.getText())){
errorMessage.setText("Invalid username or password: " + userId.getText());
}
//Replaces inputed password with an empty String.
password.setText("");
}
}
Define an initialize method on the controller and, in that method, set the tooltip text and associate the tooltip with the password field. If you wait until the processLogin action is called to set the Tooltip, the scene has already been displayed and the user has already tried to login.
Also, you don't need to place the #FXML annotation in front of the Tooltip unless you are defining Tooltip properties in FXML, which is probably not necessary in this case.

How to invoke paint method in blackberry

How can i invoke paint multiple time in my app i tried invalidate but but it is not calling paint i think can anybody provide sample code for invoking paint multiple time.
package mypackage;
import com.rss.logger.Log;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
/**
* A class extending the MainScreen class, which provides default standard
* behavior for BlackBerry GUI applications.
*/
public final class MyScreen extends MainScreen
{
BitmapField objBitmapField;
boolean objBoolean;
int postion=0;
public MyScreen()
{
objBitmapField=new BitmapField(Bitmap.getBitmapResource("bb.png"));
// Set the displayed title of the screen
setTitle("MyTitle");
objBoolean=false;
new AnimationThread().start();
}
private class AnimationThread extends Thread{
public void run() {
super.run();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
objBoolean=true;
//Add a new LabelField to the screen.
//theScreen.add(new LabelField("Hello there.");
//Call the screen’s invalidate method to
//force the screen to redraw itself.
//Note that invalidate can be called
//at the screen, manager or field level,
//which means you can inform the
//BlackBerry to only redraw the area that
//has changed.
for (int i = 0; i < 20; i++) {
try {
sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.info("in run");
postion=postion+5;
MyScreen.this.invalidate();
}
}
});
}
}
protected void paint(Graphics graphics) {
super.paint(graphics);
Log.info("in paint");
if(objBoolean)
graphics.drawBitmap(20, postion, 50, 50, Bitmap.getBitmapResource("bb.png"), 30, 40);
}
}
Hi piyus find the working code. invalidate() need to call in the paint() method. And one thing is also important that should not create object in paint method.
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.container.MainScreen;
public final class MyScreen extends MainScreen
{
private boolean objBoolean=false;
private int postion=0;
private Bitmap bb=Bitmap.getBitmapResource("bb.png");
public MyScreen()
{
setTitle("MyTitle");
new AnimationThread().start();
}
private class AnimationThread extends Thread
{
public void run()
{
objBoolean=true;
for (int i = 0; i < 20; i++)
{
try
{
sleep(200);
}
catch (InterruptedException e)
{
}
postion=postion+5;
}
}
}
protected void paint(Graphics graphics)
{
super.paint(graphics);
if(objBoolean)
graphics.drawBitmap(20, postion, 50, 50, bb, 30, 40);
invalidate();
}
}
paint() method can be invoked either by using invalidate method or by creating an object of the class that you are using now.
I think there is Typo Error in the sample code you have mentioned here. One cannot have a class inside a class just by defining it. Coming to the issue you are facing
While, calling the invalidate method, as you are using it as MyScreen.this.invalidate which is not the right way to call it, one cannot call the paint method from another class, as in your case it is AnimationThread is not possible. The propreitary feature of Screen class and the paint method is, it gets called once the Object of the screen is created.
And as I understand one can call the invalidate method for a manager or a screen, inside the same class but not by creating an object of the screen in another class and by calling it.
It should be called simply without using any objects simply, invalidate(); , gets the screen repainted or invalidated.
One can also achieve it by creating an object of the same screen, may be if one wanted to display the screen in a different way, they can create an object by using different arguments, and handle it accordingly in the paint method.
Here, whenever the thread is run, you can create an object and handle it according to your choice.
As a sample :
public class theScreen extends MainScreen{
int dummy;
public theScreen(int firstArg){
// Handle the firstArgument here
dummy=0;
}
public theScreen(int secondArg,int dummy){
// Handle the second Argument here
this.dummy = dummy;
}
public void paint(Graphics graphcis)
{
if(dummy == 0)
{
//Handle what you would like to paint here
}
else{
//Handle with a different paint here
}
}}
Hope this resolves your problem
Happy Coding.
Cheers
You may try using Screen.doPaint().
Is your Bitmap big enough to be completely drawn starting from top/left (30, 40)? It may just be that it doesn't look like it's painting because you're outside of the bounds that make sense for it to be drawn.

Blackberry PopupScreen size limited by virtual keyboard

I am trying to display a Custom PopupScreen and when the virtual keyboard is being displayed it reduces the size of the popup. I know when you for example, select new message you get a PopupScreen that allows you to select message type (sms, email, etc) and it shows on top of the virtual keyboard. Here is my code am I missing something? I can't find a z-index or something similar...
public class InsertApplicationMenuItem extends ApplicationMenuItem {
public Object run(Object context) {
InsertWhatScreen screen = new InsertWhatScreen();
UiApplication.getUiApplication().pushModalScreen(screen);
return context;
}
}
public class InsertWhatScreen extends PopupScreen {
public InsertWhatScreen() {
super(new VerticalFieldManager(), FOCUSABLE);
}
}
alt text http://dl.dropbox.com/u/2645315/2010-01-20%2015%2017%2023.png
Thanks for the help.
There's no way to put anything on top of the virtual keyboard from a third-party app. If you read the display height while the virtual keyboard is showing, you'll see that the device actually shrinks the "screen size" given to your app while the keyboard is showing.

Resources