Best way to update a huge number of buttons at the same time?

Best way to update a huge number of buttons / nodes at the same time?

I apologize in advance, this is my first StackOverflow question ...

So, I created an emulator for the specific in the home device that we are creating. This device has a button on it that flashes with an LED at a speed of 100 ms.

So, I basically created a view similar to an embedded device. I installed a button on my view that blinks throughbtn.setStyle("-fx-background-color: #"+rgb";");

This works fine and that’s it, but when I add 100 of these “Devices” on my screen, the unsafe processor rockets and the application become unusable.

Here, I hope, some relevant code snippets:

This code fragment calls the method Updateon Deviceif it is currently displayed:

final Duration oneFrameAmt = Duration.millis(10);
    final KeyFrame oneFrame = new KeyFrame(oneFrameAmt, new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent arg0) {
            updateDrawnEntities();
        }

    }); // oneFrame

    // sets the game world game loop (Timeline)
    loop = TimelineBuilder.create().cycleCount(Animation.INDEFINITE).keyFrames(oneFrame).build();
}

protected void updateDrawnEntities() {
    for (ADeviceView<?> view : DeviceLayoutManager.getDeviceViews()) {
        Pane content = view.getMainContentPanel();
        if (content.isVisible()) {
            view.update();
        }
    }
}

The Update method itself looks like that (the note m_TaskLEDhas values ​​that are set via jfx ChangeListeners, but it is updated only when the launch function is called.):

@Override
public void update() {
    m_TaskLED.run();
}

The runnable method is as follows:

    @Override
    public void run() {
        if (m_Color == null) return;
        if (m_LEDState == null) return;
        if (!m_IsChanged) return;

        if (m_LEDState != ELEDState.Off && m_Color != EColor.Off) {
            ColorRegistry.applyColor(m_Control, m_Color);
        }
        else {
            ColorRegistry.applyColor(m_Control, null);
        }

        // Clear the change flag so we can maybe shortcut future executions
        m_IsChanged = false;
    }

And last but not least, the method is applyColoras follows:

public static void applyColor(Node p_Node, EColor p_Color) {
    if (p_Color != null) {
        if (p_Node instanceof Shape) {
            ((Shape) p_Node).setFill(Paint.valueOf(getRGB(p_Color)));
        }
        else {
            p_Node.setStyle(FX_BACKGROUND_COLOR + getRGB(p_Color) + ";");
        }
    }
    else {
        if (p_Node instanceof Shape) {
            String style = ((Shape) p_Node).getStyle().toLowerCase();
            String rgb = style.substring(style.indexOf(FX_BACKGROUND_COLOR) + FX_BACKGROUND_COLOR.length());
            ((Shape) p_Node).setFill(Paint.valueOf(rgb));
        }
        p_Node.setStyle("");
    }
}

JavaFX 2, JavaFX 8 . JavaFX 2, JavaFX 8 , , JavaFX 8. , , JDK8, / - , 20%.

: Emulator with 100 devices.

, : Actual devices.

: CPU timeenter image description here

+4
1

( )? 300 100 , ( , , , JIT, , , ). , , , , , - , , - .

JavaFX 8 PseudoClasses.

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;


public class LotsOfFlashingButtons extends Application {

    @Override
    public void start(Stage primaryStage) {
        final FlowPane root = new FlowPane();
        root.setStyle("led-color: red;");
        final int NUM_BUTTONS = 300 ;
        for (int i=0; i<NUM_BUTTONS; i++) {
            final Button button = new Button(Integer.toString(i+1));
            button.setOnAction(event -> System.out.println("Button "+button.getText() + " pressed"));
            final Circle circle = new Circle(5);
            circle.setStyle("-fx-fill: led-color");
            button.setGraphic(circle);
            root.getChildren().add(button);
        }

        final BooleanProperty red = new SimpleBooleanProperty(true);

        final Timeline flash = new Timeline(new KeyFrame(Duration.millis(100), 
            event -> {
                red.set( ! red.get());
                if (red.get()) {
                    root.setStyle("led-color: red;");
                } else {
                    root.setStyle("led-color: green;");
                }
            }
        ));

        flash.setCycleCount(Animation.INDEFINITE);
        flash.play();

        Scene scene = new Scene(root, 800, 600);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

, , (.. JavaFX Application Thread). , .

UPDATE: setFill (...), , . , , css.

   final Circle[] graphics = new Circle[NUM_BUTTONS];
    for (int i=0; i<NUM_BUTTONS; i++) {
        final Button button = new Button(Integer.toString(i+1));
        button.setOnAction(event -> System.out.println("Button "+button.getText() + " pressed"));
        final Circle circle = new Circle(5);
        graphics[i] = circle ;
        button.setGraphic(circle);
        root.getChildren().add(button);
    }

    final Random rng = new Random();
    final Timeline flash = new Timeline(new KeyFrame(Duration.millis(100), 
        event -> {
            for (Circle circle : graphics) {
                circle.setFill(Color.rgb(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256)));
            }
        }
    ));
+2

Source: https://habr.com/ru/post/1532690/


All Articles