Results 1 to 14 of 14
  1. #1
    diolu is offline Member
    Join Date
    Jan 2017
    Posts
    26
    Rep Power
    0

    Default When node are actually displayed; dynamically change pane.

    I am confused when exactly shapes are actually displayed in javafx. Just consider this example code (adapted from Introduction to java Programming, by Y.D. Liang):

    Java FX Code:
    import javafx.application.Application;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.scene.shape.Polygon;
    import java.util.*;
    
    public class ShowPolygon extends Application {
        @Override // Override the start method in the Application class
        public void start(Stage primaryStage) {
            Scanner input = new Scanner(System.in);
            // Create a pane, a polygon, and place polygon to pane
            Pane pane = new Pane();
            Polygon polygon = new Polygon();
            pane.getChildren().add(polygon); 
            polygon.setFill(Color.WHITE);
            polygon.setStroke(Color.BLACK);
            ObservableList<Double> list = polygon.getPoints();
        
            final double WIDTH = 200, HEIGHT = 200;
            double centerX = WIDTH / 2, centerY = HEIGHT / 2;
            double radius = Math.min(WIDTH, HEIGHT) * 0.4;
    
            // Add points to the polygon list
            for (int i = 0; i < 6; i++) {
                list.add(centerX + radius * Math.cos(2 * i * Math.PI / 6)); 
                list.add(centerY - radius * Math.sin(2 * i * Math.PI / 6));
            }
    
            // Create a scene and place it in the stage
            Scene scene = new Scene(pane, WIDTH, HEIGHT);
            primaryStage.setTitle("ShowPolygon"); // Set the stage title
            primaryStage.setScene(scene); // Place the scene in the stage
            primaryStage.show(); // Display the stage
            
            // Polygon not displayed.
            System.out.print("Press Enter"); input.nextLine();
            
            for (int i = 0; i < 5; i++) {
                 list.add(centerX + radius * Math.cos(2 * i * Math.PI / 5));
                list.add(centerY - radius * Math.sin(2 * i * Math.PI / 5));
             }
        }
      
        /**
         * The main method is only needed for the IDE with limited
         * JavaFX support. Not needed for running from the command line.
         */
        public static void main(String[] args) {
            launch(args);
        }
    }
    At line 38 (just before prompting the user to press enter); no polygon is displayed only after I press enter, the hexagon and pentagon part are displayed. I don't understand what truly happen. Can I dynamically change the pane. I expect to display the hexagon, wait for the user to press enter and after display the pentagon. Is it possible?
    Last edited by diolu; 02-17-2017 at 12:59 PM.

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,532
    Rep Power
    24

    Default Re: When node are actually displayed; dynamically change pane.

    That start() method executes in the UI thread so nothing can be displayed until that method exits.
    It's similar to a UI event handler, if you like.

    In order to do what you want you'll need something outside that thread to sit handle the wait for the user to hit <enter> and then that would inform the GUI code to draw the next part.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  3. #3
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,904
    Rep Power
    30

    Default Re: When node are actually displayed; dynamically change pane.

    Moved to JavaFX section
    If you don't understand my response, don't ignore it, ask a question.

  4. #4
    diolu is offline Member
    Join Date
    Jan 2017
    Posts
    26
    Rep Power
    0

    Default Re: When node are actually displayed; dynamically change pane.

    @Tolls. Thak you, you pointed me in the right direction. I am very new to GUI programming and I try to understand the concepts involved. Actually, looking in the "thread" chapter, the book I have (Introduction to java programming by Liang, as mentioned) has an example that shows the principle you describe (a simple demo that use a thread to have a text blinking).

    I am still confused about the control flow of a javafx application. What triggers the real display? Actually, the main window is displayed before the start method exits, but not the nodes on them; we just have an empty window. I somehow understand that the following happen:

    1) The start method is launched.
    2) The nodes are constructed in memory.
    3) When the start method exits, the nodes are actually displayed.
    4) It is still possible to make modification from the outside (from another thread for example).

    Is this correct? What exactly triggers the display? Why the methods from the outside thread have an immediately visible effect but not the methods from the start?

  5. #5
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,532
    Rep Power
    24

    Default Re: When node are actually displayed; dynamically change pane.

    There's a single UI thread.
    All UI work is done on that thread, so events, drawing, etc.

    The start() call is an event essentially, and you use it to build your initial layout and plug everything in.
    That runs on the UI thread, so no other UI thing can happen until start() has finished.
    When you build your UI there you are queuing up redraw events (each time you add something to a container).
    When start() completes then the next event can be handled, and so on. That event will usually involve drawing the screen.

    Once it's all up then the UI thread will sit there and wait for events to happen.
    So when you click a button then that event fires and is picked up and any listeners are executed.

    You might also have events from outside the UI. This is what you want in your case.
    You want an external event to tell the UI to draw the next polygon. To do that you need another thread whose job is to just sit there and wait for the user to hit <enter> on a console.
    That external thread will call a method (there's usually a specific way to get this to run on the UI thread) that is essentially treated as an event.

    Hope that makes some sense.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  6. #6
    benji2505 is offline Senior Member
    Join Date
    Sep 2014
    Location
    MA, USA
    Posts
    381
    Rep Power
    4

    Default Re: When node are actually displayed; dynamically change pane.

    Quote Originally Posted by Tolls View Post
    There's a single UI thread.
    ...
    You might also have events from outside the UI.
    ...
    Excellent explanation.

    JavaFX will love you if you therefore surround your calls to the UI thread with something like

    Java FX Code:
    Platform.runLater(new Runnable() {
    			   @Override
    			   public void run() {
    				   fireStuffAtJavaFXHere();
    			   }
    			});

  7. #7
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,532
    Rep Power
    24

    Default Re: When node are actually displayed; dynamically change pane.

    I thought it might have the same sort of construct as Swing.
    Ta!
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  8. #8
    diolu is offline Member
    Join Date
    Jan 2017
    Posts
    26
    Rep Power
    0

    Default Re: When node are actually displayed; dynamically change pane.

    @Tolls I begin to understand the idea, thanks!

  9. #9
    diolu is offline Member
    Join Date
    Jan 2017
    Posts
    26
    Rep Power
    0

    Default Re: When node are actually displayed; dynamically change pane.

    I am sill confused. Look at this code that displays a dialog:

    Java FX Code:
    import javafx.application.Application;import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.stage.Stage;
    import javafx.scene.control.TextInputDialog;
    import java.util.*;
    import javafx.scene.shape.Circle;
    import javafx.scene.layout.Pane;
    
    
    public class Test extends Application {
      @Override // Override the start method in the Application class
      public void start(Stage primaryStage) {
        Scanner input = new Scanner(System.in);
        // Create a button and place it in the scene
        Circle circle = new Circle(100,100,5);
        Pane pane = new Pane();
        pane.getChildren().add(circle);
        Scene scene = new Scene(pane, 200, 250);
        primaryStage.setTitle("Test"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show();
        TextInputDialog dialog = new TextInputDialog("walter");
        dialog.setTitle("Text Input Dialog");
        dialog.setHeaderText("Look, a Text Input Dialog");
        dialog.setContentText("Please enter your name:");
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent()){
          System.out.println("Your name: " + result.get());
        }
      }
    
    
      public static void main(String[] args) { 
        launch(args);
      }
    }
    Running this code in a debugger, the circle is displayed at line 27, still in the start method. I understand why they have implemented that. But how is it possible? The model I had in mind (update the screen only after each event/start method is completed) would render such things impossible. Somehow, as long as you use javafx things only, everything behaves as would one naively thought. In my first post, if we replace the press enter prompt in a terminal by a javafx dialog, then the polygon will actually be displayed.
    Last edited by diolu; 03-02-2017 at 12:58 PM.

  10. #10
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,532
    Rep Power
    24

    Default Re: When node are actually displayed; dynamically change pane.

    That code builds the screen and then calls show().
    I believe that actually displays the screen, rather than queue an event.

    Do you want the main screen to display, with nothing on it, as well as the dialog?
    Or do you want just the dialog to display and, when the button is clicked, show the screen?
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  11. #11
    diolu is offline Member
    Join Date
    Jan 2017
    Posts
    26
    Rep Power
    0

    Default Re: When node are actually displayed; dynamically change pane.

    @Tolls Of course what I want is what happens; this is the natural thing to want in this case. I am looking here to have a clear idea of the program flow in mind. If I replace the dialog by prompting the user on the terminal, then nothing is displayed. Is it just the display that is delayed? What if I programmatically call methods that examine the state of the program like retrieving the bounds of a node? I always fear that something will be delayed and I can't predict what and when. What would be the code to update the screen without displaying the dialog box? It might not be so simple; I have just no idea.
    Last edited by diolu; 03-02-2017 at 01:19 PM.

  12. #12
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,532
    Rep Power
    24

    Default Re: When node are actually displayed; dynamically change pane.

    I'm not sure where you are confused.
    If I take that code, and place a break on the showAndWait() line (the equivalent of waiting for input from the terminal) then nothing is displayed. Not surprisingly as the GUI thread is blocked.

    Reread the post I made #5. I think that pretty much covers how this works.

    Without something more concrete you are trying to achieve, it's going to be hard to explain in anymore detail.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  13. #13
    diolu is offline Member
    Join Date
    Jan 2017
    Posts
    26
    Rep Power
    0

    Default Re: When node are actually displayed; dynamically change pane.

    @Tolls. The circle is displayed just after the showAndWait() (when you set a break it breaks before executing the line). You will see the difference clearly in this slightly modified example. In the case of the dialog (line 28 executed and line 29 commented out); the circle is displayed when the application pause at line 31. It is not displayed if line 28 is commented out and line 29 executed. Actually, line 28 is able to trigger the display. I want to have a clear idea when exactly nodes are displayed. At first sign line 28 and 29 look similar.

    Java FX Code:
    import javafx.application.Application;import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.stage.Stage;
    import javafx.scene.control.TextInputDialog;
    import java.util.*;
    import javafx.scene.shape.Circle;
    import javafx.scene.layout.Pane;
     
     
    public class Test extends Application {
      @Override // Override the start method in the Application class
      public void start(Stage primaryStage) {
        Scanner input = new Scanner(System.in);
        // Create a button and place it in the scene
        Circle circle = new Circle(100,100,5);
        Pane pane = new Pane();
        pane.getChildren().add(circle);
        Scene scene = new Scene(pane, 200, 250);
        primaryStage.setTitle("Test"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show();
        TextInputDialog dialog = new TextInputDialog("walter");
        dialog.setTitle("Text Input Dialog");
        dialog.setHeaderText("Look, a Text Input Dialog");
        dialog.setContentText("Please enter your name:");
    
        // Comment out ofthe two line below
        dialog.showAndWait();
        // System.out.print("Press enter: "); input.nextLine();
    
        System.out.print("Look if the circle is displayed before pressing Enter"); input.nextLine();
        
      }
        
        public static void main(String[] args) { 
        launch(args);
      }
    }

  14. #14
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,532
    Rep Power
    24

    Default Re: When node are actually displayed; dynamically change pane.

    Looks like the dialog (or more specifically the showAndWait) takes over, and the GUI displays.

    You're seeing weird stuff because the API states that this:
    ... must not be called during animation or layout processing.
    and the start() method is part of layout processing.

    So all bets are off, since you wouldn't do this normally anyway.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

Similar Threads

  1. Replies: 7
    Last Post: 01-22-2016, 08:32 PM
  2. Change JList contents after it's already been displayed?
    By LucienMontierre in forum AWT / Swing
    Replies: 2
    Last Post: 05-04-2012, 06:10 AM
  3. Can't change the background of my content pane
    By jiffi in forum AWT / Swing
    Replies: 29
    Last Post: 12-11-2011, 06:04 PM
  4. Replies: 5
    Last Post: 05-09-2011, 07:28 AM
  5. Update the JFrame after change the Content Pane
    By alisonchan30 in forum AWT / Swing
    Replies: 1
    Last Post: 04-26-2010, 07:22 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •