Функция рисования определена в отдельном потоке, а не в рисовании (Java) - PullRequest
0 голосов
/ 06 октября 2018

У меня есть три файла, вот основной, под названием Display.java:

import java.awt.*;
import javax.swing.*;

public class Display{
    static JFrame main = new JFrame("hello");
    static Container c = main.getContentPane();
    static StartScreen start = new StartScreen();
    static screenTracker track = new screenTracker();

    public static void main(String[] args) {
        main.setSize(new Dimension(1920,1080));
        main.setVisible(true);
        if(track.screen==1) {
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        c.add(start,  BorderLayout.CENTER);
    }
    }
}

Мой второй файл называется: StartScreen.java.Он содержит мою функцию рисования:

import java.applet.Applet;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class StartScreen extends Applet{
    private static final long serialVersionUID = 1L; 
    int x = 0;
    static Container c = Display.c;
    static Color gray = new Color(128,128,128);
    public void paint(Graphics g) {
        Thread t = new Thread() {
            @Override
            public void run() {
        while(true) {
        c.setBackground(gray);
        g.clearRect( 0 , 0 , getWidth() , getHeight() );
        BufferedImage img1 = null;
        BufferedImage img2 = null;
        BufferedImage img3 = null;
        try {
            img1 = ImageIO.read(new File("images/img1.png"));
            img2 = ImageIO.read(new File("images/img2.png"));
            img3 = ImageIO.read(new File("images/img3.png"));
        }
        catch(IOException e) {
            g.drawString("bad", 200, 200);
        }
        String title1 = "hello: ";
        String title2 = "Gamee ";
        String title3 = "people";
        Color pink = new Color(244,66,182);
        Color black = new Color(0,0,0);
        g.setColor(black);
        g.setFont(new Font("TimesRoman", Font.PLAIN, 50));
        g.drawString(title1, x+600, 200);
        g.setColor(pink);
        g.setFont(new Font("TimesRoman", Font.ITALIC, 50));
        g.drawString(title2, 860, 200);
        g.setFont(new Font("TimesRoman", Font.PLAIN, 50));
        g.setColor(black);
        g.drawString(title3, 960, 200);
        g.drawImage(img1, 200, 250, null);
        g.drawImage(img2, 700, 150, 1000, 750, null);
        g.drawImage(img3, 500, 250, null);
        x++;
        try {
            sleep(10);  // milliseconds
         } catch (InterruptedException ex) {}
        }
            }
        };
        t.start();
    }
}

Мой третий файл короткий:

public class screenTracker {
int screen = 1;
}

Сейчас я просто хочу, чтобы функция рисования в StartScreen.java отображалась на моем JFrame.Я хочу привет, чтобы двигаться по экрану.Я сделал нить т, чтобы экран мог закрыться.Если я избавлюсь от потока t или создам его в Display.java (внутри оператора if, где я устанавливаю операцию закрытия по умолчанию и добавляю начальный экран в контейнер c), программа рисует то, что я хочу, но Jframe выигралне близкоЯ посмотрел на многих других веб-сайтах и ​​вопросов, но я не смог понять это.Я новичок в многопоточности и графике в Java,

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Множество проблем:

  1. Не расширять апплет.Апплеты мертвы.Для пользовательского рисования вы просто расширяете JPanel и добавляете панель к рамке.

  2. В JPanel вы должны переопределить paintComponent(), а не paint ().

  3. Метод рисования предназначен только для рисования. НЕ следует:

    1. прочитать изображение в методе.Метод рисования вызывается много раз.Вы хотите, чтобы рисование было быстрым и не нужно было делать ввод / выводПрочитайте изображения в конструкторе вашего класса

    2. создавая темы.Опять же, поскольку метод рисования вызывается несколько раз, и вы не можете его контролировать, поэтому вы не хотите продолжать создавать потоки.Если вы хотите какую-то анимацию, вам следует использовать Swing Timer.

Я предлагаю вам прочитать раздел из учебника по Swing на Custom Painting.Он содержит рабочие примеры, которые покажут вам, как лучше структурировать ваш код.

Также есть раздел на How to Use Swing Timers.

0 голосов
/ 06 октября 2018

Если мы говорим о графике в Java, у нас есть только один поток, отвечающий за это EDT ([1] [Event Dispatch Thread]).Другими словами, все, что вы хотите сделать с представлением, будет обрабатываться и должно обрабатываться EDT, да, ваше представление также со всеми setbackroungs, кадрами ...

Но учтите, что это только один потокКогда этот шаг занят, некоторые вычисления не могут реагировать на пользовательские события, поэтому ваше представление замораживается.Что вы можете сделать в другом потоке, это подготовить данные (в вашем случае прочитайте файл изображений)

Для работы в EDT вы используете SwingInvoker.invokelater () или проверьте, что вы уже в EDT, используя swingutilities..isEventDispatchThread ()

[1] https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
...