TextField getText() problem in ActionListener - javafx

I working in a console, and I want to convert the text to html format with color code. If I send the text from text field, I can't replace characters, and my text is doesn't get converted. Here is an example:
My test code:
WebViewConsole webViewConsole = new WebViewConsole();
webViewConsole.appendText("§1This is a §l§2Test §r§1, just §l§2because§r§1!\n");
TextField textField = new TextField();
textField.setText("§1This is a §l§2Test §r§1, just §l§2because§r§1!\n");
System.out.println(textField.getText().replaceAll("§", ""));
System.out.println(textField.getText().contains("§"));
Button button = new Button("Send");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
for (String htmlText : webViewConsole.getHtmlFormat(textField.getText())) {
System.out.println(htmlText);
}
String text = textField.getText();
webViewConsole.appendText(textField.getText());
System.out.println(text.replaceAll("§", ""));
System.out.println(text.contains("§"));
}
});
HBox hBox = new HBox(textField, button);
VBox vBox = new VBox(webViewConsole.getConsole(), hBox);
primaryStage.setScene(new Scene(vBox, 500, 300));
primaryStage.show();
The screenshot:
screenshot
The output(i sent the message once):
1This is a l2Test r1, just l2becauser1!
true
<span style="color:white;font-weight:normal"></span>
<span style="color:blue;font-weight:normal">This is a </span>
<span style="color:darkgreen;font-weight:bold">Test </span>
<span style="color:white;font-weight:normal"></span>
<span style="color:blue;font-weight:normal">, just </span>
<span style="color:darkgreen;font-weight:bold">because</span>
<span style="color:white;font-weight:normal"></span>
<span style="color:blue;font-weight:normal">!</span>
1This is a l2Test r1, just l2becauser1!
true
If the message contains that stange characters(screenshot), the text will be converted successfully.
Sorry for my bad english, thanks for help!

Related

Is this the proper behaviour for event filter and requstfocus in javafx?

I have a very simple task to accomplish. I just want to press any letter on a button, matches the key code, and move the focus to a text field. I wrote
a simple test code as shown. I have no problem to shift the focus. However,
I don't want the letter I press shows up in the text field. Seemingly a simple programming solution turns out to be not so simple.
I don't understand why the event consume method doesn't stop the event from propagating down the event chain and have the typed letter shown up at the text field.
It seems like after the requestFocus is called, the text field picks up the letter typed from the button. This happens on Mac. Any help will be greatly appreciated.
package testkeynavigation;
public class TestKeyNavigation extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
TextField txt1 = new TextField();
TextField txt2 = new TextField();
VBox vbox = new VBox();
vbox.getChildren().add(btn);
vbox.getChildren().add(txt1);
vbox.getChildren().add(txt2);
root.getChildren().add(vbox);
Scene scene = new Scene(root, 300, 250);
btn.setOnKeyPressed((KeyEvent e) ->{
if (e.getCode() == KeyCode.A) {
e.consume();
System.out.println("e.isConsumed: "+e.isConsumed());
txt2.requestFocus();
}
});
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
btn.requestFocus();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
There are three kinds of key event: KEY_PRESSED, KEY_TYPED, and KEY_RELEASED. In a key stroke, an event of each of these types is fired, in that order, to the UI node that has the keyboard focus at the time of the event.
A TextField has an internal listener for KEY_TYPED events; so if a KEY_TYPED event occurs when the text field has focus, a character is entered into the text field (or other actions occur, e.g. deleting characters or moving the caret, depending on the key).
In your code, you listen for the first one of these - KEY_PRESSED - to occur on the button. If the key press has a code of A, you consume that event (the KEY_PRESSED event) then transfer keyboard focus to the text field. At a slightly later moment, the user releases the key, and since the text field now has focus, a KEY_TYPED event is fired on the text field. Note that this is a new event, so it is not consumed, so the text fields reacts as though a character has been entered. Finally, a KEY_RELEASED event is fired on the text field.
You can see this in action if you add the debugging code:
txt2.addEventFilter(KeyEvent.ANY, e -> {
System.out.printf("Key event on text field: type=%s, code=%s, character=%s%n",
e.getEventType(), e.getCode(), e.getCharacter());
});
To fix the problem, just listen for the last event in the series of events: the key released event. Note that you don't need to consume the event.
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
TextField txt1 = new TextField();
TextField txt2 = new TextField();
VBox vbox = new VBox();
vbox.getChildren().add(btn);
vbox.getChildren().add(txt1);
vbox.getChildren().add(txt2);
root.getChildren().add(vbox);
Scene scene = new Scene(root, 300, 250);
btn.setOnKeyReleased((KeyEvent e) ->{
if (e.getCode() == KeyCode.A) {
txt2.requestFocus();
}
});
txt2.addEventFilter(KeyEvent.ANY, e -> {
System.out.printf("Key event on text field: type=%s, code=%s, character=%s%n",
e.getEventType(), e.getCode(), e.getCharacter());
});
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
btn.requestFocus();
}

