如何将同一类中的2D图形和图像分别绘制到同一JPanel

时间:2018-07-03 11:27:22

标签: java swing graphics2d

我有一个方法(drawImages),它向扩展的JPanel绘制一个bufferedimages的数组列表。但是,只有在调用另一个方法(drawPerfectRect)时才在paintComponent方法中调用它。

此方法(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 :(得分:0)

改进添加到selectDirectory按钮的操作侦听器,如下所示:

  1. 删除动作监听器中的repaint()调用(稍后将对其进行修复)。
  2. 每次按下按钮,即可
  3. 清除缩略图列表。也就是说,在动作监听器中的thumbnailList.clear()。这样,对于每个目录选择,将仅显示最后导入的图像。
  4. 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);
        }
    });
}