Ускоряйте 2D изображения в Java *, не мешая JMenus - PullRequest
2 голосов
/ 30 октября 2008

Уже реализовано повышение производительности: - Получить совместимое изображение GraphicsConfiguration для рисования - Включить конвейер OpenGL в версии 1.5: невозможно из-за серьезных артефактов

Пока все в порядке, основным узким местом программы является рисование изображения с несколькими тысячами плиток. К сожалению это не регулярно, иначе я просто мог бы установить пиксели и масштабировать их. Я связал изображение с VolatileImages и собственными процедурами рендеринга (игнорируйте перерисовку и нарисуйте его сам с таймером). Результат был приятным и достаточным, НО: Выбор JMenu, который обычно находится над частью изображения, серьезно нарушен, потому что JMenu перезаписан. Недопустимо, и макет не может быть изменен.

Я попробовал GLJPanel из JOGL, но видимого улучшения производительности нет. Так есть ли возможность использовать VolatileImages (или другие ускоренные легковесные компоненты, такие как GLCanvas) и при этом получить нормальное отображение JMenu, и если да, то как?

Ответы [ 3 ]

2 голосов
/ 30 октября 2008

Вы можете попытаться установить всплывающие окна не легкого веса. Я не совсем уверен, если это работает, но это может, потому что всплывающее окно является нативным компонентом и не будет перезаписано. Установка всплывающих окон в тяжелом весе: JPopupMenu.setDefaultLightWeightPopupEnabled (false)

Дополнительная информация: Смешивание тяжелых и легких компонентов

1 голос
/ 30 октября 2008

Вот пример кода:

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

public final class FastDraw extends JFrame {

    private static final transient double NANO = 1.0e-9;
    private BufferStrategy bs;
    private BufferedImage frontImg;
    private BufferedImage backImg;
    private int PIC_WIDTH,
    PIC_HEIGHT;
    private Timer timer;

    public FastDraw() {
        timer = new Timer(true);
        JMenu menu = new JMenu("Dummy");
        menu.add(new JMenuItem("Display me !"));
        menu.add(new JMenuItem("Display me, too !"));
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(menu);
        setJMenuBar(menuBar);
        setIgnoreRepaint(true);
        setVisible(true);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent evt) {
                super.windowClosing(evt);
                timer.cancel();
                dispose();
                System.exit(0);
            }
        });

        try {
            backImg = javax.imageio.ImageIO.read(new File(<insert a jpg picture here>));
            frontImg = javax.imageio.ImageIO.read(<here, too>));
        }
        catch (IOException e) {
            System.out.println(e.getMessage());
        }

        PIC_WIDTH = backImg.getWidth();
        PIC_HEIGHT = backImg.getHeight();
        setSize(PIC_WIDTH, PIC_HEIGHT);

        createBufferStrategy(1); // Double buffering
        bs = getBufferStrategy();
        timer.schedule(new Drawer(),0,20);

    }

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

    private class Drawer extends TimerTask {
        private VolatileImage img;

        public void run() {
            long begin = System.nanoTime();
            Graphics2D  g  = (Graphics2D) bs.getDrawGraphics();
            GraphicsConfiguration gc = g.getDeviceConfiguration();

            if (img == null)
                img = gc.createCompatibleVolatileImage(PIC_WIDTH, PIC_HEIGHT);

            Graphics2D g2 = img.createGraphics();

            do {
                int valStatus = img.validate(gc);

                if (valStatus == VolatileImage.IMAGE_OK)
                    g2.drawImage(backImg,0,0,null);
                else {
                    g.drawImage(frontImg, 0, 0, null);
                }
                // volatile image is ready
                g.drawImage(img,0,50,null);
                bs.show();
            } while (img.contentsLost());
        }
    }
}

Измените размер окна, чтобы сделать JMenuBar видимым. Попробуйте выбрать пункт меню. См

0 голосов
/ 30 октября 2008

Ну, я не уверен, что полностью понимаю вашу проблему, но, похоже, основная проблема заключается в перерисовке панели, на которой отображается изображение. Не могли бы вы предоставить свою процедуру рисования, которая рисует изображение на панели?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...