I have a VBox, inside multiple TextFlows. How can I make this Text selectable/ copyable?
public class ExampleController implements Initializable {
#FXML
private VBox box;
#Override
public void initialize(final URL location, final ResourceBundle resources) {
final TextFlow tf = new TextFlow();
final Text t0 = new Text("First part");
final Text t1 = new Text(", second");
final Text t2 = new Text(" and third");
t0.getStyleClass().add("first-part-styling");
t1.getStyleClass().add("second-part-styling");
t2.getStyleClass().add("third-part-styling");
tf.getChildren().addAll(t0, t1, t2);
this.box.getChildren().add(tf);
}
}
I use TextFlow and Text, since I need different styling within the same sentence.
You cannot, using Text, as this class is supposed to only display text. But you can use TextFieldinstead:
public class JavaFXTest extends Application {
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
final TextFlow tf = new TextFlow();
final Text t0 = new Text("First part");
final Text t1 = new Text(", second");
final TextField t2 = new TextField(" and third");
t2.setEditable(false);
t2.setBackground(Background.EMPTY);
t2.setFocusTraversable(false);
tf.getChildren().addAll(t0, t1, t2);
root.getChildren().add(tf);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Edit You might take a look at
Rich-text area for JavaFX. This open source project on GitHub provides a styleable text area. Have not tried it, though...
try this
ObservableList<Node> nodesTextFlow = box.getChildren();
StringBuilder sb = new StringBuilder();
for (Node node : nodesTextFlow) {
ObservableList<Node> nodesText = ((TextFlow) node).getChildren();
for (Node node1 : nodesText) {
sb.append((((Text) node1).getText()));
}
}
String txt = sb.toString();
Related
I would like to make a small java fx app that has just textarea and one button on a stage and that when you type some strings in textarea and press submit it shows on the stage small table with results how many each Word had occurrences.
so my questions is: does map is the best solution for finding the occurrences even though I do not know what will be the key for finding occurrences and how to connect string from text area, to map.
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Word counting");
TextArea txt=new TextArea();
txt.setMaxSize(450, 200);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
primaryStage.hide();
ShowResults.drugiProzor();
}
});
BorderPane root = new BorderPane();
root.setTop(txt);
HBox hbox=new HBox();
hbox.setPadding(new Insets(20,20,100,180));
hbox.getChildren().add(btn);
root.setBottom(hbox);
Scene scene = new Scene(root, 450, 300);
primaryStage.setTitle("Word counting!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
and the second class is again gui class with table view
public class ShowResults {
static Stage secondaryStage;
public static void drugiProzor() {
secondaryStage=new Stage();
TableView table=new TableView();
TableColumn column1=new TableColumn("Word");
column1.setMinWidth(200);
TableColumn column2=new TableColumn("Number of occurencies");
column2.setMinWidth(200);
table.getColumns().addAll(column1,column2);
StackPane pane=new StackPane();
pane.getChildren().add(table);
Scene scene = new Scene(pane, 450, 300);
secondaryStage.setScene(scene);
secondaryStage.setTitle("Counting words");
secondaryStage.show();
}
}
and third class shoyld be the class where the magic happends something like this:
public class Logic {
public void logic()
}
}
You can just do something like
public Map<String, Long> countWordOccurences(String text) {
return Pattern.compile("\\s+") // regular expression matching 1 or more whitespace
.splitAsStream(text) // split at regular expression and stream words between
// group by the words themselves and count each group:
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}
Check the Javadocs to see what each step is doing: Pattern, Collectors.groupingBy(), Function, etc.
If you want to count in a case-insensitive way, you can replace Function.identity() with String::toLowerCase
.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
and if you want to ignore punctuation, you can add
map(s -> s.replaceAll("[^a-zA-Z]",""))
to the pipeline.
Here is my code, I'm trying to load a splash screen image with transparent background before my main stage starts. They come almost at the same time, but the big problem is I get a grey rectangle before anything else: .
Here is the code:
public class Menu extends Application {
private Pane splashLayout;
private Stage mainStage;
private ImageView splash;
// Creating a static root to pass to ScreenControl
private static BorderPane root = new BorderPane();
public void start(Stage splashStage) throws IOException {
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.splash = new ImageView(new Image(getClass().getResource("/splash.png").toString()));
splashStage.initStyle(StageStyle.TRANSPARENT);
showSplash(splashStage, screenSize);
// Constructing our scene using the static root
root.setCenter(new ScrollPane);
Scene scene = new Scene(root, screenSize.getWidth(), screenSize.getHeight());
showMainStage(scene);
if (splashStage.isShowing()) {
mainStage.setIconified(false);
splashStage.toFront();
FadeTransition fadeSplash = new FadeTransition(Duration.seconds(1.5), splashLayout);
fadeSplash.setDelay(Duration.seconds(3.5));
fadeSplash.setFromValue(1.0);
fadeSplash.setToValue(0.0);
fadeSplash.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
splashStage.hide();
}
});
fadeSplash.play();
}
}
private void showMainStage(Scene scene) {
mainStage = new Stage(StageStyle.DECORATED);
mainStage.setTitle("book-depot");
mainStage.getIcons().add(new Image(getClass().getResourceAsStream("/icon.png")));
mainStage.setScene(scene);
mainStage.show();
}
private void showSplash(Stage splashStage, Dimension screenSize) {
splashLayout = new StackPane();
splashLayout.setStyle("-fx-background-color: transparent;");
splashLayout.getChildren().add(splash);
Scene splashScene = new Scene(splashLayout, 690, 590);
splashScene.setFill(Color.TRANSPARENT);
splashStage.setScene(splashScene);
splashStage.show();
}
public void mainGui(String[] args) {
launch(args);
}
}
Am I doing something wrong or I really can't get a transparent background?
This is what it looks like when also the other stage loads up, but I'd like it to work like that even before the main stage loads, or at least I'd want to remove the grey rectangle you can see in the other screenshot
The grey background is your "mainStage" since you are showing splash and main stages at the same time. At the beginning while showing the splash stage you can just init (not show) the main stage and show it later when the animation finishes:
public class ModifiedMenu extends Application
{
private Pane splashLayout;
private Stage mainStage;
private ImageView splash;
// Creating a static root to pass to ScreenControl
private static BorderPane root = new BorderPane();
public void start(Stage splashStage) throws IOException {
final Dimension2D screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.splash = new ImageView(new Image(getClass().getResource("/splash.png").toString()));
splashStage.initStyle(StageStyle.TRANSPARENT);
showSplash(splashStage, screenSize);
// Constructing our scene using the static root
root.setCenter(new ScrollPane());
Scene scene = new Scene(root, screenSize.getWidth(), screenSize.getHeight());
initMainStage(scene);
if (splashStage.isShowing()) {
splashStage.toFront();
FadeTransition fadeSplash = new FadeTransition(Duration.seconds(1.5), splashLayout);
fadeSplash.setDelay(Duration.seconds(3.5));
fadeSplash.setFromValue(1.0);
fadeSplash.setToValue(0.0);
fadeSplash.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
splashStage.hide();
mainStage.show();
}
});
fadeSplash.play();
}
}
private void initMainStage(Scene scene) {
mainStage = new Stage(StageStyle.DECORATED);
mainStage.setTitle("book-depot");
mainStage.getIcons().add(new Image(getClass().getResourceAsStream("/icon.png")));
mainStage.setScene(scene);
}
private void showSplash(Stage splashStage, Dimension2D screenSize) {
splashLayout = new StackPane();
splashLayout.setStyle("-fx-background-color: transparent;");
splashLayout.getChildren().add(splash);
Scene splashScene = new Scene(splashLayout, 690, 590);
splashScene.setFill(Color.TRANSPARENT);
splashStage.setScene(splashScene);
splashStage.show();
}
public void mainGui(String[] args) {
launch(args);
}
}
I added a borderpane which contains text to a javafx scene.
How do you update a scene in javafx ?
I would like to do this so that i can reflec the changes dynamically.
So a sample would look like this :
My gui : text
dynamic update
My gui : updated text
public class JFXPnlRef extends JFXPanel {
public JFXPnlRef(){
this.init();
}
private void init(){
Platform.setImplicitExit(false);
/* run gui main scene */
Platform.runLater(new Runnable(){
#Override
public void run(){
createScene();
}
});
}
private void createScene(){
/* we are in the JFX thread */
/* set our look and feel style for the gui */
borderPane = new BorderPane();
final Text text = new Text();
text.setFont(new Font(25));
text.setText("javafx threads!");
borderPane.setLeft(text);
scene = new Scene(borderPane);
this.setScene(scene);
}
public void myThread(){
JFXPnlThrd.run( new Runnable() {
#Override
public void run() {
final Text text = new Text();
text.setFont(new Font(25));
text.setText("inside the thread!");
scene.getRoot().getChildrenUnmodifiable();
Parent root = scene.getRoot();
ObservableList<Node> i = root.getChildrenUnmodifiable();
/* use the root node to add stuff to the border pane ? */
revalidate();
repaint();
updateUI();
}
}); //end of thread
}//end of method
}//end of class
/ * outter class to check if we are in the javafx thread */
public class JFXPnlThrd {
public static void run(Runnable task) {
if(task == null)
throw new IllegalArgumentException(
"The task can not be null");
if(Platform.isFxApplicationThread()) task.run();
else Platform.runLater(task);
}
}
Thank you ItachiUchiha!
The answer was simple.
Move the local Text defined as
final Text text = new Text();
to a class instance variable
private Text text;
I am new to use javafx i want to use list with unique element in javafx how i can manage it . Display the Content of List view should be unique duplicates value get skipped.
thank you
static ObservableList<String> items = FXCollections.observableArrayList();
static ObservableList<String> bamitems = FXCollections
.observableArrayList();
static ListView<String> list;
static ListView<String> listforbam;
public static void test() throws Exception {
HBox root = new HBox();
VBox yesaccordion = new VBox();
Accordion acc = new Accordion();
acc.getPanes().addAll(createPanes());
yesaccordion.getChildren().add(acc);
root.getChildren().addAll(yesaccordion);
jfxpanel.setScene(new Scene(root, 200, 100));
panel.add(jfxpanel);
items.addAll(LoadVCFFileToTrack.destitemlist);
bamitems.addAll(LoadVCFFileToTrack.destitemBamlist);
if (LoadVCFFileToTrack.destitemBamlist.size() > 0) {
listforbam = new ListView<String>();
listforbam.setItems(bamitems);
}
if (LoadVCFFileToTrack.destitemlist.size() > 0) {
list = new ListView<String>();
list.setItems(items);
}
Use a Set or better an ObservableSet to store the items you want to display in the ListView.
To add the set to the list view you can use FXCollections.observableArrayList(Collection col) method. It will convert the ObservableSet to ObservableArrayList.
listView.setItems(FXCollections.observableArrayList(observableSet));
Complete example
public class Main extends Application {
#Override
public void start(Stage stage) {
ObservableSet<String> observableSet = FXCollections.observableSet();
//Item1 is repeated twice
observableSet.addAll(Arrays.asList("Item1","Item2","Item3", "Item1"));
ListView<String> listView = new ListView<>();
listView.setItems(FXCollections.observableArrayList(observableSet));
stage.setScene(new Scene(listView, 200, 200));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I am making a school project in JAVAFX and I can't figure out how to collide with my 2 objects(bullet and enemy tank). Can someone tell me the right way to do it? I am trying more than 3 weeks... google everything but still not working.
public class TankGame extends Application {
private final static int WIDTH = 800;
private final static int HEIGHT = 600;
private final static Image BACKGROUND_IMAGE = new Image(TankGame.class.getResource("imgs/Tank_back.png").toString());
private final static Image PATRONA = new Image(TankGame.class.getResource("imgs/Tank_patrona.png").toString());
private Animation modelAnimacePatrony;
private Group patrona;
private double smerStrelyX, smerStrelyY;
private Otaceni otaceni = new Otaceni();
private TankHrac tankHrac = new TankHrac();
private TankProtivnik tankProtivnik = new TankProtivnik();
#Override
public void start(Stage primaryStage) {
final ImageView background = new ImageView(BACKGROUND_IMAGE);
final ImageView bullet = new ImageView(PATRONA);
patrona = new Group(bullet);
final Group root = new Group(background, tankHrac, tankProtivnik, patrona);//deti
patrona.setVisible(false);
Scene scene = new Scene(root, WIDTH, HEIGHT); //okno
tankHrac.setTranslateX(50);//defaultni vyskyt modelu
tankHrac.setTranslateY(50);//defaultni vyskyt modelu
tankProtivnik.setTranslateX(350);//defaultni vyskyt modeluProtivnika
tankProtivnik.setTranslateY(150);//defaultni vyskyt modeluProtivnika
smerStrelyX = tankHrac.getTranslateX();
smerStrelyY = tankHrac.getTranslateY()-250;
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
/**
* Shooting
*/
if( ke.getCode() == KeyCode.SPACE ) {
if(!patrona.isVisible()){
//patrona.setVisible(true);
shooting(smerStrelyX,smerStrelyY, tankHrac);
}
}
}
});
primaryStage.setTitle("Tank 1.0");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setResizable(false);
}
public void shooting(double smerStrelyX, double smerStrelyY, TankHrac jakyModelTanku){
patrona.setVisible(true);
modelAnimacePatrony = TranslateTransitionBuilder.create()
.node(patrona)
.fromX(jakyModelTanku.getTranslateX()+30)
.toX(smerStrelyX+30)
.fromY(jakyModelTanku.getTranslateY()+30)
.toY(smerStrelyY+30)
.duration(Duration.seconds(1))
.onFinished(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent t){
modelAnimacePatrony.stop();
patrona.setVisible(false);
}
})
.build();
modelAnimacePatrony.play();
}
here are all source files: https://www.dropbox.com/sh/1iq98jtxh8m06tt/7Y9LQSjfYs