TextField ESCAPE Keycode not caught

I'm trying to catch an ESCAPE key press in a textfield.
I was expecting to put a simple event listener (or even an event filter) to the textfield. But nothing works.
It seems all key events are caught, except the ESCAPE key I 'm waiting for.
Can you provide any help please,
Thanks in advance
PS: the following bunch of code explains how I proceed.
public class KeyEventSample extends Application {
/**
* Constructor
*/
public KeyEventSample() {super();}
#Override
public void start(final Stage primaryStage) throws Exception {
final TextField textField = new TextField();
final TextArea textArea = new TextArea();
textField.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.ESCAPE)
textArea.appendText("ESCAPE");
else if (e.getCode() == KeyCode.ENTER)
textArea.appendText("ENTER");
else
textArea.appendText("->"+e.getCode().toString());
});
final BorderPane borderPane = new BorderPane();
borderPane.setCenter(textField);
borderPane.setBottom(textArea);
final Scene scene = new Scene(borderPane, 300, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
}

JavaFX, TextField value to variable

I am trying to get the users input from a text box and set it as a variable but I dont know how. I have written and tried the following code:
btn = new Button("set speed");
TextField speedinput = new TextField();
btn.setOnAction(car.speed = Integer.parseInt(speedinput));
Any help would be great, thanks:)
Check out official docs for TextField and docs for Button:
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
car.speed = Integer.parseInt(speedinput.getText());
}
});

Change label javafx on keyboard input

I would like a javafx label to be automatically updated to what is being typed into a textfield, currently i have it changing only when enter is clicked. I am using a mix of swing and javafx.
is this possible?
thanks
exprField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Platform.runLater(new Runnable() {
#Override
public void run() {
fxLabel.setText(exprField.getText());
}
});
}
});
You can use the Binding-Mechanism for this purpose.
GridPane p = new GridPane();
TextField tf = new TextField("DEFAULT");
Label l1 = new Label("...");
l1.textProperty().bind(tf.textProperty());
p.add(tf, 0, 0);
p.add(l1, 1, 0);
Scene sc = new Scene(p, 500, 500);
arg0.setScene(sc);
arg0.show();
This code sets a textbox and a label into a gridpane. The text property of the label is bound to the text property of the textfield, which means as soon as the textfields changes, the text of the label gets updated according to whatever text is now in the textfield.
More information can be found here: http://docs.oracle.com/javafx/2/binding/jfxpub-binding.htm

Make portion of a text bold in a JavaFx Label or Text

