powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Потоковая отрисовка на canvas в приложении JavaFX
12 сообщений из 12, страница 1 из 1
Потоковая отрисовка на canvas в приложении JavaFX
    #39484794
solo700
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Простое приложение. Каркас JavaFX в рабочей области Canvas и Button.
Запускается приложение, создается каркас, запускается поток в котором в цикле
с задержкой 10 миллисек. на canvas отрисовывается текст. Рано или поздно текст на canvas встает.
На консоль продолжает выводиться. Иногда на canvas отрисовывается 1000 раз, иногда 100 а иногда 300000 раз.
Кто знает в чем дело ? Почему в какой то момент текст перестает отрисовываться ?
Программа небольшая ... ниже исходники.

файл Main.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
package drawtext;
	
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;

public class Main extends Application {
	static int isShutdown = 0;
    static int isStopDraw = 0;
    final Canvas canvas = new Canvas(400, 400);
    final GraphicsContext gc = canvas.getGraphicsContext2D();
    Button btn = new Button();
    Stage primaryStageMy;
    StackPane root = new StackPane();
    Scene scene = new Scene(root,400,400);

    @Override
	public void start(Stage primaryStage) {
    	try {
			btn.setText("isStopDraw " + isStopDraw);
	        btn.setOnAction(new EventHandler<ActionEvent>() {
	            @Override
	            public void handle(ActionEvent event) {
	                if(0==isStopDraw) {
	                    isStopDraw=1;
	                } else {
	                    isStopDraw=0;
	                }
	                btn.setText("isStopDraw " + isStopDraw);
	            }
	        });
	        root.getChildren().add(canvas);
	        root.getChildren().add(btn);
	        StackPane.setAlignment(canvas, Pos.CENTER);
	        primaryStage.setScene(scene);
			primaryStage.show();
			ExecutorService exec = Executors.newSingleThreadExecutor();
			exec.execute(new Draw(this));
			exec.shutdown();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
		isShutdown = 1;
		
	}
}



файл Draw.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
package drawtext;

import javafx.geometry.Bounds;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;

public class Draw implements Runnable {
	
	private Main main;
	private GraphicsContext gc;
		
	public Draw(Main main) {
		this.main = main;
		this.gc = main.gc;
	}
	
