бесконечный цикл останавливает ввод текста - PullRequest
2 голосов
/ 26 апреля 2019

Я рендерил модель на холсте с помощью opengl, поэтому использую цикл while и запускаю его под потоком, чтобы не нарушать основной поток. У меня также есть текстовое поле, где я хочу написать текст. Текстовое поле фокусируется на моем действии и принимает данные, но при наведении курсора на текстовое поле фокусируется, но я не могу что-то написать на нем. Это может быть из-за цикла while, но я не знаю, как это преодолеть. Я хочу, чтобы пользовательский интерфейс оставался отзывчивым.

Вот мой код:

import java.awt.Canvas;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JTextField;

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.PixelFormat;

public final class Loader extends JFrame {

    public final int FPS = 120; // better cause of animations

    public static Loader loader;
    public Canvas canvas;
    private Viewport viewport;
    private JTextField textField;

    private Loader() {

        setTitle("Test");
        setResizable(true);
        setSize(320, 285);
        setLocationRelativeTo(null);
        getContentPane().setLayout(null);
        setVisible(true);

        canvas = new Canvas();
        getContentPane().add(canvas);
        canvas.setBounds(10, 24, 280, 163);

        textField = new JTextField();
        textField.setColumns(10);
        textField.setBounds(91, 193, 116, 22);
        getContentPane().add(textField);
    }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {

                    // Initialize the frame
                    loader = new Loader();

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                // render the model
                                loader.render();
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }).start();

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private static void init(Canvas canvas) throws Exception {

        Display.setParent(canvas);
        try {
            Display.create(new PixelFormat(8, 24, 8, 8));
        } catch (Exception ex) {
            Display.create(new PixelFormat(8, 24, 8, 0));
        }
        Display.makeCurrent();
        Display.setVSyncEnabled(false);
        Display.setSwapInterval(0);
    }

    private void render() throws Exception {
        init(canvas);
        loader.viewport = new Viewport(canvas);
        long[] timerCache = new long[10];
        long timerCur = 0L;
        long timerDst = 0L;
        long timerLast = 0L;
        long timerRate = 1000000L * 1000L / FPS;
        int timerCacheIndex = 0;
        int timerCacheSize = 0;
        boolean minSleep = Runtime.getRuntime().availableProcessors() <= 1;
        long[] clockCache = new long[32];
        int clockIndex = 0;
        int fps = 0;
        while (isVisible()) {
            long clock = System.nanoTime();
            long lastClock = clockCache[clockIndex];
            clockCache[clockIndex] = clock;
            if (++clockIndex == 32)
                clockIndex = 0;

            if (lastClock != 0L && clock > lastClock) {
                fps = (int) (1000000L * 1000L * 32L / (clock - lastClock));
            }
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
            GL11.glClearColor(.5f, .6f, .9f, 1f);
            loader.viewport.render();
            if (minSleep)
                try {
                    Thread.sleep(1L);
                } catch (Exception ex) {
                }

            timerCache[timerCacheIndex++] = System.nanoTime();
            if (timerCacheSize < timerCacheIndex)
                timerCacheSize = timerCacheIndex;

            if (timerCacheIndex == 10)
                timerCacheIndex = 0;

            long time = 0L;
            for (int i = 0; i != timerCacheSize; time += timerCache[i++])
                ;

            time /= (long) timerCacheSize;
            if (timerCacheSize == 1)
                timerLast = time;

            timerCur += time - timerLast;
            timerLast = time;
            timerDst += timerRate;
            if (timerDst > timerCur) {
                long sleep = timerDst - timerCur;
                try {
                    Thread.sleep(sleep / 1000000L, (int) (sleep % 1000000L));
                } catch (Exception ex) {
                }
                timerCur = timerDst;
                for (int i = 0; i != timerCacheSize; ++i)
                    timerCache[i] += sleep;

                timerLast += sleep;
            }
        }
    }
}

Этот рисунок может помочь узнать, как он выглядит в настоящее время. https://gyazo.com/e6950fd8dd01306c704857e94f214f93.gif

Я не вижу, где здесь ошибка, я уже использую поток для метода рендера.

Edit:

Viewport.java

public Viewport(Canvas canvas) throws LWJGLException {
    this.canvas = canvas;
    this.scale = 1.0F;
    this.pitch = 180.0F;
    this.yaw = 0.0F;
    this.roll = 0.0F;
}

public void render() {
    try {
        Dimension size = canvas.getSize();
        if (models != null && size.width > 0 && size.height > 0) {
            if (width != size.width || height != size.height) {
                width = size.width;
                height = size.height;
                glViewport(0, 0, width, height);
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                float c = (float) Math.sqrt((double) (width * width) + (double) (height * height));
                glOrtho(0.0F, (float) width, 0.0F, (float) height, -c, c);
                glMatrixMode(GL_MODELVIEW);
            }

            if (Mouse.isButtonDown(0) && !Mouse.isButtonDown(1)) {
                yaw -= (float) Mouse.getDX() / 2;
                pitch -= (float) Mouse.getDY() / 2;
            }
            if (Mouse.isButtonDown(0) && Mouse.isButtonDown(1)) {
                offset_z += (float) Mouse.getDY();
            }

            float wheel = (float) Mouse.getDWheel() / 1800.0F;
            if (wheel > 1.0F)
                wheel = 1.0F;
            else if (wheel < -1.0F)
                wheel = -1.0F;
            scale += scale * wheel;
            if (scale < 0.01F)
                scale = 0.01F;
            for (Model3D model : models) {
                float x = (float) width / 2.0F;
                float y = ((float) -((100.0F * (scale))) + offset_z) + (float) (height - model.height()) / 2.0F;
                float z = 0.0F;

                model.render(model, x, y, z, pitch, yaw, roll, scale, scale, scale);
            }

            Display.update();
        }
    } catch (Throwable t) {

    }

}

Ответы [ 2 ]

0 голосов
/ 04 мая 2019

Можете ли вы попробовать добавить requestFocus() в конец вашего render() метода вашего Loader класса и сообщить, что происходит?

0 голосов
/ 02 мая 2019

Вместо:

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // render the model
                    loader.render();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();

может быть:

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    // render the model
                    loader.render();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }        
        });

Он будет работать в потоке диспетчеризации AWT, возможно, проблема исчезнет. Качели не безопасны для ниток, что иногда осложняет жизнь.

...