Как рисовать 2D-графику и изображения отдельно в одном классе в одной и той же JPanel - PullRequest
0 голосов
/ 03 июля 2018

У меня есть метод (drawImages), который рисует массив расширенных изображений в расширенную JPanel. Однако он вызывается только в методе paintComponent, когда вызывается другой метод (drawPerfectRect).

Этот метод (drawPerfectRect) отвечает за использование переданных ему координат для рисования прямоугольника с использованием точек, на которые нажал пользователь.

По сути, у меня две проблемы:

  1. Он не рисует массив списков буферизованных изображений до тех пор, пока пользователь не щелкнет и не перетянет, чтобы создать прямоугольник (нужно, чтобы изображения рисовались после нажатия на selectDirectory (JButton)).
  2. Он также заново рисует буферизованные изображения для каждого последующего нарисованного прямоугольника.

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

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.*;

import com.sun.tools.internal.ws.wsdl.document.Import;
import net.coobird.thumbnailator.*;
import com.mortennobel.imagescaling.*;

import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.geom.RoundRectangle2D;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.Timer;

public class ImportWorkspace extends JPanel{

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int x, y, x2, y2;
ArrayList<BufferedImage> thumbnailList = new ArrayList<BufferedImage>();
int ContentPanelWidth;
private boolean addThumbnails = false;

    public ImportWorkspace(){

    x = y = x2 = y2 = 0;
    setLayout(null);
    setBackground(Color.decode("#2a2e37"));
    setBounds(85, 0, screenSize.width-85, screenSize.height);
    //System.out.println("W: " + super.getWidth() + ", H: " + super.getHeight());
    ContentPanelWidth = getWidth();
    System.out.println(ContentPanelWidth);

        JLabel dataIcon =  new JLabel(new ImageIcon(new ImageIcon ("folder.png").getImage().getScaledInstance(256,256, Image.SCALE_DEFAULT)));
        dataIcon.setBounds((getWidth()/2)-128, (getHeight()/2)-200, 256, 256);
        add(dataIcon);

        JLabel askImport = new JLabel("No Data Files have been selected: To begin importing data please select a directory.");
        askImport.setFont(new Font("Helvetica", Font.PLAIN, 20));
        askImport.setForeground(Color.white);
        askImport.setBounds((getWidth()/2)-375, (getHeight()/2)+50, 750, 100);
        add(askImport);

        JButton selectDirectory = new JButton("Select Directory");
        selectDirectory.setBounds((getWidth()/2)-75, (getHeight()/2)+150, 150, 50); //+half of width or height
        add(selectDirectory);

        selectDirectory.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                removeAll();
                revalidate();
                repaint();
                setLayout(new FlowLayout(FlowLayout.LEFT));

                ImportingImages getImages = new ImportingImages();
                getImages.importFiles();

                File curDir = new File("");
                File[] files = curDir.listFiles();
                long noFiles = curDir.length();

                for (File f : files) {
                    String fileName = f.getName();
                    String hiddenFile = ".DS_Store";
                    if (fileName.equals(hiddenFile)){
                        //System.out.println("Do nothing");
                    } else {

                        String thumbnailPath = curDir + "/" + f.getName();
                        try {
                            BufferedImage thumbnailIcon = ImageIO.read(new File(thumbnailPath));
                            thumbnailList.add(thumbnailIcon);
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }

                    }
                }

                MyMouseListener listener = new MyMouseListener();
                addMouseListener(listener);
                addMouseMotionListener(listener);

                //DisplayImages(thumbnailList, ContentPanelWidth);
            }
        });
    }

        public void setStartPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void setEndPoint(int x, int y) {
        x2 = (x);
        y2 = (y);
    }


    public void drawPerfectRect(Graphics g, int x, int y, int x2, int y2) {
        int px = Math.min(x,x2);
        int py = Math.min(y,y2);
        int pw = Math.abs(x-x2);
        int ph = Math.abs(y-y2);

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        int alpha = 100; // 127 50% transparent
        Color cyanTransparent = new Color(0,206,209, alpha);
        g2.setColor(cyanTransparent);
        g2.fillRoundRect(px, py, pw, ph, 5, 5);

        g2.setColor(Color.cyan);
        g2.setStroke(new BasicStroke(1));
        g2.drawRoundRect(px, py, pw, ph, 5, 5);

    }

    public void drawImages(Graphics g){
            int xSpacing = 10;
            int ySpacing = 20;
            int noImages = 0;
            for (BufferedImage thumbnail : thumbnailList){
                g.drawImage(thumbnail, xSpacing, ySpacing,null );
                if ((xSpacing+100) > (ContentPanelWidth-100)){
                    ySpacing = ySpacing + 77;
                    xSpacing = 10;
                } else{
                    xSpacing = xSpacing + 110;
                }
                noImages = noImages + 1;
                //System.out.println(noImages);
            }
    }

    class MyMouseListener extends MouseAdapter {

        public void mousePressed(MouseEvent e) {
            setStartPoint(e.getX(), e.getY());
        }

        public void mouseDragged(MouseEvent e) {
            setEndPoint(e.getX(), e.getY());
            revalidate();
            repaint();
        }

        public void mouseReleased(MouseEvent e) {
            setEndPoint(e.getX(), e.getY());
            revalidate();
            repaint();
        }
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        System.out.println(addThumbnails);
        drawImages(g2);
        drawPerfectRect(g2, x, y, x2, y2);  
    }
}

