I have a ListView with String's items. I created an override method setOnMouseClicked for Button. When we push it, ListView create new item and we can edit the name of it. But then I need take this name of item. So I can't do this... Maybe I should use a theads? Hope for yours answers.
Main problem - How I can get item's name after I edited it?
Code:
#Override
public void start(Stage stage) throws Exception {
File file = new File("D:\\");
String[] filesName = file.list();
ObservableList<String> Langs = FXCollections.observableArrayList(filesName);
ListView<String> langsListView = new ListView<String>(Langs);
Button BtnBack = new Button();
Button CreateDir = new Button();
CreateDir.setText("New Directory");
BtnBack.setText("Back");
ArrayList<String> z = new ArrayList<String>();
z.add(file.getPath());
CreateDir.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
langsListView.setEditable(true);
langsListView.getItems().add(0,"");
langsListView.setCellFactory(TextFieldListCell.forListView());
langsListView.layout();
langsListView.edit(0);
langsListView.setEditable(false);
//I need that next code is working but it isn't... don't know why.
String newDir = new String();
for (String s : z)
newDir += s;
File newfile = new File(newDir+langsListView.getItems().get(0));
System.out.println(newDir + langsListView.getItems().get(0));
}
});
FlowPane BtnPane = new FlowPane(10,10,BtnBack, CreateDir);
FlowPane root = new FlowPane(BtnPane,langsListView);
Scene scene = new Scene(root, 600, 500);
stage.setScene(scene);
stage.setTitle("ListView in JavaFX");
stage.show();
}
Related
I would like to add items to a table dynamically.
I do it like this:
public class TestApp extends Application {
public static void main(final String[] args) {
launch(args);
}
private final AtomicLong counter = new AtomicLong();
#Override
public void start(final Stage primaryStage) {
final VBox root = new VBox(5);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);
final TableView<String> tableView = new TableView<>();
final TableColumn<String, String> column = new TableColumn<>("Text");
column.setCellValueFactory(f -> new SimpleStringProperty(f.getValue()));
tableView.getColumns().add(column);
// Add some sample items to our TableView
for (int i = 0; i < 100; i++) {
tableView.getItems().add("Item #" + counter.incrementAndGet());
}
final Button button = new Button("Add items");
final long oldElement = counter.get();
button.setOnAction(e -> {
// Add more elements
for (int i = 0; i < 10; i++) {
tableView.getItems().add("Item #" + counter.incrementAndGet());
}
tableView.scrollTo("Item #" + oldElement);
});
root.getChildren().add(button);
root.getChildren().add(tableView);
// Show the Stage
primaryStage.setWidth(300);
primaryStage.setHeight(300);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
(Example taken from here)
What I would like to change now, is, that when the table is already scrolled down completely, and I add more items, the table automatically scrolls down.
The 'scroll-state' seems to be maintained, which is why I still see the very bottom of the table (and the new elements).
How can I add items to the table but keeping the scroll at the current position / current row?
The 'scrollTo' works, but moves the last element from the bottom of the view to the top, which is also a litte irritating.
I am working on an application in JavaFX where I need multiple scenes to switch between. But it seems like I can't have the same item (Example: a toolbar) In multiple scenes, it just shows the item in one of the scenes. Maybe it isn't possible to have the same item in different scenes, so my question is how do I do it then? Do I need multiple stages and if that is the case how do I change between stages? I am not using FXML for this project, we have to code it.. My current code:
public class Main extends Application {
private Label time;
private int minute;
private int hour;
private int second;
public static void main(String[] args) {
launch(args);
}
// CLOCK RUNNING
public void initialize() {
Timeline clock = new Timeline(new KeyFrame(Duration.ZERO, e -> {
Calendar cal = Calendar.getInstance();
second = cal.get(Calendar.SECOND);
minute = cal.get(Calendar.MINUTE);
hour = cal.get(Calendar.HOUR);
//System.out.println(hour + ":" + (minute) + ":" + second);
time.setText(hour + ":" + (minute) + ":" + second);
}),
new KeyFrame(Duration.seconds(1))
);
clock.setCycleCount(Animation.INDEFINITE);
clock.play();
}
#Override
public void start(Stage primaryStage) throws Exception {
//Specify The Size of Scenes, and the scenes.
BorderPane root1 = new BorderPane();
BorderPane root2 = new BorderPane();
Scene scene1 = new Scene(root1, 1100, 900);
Scene scene2 = new Scene(root2,1100,900);
// Get CSS File
scene1.getStylesheets().add("Helmuth.css");
time = new Label("Time:");
initialize();
//ToolBar i want this to be shown in both scenes //
Button homebt = new Button("Home");
Button tabelbt = new Button("Tabel");
ToolBar toolBar = new ToolBar();
toolBar.getItems().add(homebt);
toolBar.getItems().add(tabelbt);
toolBar.getItems().add(time);
Label label1 = new Label("Welcome to the first scene!");
Button button1 = new Button("Go to scene 2");
button1.setOnAction(e -> primaryStage.setScene(scene2));
VBox layout1 = new VBox();
layout1.getChildren().addAll(button1,toolBar);
Button button2 = new Button("Go Back");
button2.setOnAction(e -> primaryStage.setScene(scene1));
VBox mainbox = new VBox();
mainbox.setAlignment(Pos.TOP_CENTER);
mainbox.getChildren().addAll(button2, toolBar);
// Start scene 1
root2.setCenter(mainbox);
root1.setCenter(layout1);
primaryStage.setScene(scene1);
primaryStage.setTitle("Helmuth");
boolean b = false;
primaryStage.setResizable(b);
primaryStage.show();
}
}
Why do you want to switch between different scenes. A solution to your problem might be to just exchange the root node of the scene.
I have having trouble getting my program to take the user input from textField and displaying it in textArea. The program I'm making is a Stack/Queue program. It has a textField that a user inputs a number into. Then there is a button that takes the input and displays it in the textArea as a Stack(FILO).
Edit 1:
I am able to move the user input into the textArea now but, whenever I add a second input it just replaces the old input with the new instead of showing the list. I am supposed to use a toString method to show the whole list? Where do I need to put the toString method if I need it?
TLDR, How do I take input from textField and display it in textArea?
This is my main class.
TextField text = new TextField();
TextArea textArea = new TextArea("Text Area");
public class StackQueue extends Application
{
#Override
public void start(Stage stage) throws Exception
{
Stack myStack = new Stack();
Button btAdd = new Button("Add");
Button btDel = new Button("Delete");
Button btClear = new Button("Clear");
BorderPane bpane = new BorderPane();
text.setPrefWidth(50);
text.setAlignment(Pos.CENTER_LEFT);
text.setText("Label");
text.clear();
textArea.setPrefColumnCount(1);
textArea.setPrefRowCount(10);
textArea.clear();
HBox hBox = new HBox();
hBox.getChildren().addAll(btAdd, btDel, btClear);
bpane.setTop(hBox);
bpane.setCenter(text);
bpane.setBottom(textArea);
Scene scene = new Scene(bpane, 500, 250);
stage.setTitle("Stack Example");
stage.setScene(scene);
stage.show();
EventHandler<ActionEvent> addEvent = event -> add();
EventHandler<ActionEvent> delEvent = event -> del();
btAdd.setOnAction(addEvent);
btDel.setOnAction(delEvent);
public void add()
{
textArea.setText(text.getText(x));
}
public void del()
{
}
}
public static void main(String[] args)
{
launch(args);
}
}
This is the Stack class.
public class Stack<E>
{
public String status = "String";
public ArrayList<E> arrayList;
public Stack()
{
arrayList = new ArrayList(10);
}
public void add(String x)
{
arrayList.add(0, (E) x);
}
//public String del
{
}
public void Clear()
{
}
}
You have included add() and del() function inside the start() function. You need to move them outside of start() function and inside of your StackQueue class.
After doing that the variables text and textArea should be created outside of start() function because the method add() and del() are trying to get the value of text and textArea variables.
Finally, you should implement the logic to handle addition and deletion of elements inside add() and del() methods.
Paste the following code in StackQueue.java file. I didn't implement the deletion functionality and you need to tweak the add() method too. I hope now you will be able to solve it.
I added a string which will get the old value of text field and append that old value when further addition is done along with the new value
public class StackQueue extends Application {
TextField text = new TextField();
TextArea textArea = new TextArea();
String oldText;
#Override
public void start(Stage stage) throws Exception
{
Stack myStack = new Stack();
Button btAdd = new Button("Add");
Button btDel = new Button("Delete");
Button btClear = new Button("Clear");
BorderPane bpane = new BorderPane();
text.setPrefWidth(50);
text.setAlignment(Pos.CENTER_LEFT);
text.setText("Label");
text.clear();
textArea= new TextArea("Text Area");
textArea.setPrefColumnCount(1);
textArea.setPrefRowCount(10);
textArea.clear();
oldText = text.getText();
HBox hBox = new HBox();
hBox.getChildren().addAll(btAdd, btDel, btClear);
bpane.setTop(hBox);
bpane.setCenter(text);
bpane.setBottom(textArea);
Scene scene = new Scene(bpane, 500, 250);
stage.setTitle("Stack Example");
stage.setScene(scene);
stage.show();
EventHandler<ActionEvent> delEvent = event -> del();
btAdd.setOnAction( e -> {
textArea.setText(oldText + text.getText());
oldText = oldText + text.getText() +"\n";
});
btDel.setOnAction(delEvent);
}
public void del()
{
}
public static void main(String[] args)
{
launch(args);
}
}
I tried using this method to print show a popup with label "THAT'S IT" and I don't want to use the Popup class
public void showStage(Stage Owner){
HBox hBox = new HBox();
hBox.getChildren().add(new Label("THAT'S IT"));
Scene sc = new Scene(hBox);
Stage popup = new Stage();
popup.setScene(sc);
popup.setWidth(400);
popup.setHeight(100);
popup.initOwner(owner);
popup.initModality(Modality.WINDOW_MODAL);
popup.show();
}
and then I call the showStage() method from the start method
public void start(Stage primaryStage) {
Label lb = new Label();
btn.setText("Say 'Hello World'");
btn.setOnAction(e->{
lb.setText("hello everyone");showStage(primaryStage);
});
But the output of the code :
Why don't you use a dialog?
You can use it in your main controller class without creating an other stage for instance like this:
Dialog dialogQtPrescription = new Dialog();
dialogQtPrescription.setTitle("yourTitle");
dialogQtPrescription.setHeaderText("yourHeadertext");
dialogQtPrescription.initModality(Modality.WINDOW_MODAL);
dialogQtPrescription.initOwner(mainStage);
dialogQtPrescription.initStyle(StageStyle.UTILITY);
GridPane gridDialogPrescription = new GridPane();
gridDialogPrescription.setHgap(10);
gridDialogPrescription.setVgap(10);
gridDialogPrescription.add(new Label(bundle.getString("quantityPrescription.title")), 0, 0);
TextField txtQtPrescr = new TextField();
ButtonType buttonTypeNo = new ButtonType("no");
ButtonType buttonTypeYes = new ButtonType("yes");
ButtonType buttonTypeCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
dialogQtPrescription.getDialogPane().getButtonTypes().addAll(buttonTypeNo,buttonTypeYes, buttonTypeCancel);
txtQtPrescr.setPrefWidth(100);
gridDialogPrescription.add(txtQtPrescr, 1, 0);
dialogQtPrescription.getDialogPane().setContent(gridDialogPrescription);
Optional<ButtonType> result = dialogQtPrescription.showAndWait();
this is just a stack of code from a project but i hope it make you to understand my idea.
here's better explained: http://code.makery.ch/blog/javafx-dialogs-official/
You can use this in order to make a Popup on any Screen in JavaFX
public void popup() {
final Stage dialog = new Stage();
dialog.setTitle("Confirmation");
Button yes = new Button("Yes");
Button no = new Button("No");
Label displayLabel = new Label("What do you want to do ?");
displayLabel.setFont(Font.font(null, FontWeight.BOLD, 14));
dialog.initModality(Modality.NONE);
dialog.initOwner((Stage) tableview.getScene().getWindow());
HBox dialogHbox = new HBox(20);
dialogHbox.setAlignment(Pos.CENTER);
VBox dialogVbox1 = new VBox(20);
dialogVbox1.setAlignment(Pos.CENTER_LEFT);
VBox dialogVbox2 = new VBox(20);
dialogVbox2.setAlignment(Pos.CENTER_RIGHT);
dialogHbox.getChildren().add(displayLabel);
dialogVbox1.getChildren().add(yes);
dialogVbox2.getChildren().add(no);
yes.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
// inside here you can use the minimize or close the previous stage//
dialog.close();
}
});
no.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
dialog.close();
}
});
dialogHbox.getChildren().addAll(dialogVbox1, dialogVbox2);
Scene dialogScene = new Scene(dialogHbox, 500, 40);
dialogScene.getStylesheets().add("//style sheet of your choice");
dialog.setScene(dialogScene);
dialog.show();
}
I want to bind text field to indicate whether list of integer contain 1.
i have a button that insert 1 to the list and I want the text field will update but this doesn't happens. why and how can i repair it?
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
final List<Integer> list = new ArrayList<Integer>();
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
list.add(1);
}
});
TextField txt = new TextField();
txt.textProperty().bind(new SimpleStringProperty(String.valueOf(list.contains(1))));
VBox root = new VBox();
root.getChildren().addAll(btn,txt);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
Try creating a BooleanBinding:
#Override
public void start( final Stage primaryStage )
{
primaryStage.setTitle( "Hello World!" );
final List<Integer> list = new ArrayList<>();
// we need an ObservableList, duh, to observe!
final ObservableList<Integer> oblist = FXCollections.observableArrayList( list );
Button btn = new Button();
btn.setText( "Say 'Hello World'" );
btn.setOnAction( new EventHandler<ActionEvent>()
{
#Override
public void handle( ActionEvent event )
{
oblist.add( 1 );
}
} );
BooleanBinding bb = Bindings.createBooleanBinding( () -> oblist.contains( 1 ), oblist );
TextField txt = new TextField();
txt.textProperty().bind( bb.asString() );
VBox root = new VBox();
root.getChildren().addAll( btn, txt );
final Scene scene = new Scene( root, 400, 300 );
primaryStage.setScene( scene );
primaryStage.show();
}
I still doesn't understand what problem with my code, can you explain
me please?
Let's break down the code: new SimpleStringProperty(String.valueOf(list.contains(1)));
-> initially list.contains(1) = false
-> String.valueOf(false) = "false"
-> new SimpleStringProperty("false") will create new instance of StringProperty with initial value "false", and this instance is bound to textProperty of textField. That is it, since we are initiating with the String value "false", no further observation for list and its content where it contains 1 or not. Hence we need an observable list here.
Thus the textfield's text will change in sync if the bound StringProperty is changed. Rewriting as,
StringProperty sp = new SimpleStringProperty(String.valueOf(list.contains(1)));
txt.textProperty().bind(sp);
sp.set("newVal"); // at this point textfield's text will be updated with
// "newVal", but it has nothing about list and its content.