In my JavaFx application I need to have a word or two rendered in boldface in the whole sentence. Currently the sentence is rendered as a JavaFx Label but upgrading component also would not allow me set the text as so that I can have the words "Sample" displayed in bold.
String s = "This is a <b>Sample</b> sentence"
Label label = new Label(s);
output
This is a Sample sentence
JavaFx Text also does not allow this. Is there any component where I can have a portion of the text in boldface?
I am not sure if JavaFx WebView is a good idea for rendering many small sentences in a window.
It is possible to use TextFlow container from JavaFX8.
Then you can easily add differently styled Text nodes inside it.
TextFlow flow = new TextFlow();
Text text1=new Text("Some Text");
text1.setStyle("-fx-font-weight: bold");
Text text2=new Text("Some Text");
text2.setStyle("-fx-font-weight: regular");
flow.getChildren().addAll(text1, text2);
TextFlow container will automatically wrap content Text nodes.
Since the previous answers did not include FXML code, I'll post an additional one.
As suggested by #Ernisto, you can use a TextFlow that contains Text parts, where each part can be styled differently.
Example FXML file content:
<TextFlow>
<Text text="Normal text and "/>
<Text text="bold text and " style="-fx-font-weight: bold"/>
<Text text="italic text and " style="-fx-font-style: italic"/>
<Text text="red text." style="-fx-stroke: red"/>
</TextFlow>
Output:
Update: JavaFX 8 provides new control for the rich text: TextFlow
Unfortunately there is no such feature in 2.2, although it may be included into next release.
For now you can try to use next approaches:
HBox with several Label or Text components
WebView
Canvas with several Text components drawn
public class UtilsDialog {
private static final String TAG = "UtilsDialog";
private static boolean sIsShowing = false;
public static void showDialogShowError(String title, String msg, String defaultStyle,
#Nullable String customStyle, String... styledWords) {
if (sIsShowing) return;
Stage dialogStage = new Stage(StageStyle.UTILITY);
dialogStage.initModality(Modality.APPLICATION_MODAL);
dialogStage.setWidth(400);
dialogStage.setHeight(220);
BorderPane borderPane = new BorderPane();
borderPane.setPadding(new Insets(15));
borderPane.setPrefWidth(Integer.MAX_VALUE);
borderPane.setPrefHeight(Integer.MAX_VALUE);
Scene scene = new Scene(borderPane);
dialogStage.setScene(scene);
sIsShowing = true;
dialogStage.show();
UtilsGui.closeOnEsc(borderPane, scene);
scene.addEventHandler(KeyEvent.KEY_PRESSED, t -> {
if (t.getCode() == KeyCode.ESCAPE) {
sIsShowing = false;
}
});
// Top
Text textTitle = new Text(title);
textTitle.setStyle("-fx-font-size: 18px;");
HBox hBoxTop = new HBox(10);
hBoxTop.getChildren().addAll(textTitle);
borderPane.setTop(hBoxTop);
// Center
TextFlow textFlow = new TextFlow();
List<String> words = Arrays.asList(msg.split(" "));
List<String> styledWordsList = Arrays.asList(styledWords);
for (String word : words) {
Text tmpWord = new Text(word);
if (styledWordsList.contains(word
.replace(".", "")
.replace(",", "")
.replace("?", "")
.replace("!", "")
.replace(";", "")
.replace("\n", "")
)) {
tmpWord.setStyle(customStyle);
} else {
if (defaultStyle == null) {
tmpWord.setStyle("");
} else {
tmpWord.setStyle(defaultStyle);
}
}
tmpWord.setText(tmpWord.getText());
textFlow.getChildren().add(tmpWord);
textFlow.getChildren().add(new Text(" "));
}
Text textMsg = new Text(msg);
textMsg.setStyle("-fx-font-size: 14px;");
HBox hBoxInputPane = new HBox(10);
hBoxInputPane.setAlignment(Pos.CENTER);
VBox vBoxCenter = new VBox(10);
vBoxCenter.setPadding(new Insets(25, 0, 15, 0));
vBoxCenter.getChildren().addAll(textFlow);
borderPane.setCenter(vBoxCenter);
JFXButton btnOk = new JFXButton("OK");
btnOk.setAlignment(Pos.CENTER_RIGHT);
btnOk.setStyle("-fx-text-fill: WHITE; -fx-background-color: #5264AE; -fx-font-size: 14px;");
btnOk.setOnAction(event -> {
sIsShowing = false;
dialogStage.close();
});
// Bottom
HBox hBoxBottom = new HBox();
final Pane spacer = new Pane();
HBox.setHgrow(spacer, Priority.ALWAYS);
hBoxBottom.getChildren().addAll(spacer, btnOk);
borderPane.setBottom(hBoxBottom);
// store on close
dialogStage.setOnCloseRequest(event -> sIsShowing = false);
}
}
call:
UtilsDialog.showDialogShowError("Test", "This is the message to show. Does it work?",
null, "-fx-font-weight: bold", "This", "message", "show");

Resources