1 Ответ

0 голосов
/ 04 июля 2018

Улучшение слушателя действия, добавленного к кнопке selectDirectory, следующим образом:

  1. Удалите вызов repaint() внутри слушателя действия (исправит это позже).
  2. Очистить список миниатюр при каждом нажатии кнопки. То есть thumbnailList.clear() внутри слушателя действия. Таким образом, только последние импортированные изображения будут отображаться для каждого выбора каталога.
  3. Вызовите repaint() внутри слушателя действия кнопки после цикла for, который добавляет миниатюры в список. Таким образом, панель будет перекрашена (с новыми изображениями) после фактической загрузки изображений в список.

В результате конструктор ImportWorkspace можно записать следующим образом:

public ImportWorkspace(){

    x = y = x2 = y2 = 0;
    setLayout(null);
    setBackground(Color.decode("#2a2e37"));
    setBounds(85, 0, screenSize.width-85, screenSize.height);
    //System.out.println("W: " + super.getWidth() + ", H: " + super.getHeight());
    ContentPanelWidth = getWidth();
    System.out.println(ContentPanelWidth);

    JLabel dataIcon =  new JLabel(new ImageIcon(new ImageIcon ("folder.png").getImage().getScaledInstance(256,256, Image.SCALE_DEFAULT)));
    dataIcon.setBounds((getWidth()/2)-128, (getHeight()/2)-200, 256, 256);
    add(dataIcon);

    JLabel askImport = new JLabel("No Data Files have been selected: To begin importing data please select a directory.");
    askImport.setFont(new Font("Helvetica", Font.PLAIN, 20));
    askImport.setForeground(Color.white);
    askImport.setBounds((getWidth()/2)-375, (getHeight()/2)+50, 750, 100);
    add(askImport);

    JButton selectDirectory = new JButton("Select Directory");
    selectDirectory.setBounds((getWidth()/2)-75, (getHeight()/2)+150, 150, 50); //+half of width or height
    add(selectDirectory);

    selectDirectory.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {

            removeAll();
            revalidate();
            //repaint();           //Removed this line. It is not necessary in this place. Will be re-added AFTER the `for` loop below...
            thumbnailList.clear(); //Added this line.
            setLayout(new FlowLayout(FlowLayout.LEFT));

            ImportingImages getImages = new ImportingImages();
            getImages.importFiles();

            File curDir = new File("");
            File[] files = curDir.listFiles();
            long noFiles = curDir.length();

            for (File f : files) {
                String fileName = f.getName();
                String hiddenFile = ".DS_Store";
                if (fileName.equals(hiddenFile)){
                    //System.out.println("Do nothing");
                } else {

                    String thumbnailPath = curDir + "/" + f.getName();
                    try {
                        BufferedImage thumbnailIcon = ImageIO.read(new File(thumbnailPath));
                        thumbnailList.add(thumbnailIcon);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }

                }
            }

            repaint(); //Added this line! Now the newly loaded images shall be painted.

            MyMouseListener listener = new MyMouseListener();
            addMouseListener(listener);
            addMouseMotionListener(listener);

            //DisplayImages(thumbnailList, ContentPanelWidth);
        }
    });
}
...