	public void run() {
		Bounds ViewRect;
		synchronized(gc) {
			gc.setFont(new Font("Times New Roman", 20));
			int i = 0;
			while(true) {
	            try {
	                Thread.sleep(10);
	            } catch(InterruptedException ignory) {
	                System.out.println("Аварийный выход 1 !" + i);
	                //return;
	                continue;
	            }
	            if(1 == main.isShutdown) {
	                break;
	            }
	            if(1 == main.isStopDraw) {
	            	System.out.println("Нажата кнопка Стоп !" + i);
	                Thread.yield();
	                continue;
	            }
	            try {
	                ViewRect=main.canvas.getBoundsInParent();
	                gc.setFill(Color.WHITE);
	                gc.fillRect(ViewRect.getMinX(), ViewRect.getMinY(), ViewRect.getWidth(), ViewRect.getHeight());
	                gc.setFill(Color.BLACK);
	                gc.clearRect(0, 0, 400, 400);
	               	gc.fillText(" Тестовая запись на холсте. № " + i, 20, 50);
	            } catch(Exception ignory) {
	                System.out.println("Аварийный выход 2 !" + i);
	                //return;
	                continue;
	            }
	            System.out.println(" Тестовый вывод на консоль № " + i);
	            i++;
	        }
		}
	}
}
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484808
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
solo700
Код: java
1.
gc.fillText(" Тестовая запись на холсте. № " + i, 20, 50);


сюда добавить использование памяти по всем параметрам
solo700
Код: java
1.
catch


сюда вывод стека ошибки
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484815
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
solo700,

Вы вообще не поняли JavaFX. Нет никакой "отрисовки". Вы задаёте JavaFX "векторные" объекты - Node, а он их отрисовывает когда ему надо и как ему надо.

UI он, обычно, однопоточный. Инфа по потокам тут
https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm
Но вам ещё рано. Вам бы разобраться как оно вообще работает.
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484883
Victor Metelitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
solo700, вместо написания циклов с задержкой, быть может, вам имеет смысл поискать примеры на тему "javafx.animation.AnimationTimer".
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484891
solo700
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всё ждал ... кто первый предложит Animation. Конечно можно его использовать ... и даже нужно ... здесь вопрос принципиальный .. почему толком не работает этот код ?
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484893
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
solo700Всё ждал
а ты не жди. Делай что тебе написали.
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484897
Victor Metelitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько я понимаю, в JavaFx понятие "animation" и класс AnimationTimer не вполне... кхм...

Animation работает и без этого класса, кодом наподобие
Код: java
1.
2.
3.
4.
        TranslateTransition transTransition = new TranslateTransition(new Duration(75000), textRef);
        transTransition.setToY(-820);
        transTransition.setInterpolator(Interpolator.LINEAR);
        transTransition.setCycleCount(Timeline.INDEFINITE);

,

а (под)класс AnimationTimer дёргает кастомный public void handle(long now) шестьдесят раз в секунду.
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484898
Victor Metelitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Victor MetelitsaAnimation работает и без этого класса
Хотя исходники я не смотрел, внутри может быть всё, что угодно, просто наружу не видно.
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484905
solo700
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,
Извините что значит авторсюда добавить использование памяти по всем параметрам ?
Я проверял как работает уборщик мусора ...
Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()
хорошо работает (с 5 мег поднимается до 9 и падает обратно) - т.е. с памятью здесь всё в порядке. Я пытался обработать все исключения
catch(Exception ignory) { ... } - не генерятся исключения ... вообще. Я не знаю за что зацепиться. Здесь 2 потока - один главный,
он управляет формой, 2-ой с циклом в ктр. дергаю ресурсы формы. Понятно, что первый поток использует те же ресурсы, но я пытаюсь синхронизировать в частности графический контекст. Пробовал вставлять явную блокировку Lock - не помогает.
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39484932
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
solo700но я пытаюсь синхронизировать в частности графический контекст.
Этот метод не работает.
Ты его с потолка взял?
Используй другую кучу методов: сцена\ Platform.runLater\передачаВосновнойПоток\....анимация\таймеры
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39485614
solo700
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если кому интересно решение следующее ...
Добавляем функцию
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public static void gui_call(Runnable code) throws Exception {
    if (Platform.isFxApplicationThread()) { 
        code.run();
        return;
    }
    int timeout=100;
    Runnable r=new Runnable() {
        public synchronized void run() {
            code.run();
            notify();
        }
    };
    synchronized(r) {
        Platform.runLater(r);
        r.wait(timeout);
    }
}



и отрисовка
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
final int ii=i;
gui_call(new Runnable() { public void run() {
    Bounds ViewRect=main.canvas.getBoundsInParent();
    gc.setFill(Color.WHITE);
    gc.fillRect(ViewRect.getMinX(), ViewRect.getMinY(), ViewRect.getWidth(), ViewRect.getHeight());
    gc.setFill(Color.BLACK);
    gc.clearRect(0, 0, 400, 400);
    gc.fillText(" Тестовая запись на холсте. № " + ii, 20, 50);
}});


на форуме rsdn подсказали.
Всем спасибо ! Вопрос закрыт.
...
Рейтинг: 0 / 0
Потоковая отрисовка на canvas в приложении JavaFX
    #39485623
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
solo700Если кому интересно решение следующее ...
Это не "решение". Это нагромождение бесполезного кода. Synchronized??? wait/notify??? Задлянафига они в однопоточном GUI?
О какой тут вообще многопоточности идёт речь, если вы все потоки в очередь выстраиваете через synchronized и runLater?

solo700на форуме rsdn подсказали.
Там ещё и не такое подскажут. У вас принципиальное непонимание в том как работет UI. Прочитайте про очередь событий. Ссылки на туториал, я так понимаю давать бесполезно.

Ваше решение сродни тому, что пытаясь рисовать в несолько потоков, вы идёте в магазин за новой кисточкой для каждого нового штриха. Многопоточным может быть только моделирование вашей предметной области. А UI он как был однопоточным, так и остался.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Потоковая отрисовка на canvas в приложении JavaFX
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]