Вопрос по java, image, swing, thread-sleep, paintcomponent – Как я могу нарисовать изображение по частям?

0
class DrawIma extends JPanel{
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        for (int i=0;i<20;i++){
            for (int j=0;j<20;j++) {    
                g.drawImage(BuArr[i*20+j], 20*i, 20*j, 20, 20, null);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

В этой частиBuArr являются400 блоков разделен отBufferedImageТеперь я хочу, чтобы они рисовались один за другим, но метод не может рисовать блоки отдельно, как я могу это сделать?

Примечание: изменитьg.drawImage(BuArr[i*20+j], 20*i, 20*j, 20, 20, null); вg.drawImage(BuArr[i*20+j], 20*i, 20*j, 20, 20, this); Andrew Thompson
этот способ неправильный, вы не можете создать анимацию в блокировке paintComponent () с помощью Thread.sleep mKorbel

Ваш Ответ

1   ответ
3

Это означает, что вы не должны выполнять какие-либо длительные работы или блокировки (Thread.sleep) операции внутри потока IU (поток диспетчеризации событий). Это также означает, что вы не можете обновлять, изменять или создавать элементы пользовательского интерфейса вне контекста EDT.

Вместо этого используйте SwingTimer генерировать повторный обратный вызов с заданным интервалом и визуализировать части изображения в нечто вродеBufferedImage, который вы можете нарисовать на компонент через егоpaintComponent метод ...

УвидетьПараллелизм в Swing а такжеКак использовать Swing Timers Больше подробностей

Потому что это была хорошая трата времени

Это создаетList изRectangles которые представляют отдельные блоки, которые я хочу нарисовать, я затем случайным образомList и запуститьTimerвыбирая самый верхRectangle отList и используяBufferedImage#getSubImage нарисовать его из мастера в буфер, который раскрашивается на экран ...

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestImage {

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

    public TestImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage master;
        private BufferedImage copy;

        private List<Rectangle> blocks;

        public TestPane() {
            setBackground(Color.BLACK);
            try {
                master = ImageIO.read(new File("..."));
                copy = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = copy.createGraphics();
                AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f);
                g2d.setComposite(composite);
                g2d.setColor(new Color(0, 0, 0, 0));
                g2d.fillRect(0, 0, master.getWidth(), master.getHeight());
                g2d.dispose();

                int blockSize = 40;

                int width = master.getWidth();
                int height = master.getHeight();

                float aspect = Math.min(width, height) / (float) Math.max(width, height);

                int blockHeight = blockSize;
                blocks = new ArrayList<>(blockSize * 2);
                for (int y = 0; y < master.getHeight(); y += blockHeight) {
                    if (y + blockHeight > master.getHeight()) {
                        blockHeight = master.getHeight() - y;
                    }
                    int blockWidth = blockSize;
                    for (int x = 0; x < master.getWidth(); x += blockWidth) {
                        if (x + blockWidth > master.getWidth()) {
                            blockWidth = master.getWidth() - x;
                        }
                        Rectangle block = new Rectangle(x, y, blockWidth, blockHeight);
                        blocks.add(block);
                    }
                }
                Collections.shuffle(blocks);
                Timer timer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (blocks.isEmpty()) {
                            ((Timer) e.getSource()).stop();
                        } else {
                            Graphics2D g2d = copy.createGraphics();
                            Rectangle block = blocks.remove(0);
                            g2d.drawImage(master.getSubimage(block.x, block.y, block.width, block.height), block.x, block.y, TestPane.this);
                            g2d.dispose();
                            repaint();
                        }
                    }
                });

                timer.start();

            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return master == null ? new Dimension(200, 200) : new Dimension(master.getWidth(), master.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (copy != null) {
                int x = (getWidth() - copy.getWidth()) / 2;
                int y = (getHeight() - copy.getHeight()) / 2;
                g2d.drawImage(copy, x, y, this);
            }
            g2d.dispose();
        }

    }

}

Похожие вопросы