I have a modal dialog that I pop up, which contains text boxes. If the user has the mouse over the text box (so the TEXT cursor shows) and then hits Enter to close the dialog, the cursor gets left in the TEXT state. So far I have found no way programmatically to change it back to the DEFAULT state. If I try some other cursor on the main scene (like HAND or MOVE) it works. But DEFAULT does not.
I'm using JavaFx / JDK 1.7 that was "fresh" when I downloaded within the last couple of months. I'm on Windows 8.1.
I've searched the web a fair bit and haven't found any mention of it. Is this a known bug? Can anybody suggest a workaround or explain what is going on?
Code sample follows. Simply click on the text edit in the dialog, keep the mouse over the textbox so the cursor is TEXT, and hit Enter.
package jfxtest;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class Jfxtest extends Application {
public static void main(String[] args) {
launch(args);
}
#Override public void start(final Stage primaryStage) {
Button btn = new Button();
btn.setText("Open Dialog");
btn.setOnAction(
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
final Stage dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(primaryStage);
final TextField txt = new TextField("Hit Enter while I have focus and the mouse is over me!");
txt.setMinWidth(280);
Button btnOk = new Button("OK");
btnOk.setDefaultButton(true);
btnOk.setOnAction(
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
// these don't work
txt.setCursor(Cursor.DEFAULT);
dialog.getScene().setCursor(Cursor.DEFAULT);
primaryStage.getScene().setCursor(Cursor.DEFAULT);
dialog.close();
// and these don't work
txt.setCursor(Cursor.DEFAULT);
dialog.getScene().setCursor(Cursor.DEFAULT);
primaryStage.getScene().setCursor(Cursor.DEFAULT);
}
} );
VBox dialogVbox = new VBox(20);
dialogVbox.getChildren().add(txt);
dialogVbox.getChildren().add(btnOk);
Scene dialogScene = new Scene(dialogVbox, 300, 200);
dialog.setScene(dialogScene);
dialog.showAndWait();
// and these doesn't work
dialogScene.setCursor(Cursor.DEFAULT);
primaryStage.getScene().setCursor(Cursor.DEFAULT);
// but this works as expected (!), although it doesn't solve my problem
// primaryStage.getScene().setCursor(Cursor.HAND);
}
} );
VBox vbox = new VBox(20);
vbox.getChildren().add(btn);
Scene scene = new Scene (vbox, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
}
I need to show a Panel with an extra options in the same Scene when I click on the Button, but I've no idea how to achieve this behaviour. The problem that the Stage not resizing when I add panel to root VBox.
I've written simple code to demonstrate the problem.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) throws Exception {
final VBox root = new VBox();
Button button = new Button("add label");
root.getChildren().add(button);
button.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
root.getChildren().add(new Label("hello"));
}
});
stage.setScene(new Scene(root));
stage.show();
}
}
I suppose I need to call some method to notify root container to do layout, but all methods I try haven't brought me desired results.
Program Works
Your program is working almost as you expect I think (when you click the "add label" button, a new label is added to the scene).
Why you can't see it working
You can't see the newly added label as a stage is sized by default to fit the initial content of the scene. When you add more area to the scene, the stage won't be automatically resized to encompass the new area.
What to do to see it work
Manually resize the stage window after adding a label.
OR
Set an initial size for the scene so that you can see the newly added labels.
stage.setScene(new Scene(root, 200, 300));
OR
After you add each new label, size the stage to the scene.
stage.sizeToScene();
just change the code
button.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
root.getChildren().add(new Label("hello"));
stage.sizeToScene();
}
});
actually i'm looking for something very similar to this thread:
How to hide the controls of HTMLEditor?
so basically i try to add a custom button to the javafx html editor but with the difference that it's implemented through FXML.
So my question is:
Is there a "work-around" to add custom buttons to the html-editor when it's implemented through FXML?
Sample solution is :
htmlEditor.setVisible(false);
Platform.runLater(new Runnable() {
#Override
public void run() {
Node[] nodes = htmlEditor.lookupAll(".tool-bar").toArray(new Node[0]);
for (Node node : nodes) {
node.setVisible(false);
node.setManaged(false);
}
htmlEditor.setVisible(true);
}
});
I have modified the #jewelsea answer for javaFX9.
I have also added some customization to move toolbars. The main idea is to get all the components by css selector, then modify or hide them. Read the class HTMLEditorSkin to get the CSS classes names, like ".html-editor-align-center" for the align button.
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.control.RadioMenuItem;
import javafx.scene.control.ToolBar;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.web.HTMLEditor;
import javafx.stage.Stage;
public class HTMLEditorCustomizationSample2 extends Application {
// limits the fonts a user can select from in the html editor.
private static final ObservableList<String> limitedFonts = FXCollections.observableArrayList("Arial",
"Times New Roman", "Courier New", "Comic Sans MS");
private HTMLEditor htmlEditor;
public static void main(String[] args) {
launch(args);
}
#SuppressWarnings("unchecked")
#Override
public void start(Stage stage) {
htmlEditor = new HTMLEditor();
stage.setScene(new Scene(htmlEditor));
stage.show();
customizeEditor(htmlEditor);
}
private void customizeEditor(HTMLEditor htmlEditor) {
// hide controls we don't need.
Node seperator = htmlEditor.lookup(".separator");
seperator.setVisible(false);
seperator.setManaged(false);
hideByClass(htmlEditor, ".separator");
hideByClass(htmlEditor, ".html-editor-cut", ".html-editor-copy", ".html-editor-paste", ".html-editor-strike",
".html-editor-hr");
hideByClass(htmlEditor, ".html-editor-align-left"
, ".html-editor-align-center"
, ".html-editor-align-right"
, ".html-editor-align-justify", ".html-editor-outdent"
, ".html-editor-indent", ".html-editor-bullets"
, ".html-editor-numbers");
// Move the toolbars
Node top= htmlEditor.lookup(".top-toolbar");
GridPane.setConstraints(top,1,0,1,1);
Node bottom= htmlEditor.lookup(".bottom-toolbar");
GridPane.setConstraints(bottom,0,0,1,1);
Node web= htmlEditor.lookup("WebView");
GridPane.setConstraints(web,0,1,2,1);
// modify font selections.
int i = 0;
Set<Node> fonts = htmlEditor.lookupAll(".font-menu-button");
Iterator<Node> fontsIterator = fonts.iterator();
fontsIterator.next();
ComboBox<String> formatComboBox = (ComboBox<String>) fontsIterator.next();
formatComboBox.itemsProperty().addListener((obs, old, value) -> {
if (value.size() != limitedFonts.size()) {// should loop on array for equality
Platform.runLater(() -> {
value.clear();
// stop.set(true);
value.addAll(limitedFonts);
formatComboBox.setValue(limitedFonts.get(0));
});
}
});
// add a custom button to the top toolbar.
Node node = htmlEditor.lookup(".top-toolbar");
if (node instanceof ToolBar) {
ToolBar bar = (ToolBar) node;
ImageView graphic = new ImageView(
new Image("http://bluebuddies.com/gallery/title/jpg/Smurf_Fun_100x100.jpg", 16 , 16, true, true));
graphic.setEffect(new DropShadow());
Button smurfButton = new Button("", graphic);
bar.getItems().add(smurfButton);
smurfButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
htmlEditor.setHtmlText("<font face='Comic Sans MS' color='blue'>Smurfs are having fun :-)</font>");
}
});
}
}
private void hideByClass(HTMLEditor htmlEditor, String... selectors) {
for (String selector : selectors) {
Set<Node> nodes = htmlEditor.lookupAll(selector);
for (Node node : nodes) {
node.setVisible(false);
node.setManaged(false);
}
}
}
#Override
public void stop() throws Exception {
super.stop();
System.out.println(htmlEditor.getHtmlText());
}
}
Here is some sample code which customizes the HTMLEditor and adds a custom button to it. The sample code does not use fxml but really it's very similar if fxml is used. You could define the HTMLEditor in fxml and inject it into your Controller using the standard #FXML annotation. Once you have a reference to the editor, customize it in Java code using an appropriate variation of the sample code. For the added button, just create it in Java rather than fxml and it will be simpler.
I want to create a borderpane what is transparent.I tried setting background color to transparent but it appears white. plz let me know if there is a way.
Code i tried.
BorderPane root=new BorderPane();
root.setStyle("-fx-background-color:transparent");
Scene scene=new Scene(root);
stage.setScene(scene);
stage.show();
Thank you...
Try setting the stage to transparent:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class TransparentStage extends Application {
#Override
public void start(Stage stage) {
// important line
stage.initStyle(StageStyle.TRANSPARENT);
Text text = new Text("Transparent!");
text.setFont(new Font(40));
VBox box = new VBox();
box.getChildren().add(text);
final Scene scene = new Scene(box,300, 250);
scene.setFill(null);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This is not working for me, the context menu doesn't get displayed:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
/**
*
* #author Alvaro
*/
public class TextAreaContextMenu extends Application {
Group root = new Group();
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(root));
TextArea t = new TextArea();
ContextMenu m = new ContextMenu();
m.setOnShowing(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent arg0) {
System.out.println("Showing...");
}
});
MenuItem item = new MenuItem("Item");
m.getItems().add(item);
t.setContextMenu(m);
root.getChildren().add(t);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Is this a bug? or am I doing something wrong?
I'm running jdk1.7.0_02, and I think JavaFX 2.0.2 SDK.
BTW, how do I find out, exactly which JavaFX SDK version I have installed?
Thanks in advance for any help.
Your code works for me with JavaFX 2.1 dev build on Windows. Right-click on text area shows menu with one element named "item".
Can you try 2.1 dev version?
You can find out your current version by running next code:
System.out.println(com.sun.javafx.runtime.VersionInfo.getVersion());