⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 visualization2dpanel.java

📁 基于MPEG 7 标准,符合未来语义网架构,很值得参考
💻 JAVA
字号:
/*
 * This file is part of Caliph & Emir.
 *
 * Caliph & Emir is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Caliph & Emir is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Caliph & Emir; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Copyright statement:
 * --------------------
 * (c) 2002-2005 by Mathias Lux (mathias@juggle.at)
 * http://www.juggle.at, http://caliph-emir.sourceforge.net
 */
package at.lux.fotoretrieval.panels;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;

/**
 * Date: 14.01.2005
 * Time: 00:00:38
 *
 * @author Mathias Lux, mathias@juggle.at
 */
public class Visualization2DPanel extends JPanel implements MouseMotionListener, MouseListener {
    private float points[][];
    private float maxX = 0f, maxY = 0f, minX = 0f, minY = 0f;
    private java.util.List<String> fileList;
    private static final int OFFSET = 20;
    private java.util.List<BufferedImage> imageList;
    private static final float IMG_MAXIMUM_SIDE = 20f;
    private int imagesLoaded = 0;
    private AffineTransform transform;

    private int moveX = 0, moveY = 0;
    private enum MouseState {NONE, BUTTON1_PRESSED};
    private MouseState state = MouseState.NONE;

    private Point lastPoint = null;

    /**
     * Creates a new <code>JPanel</code> with a double buffer
     * and a flow layout.
     */
    public Visualization2DPanel(float[][] points, java.util.List<String> files) {
        this.points = points;
        fileList = files;
        addMouseMotionListener(this);
        addMouseListener(this);
        init();
        LoaderThread lt = new LoaderThread(this);
        new Thread(lt).start();
    }

    private void init() {
        imageList = new LinkedList<BufferedImage>();
        for (int i = 0; i < points.length; i++) {
            float[] point = points[i];
            if (point[0] > maxX) maxX = point[0];
            if (point[1] > maxY) maxY = point[1];
            if (point[0] < minX) minX = point[0];
            if (point[1] < minY) minX = point[1];
        }
    }

    /**
     * Allows the iterative loading of image files ...
     * @return true if another image file can be loaded, false otherwise.
     */
    public boolean initNextImage() {
        if (imagesLoaded < points.length) {
            String pathname = fileList.get(imagesLoaded);
            pathname = pathname.replace(".mp7.xml", ".jpg");
            File f = new File(pathname);
            BufferedImage bi = null;
            try {
//                System.out.println("Reading file " + imagesLoaded + ": " + pathname);
                bi = ImageIO.read(f);
                if (bi != null) bi = resize(bi);
            } catch (IOException e) {
                System.err.println("Error reading image " + pathname);
            }
            imageList.add(bi);
        }
        imagesLoaded++;
        repaint();
        if (imagesLoaded > points.length)
            return false;
        else
            return true;
    }

    private BufferedImage resize(BufferedImage img) {
        int height = img.getHeight();
        int width = img.getWidth();
        float scaleFactor = ((float) width) / IMG_MAXIMUM_SIDE;
        if (height > width) {
            scaleFactor = ((float) height) / IMG_MAXIMUM_SIDE;
        }
        int widthNew = (int) (((float) width) / scaleFactor);
        int heightNew = (int) (((float) height) / scaleFactor);
        BufferedImage bi = new BufferedImage(widthNew, heightNew, BufferedImage.TYPE_INT_RGB);
        bi.getGraphics().drawImage(img, 0, 0, bi.getWidth(), bi.getHeight(), null);
        return bi;
    }

    /**
     * Calls the UI delegate's paint method, if the UI delegate
     * is non-<code>null</code>.  We pass the delegate a copy of the
     * <code>Graphics</code> object to protect the rest of the
     * paint code from irrevocable changes
     * (for example, <code>Graphics.translate</code>).
     * <p/>
     * If you override this in a subclass you should not make permanent
     * changes to the passed in <code>Graphics</code>. For example, you
     * should not alter the clip <code>Rectangle</code> or modify the
     * transform. If you need to do these operations you may find it
     * easier to create a new <code>Graphics</code> from the passed in
     * <code>Graphics</code> and manipulate it. Further, if you do not
     * invoker super's implementation you must honor the opaque property,
     * that is
     * if this component is opaque, you must completely fill in the background
     * in a non-opaque color. If you do not honor the opaque property you
     * will likely see visual artifacts.
     * <p/>
     * The passed in <code>Graphics</code> object might
     * have a transform other than the identify transform
     * installed on it.  In this case, you might get
     * unexpected results if you cumulatively apply
     * another transform.
     *
     * @param g the <code>Graphics</code> object to protect
     * @see #paint
     * @see javax.swing.plaf.ComponentUI
     */
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        // save old transformations ...
        AffineTransform old = g2.getTransform();
        // erase background
        g2.setColor(Color.black);
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.setColor(Color.green);
        // Apply move
        transform = AffineTransform.getTranslateInstance(moveX,  moveY);
        g2.setTransform(transform);
        float width = this.getWidth() - 2 * OFFSET;
        float height = this.getHeight() - 2 * OFFSET;
        for (int i = 0; i < points.length; i++) {
            float[] point = points[i];
            float x = (point[0] - minX) / (maxX - minX);
            float y = (point[1] - minY) / (maxY - minY);
            int projectionX = (int) (x * width) + OFFSET;
            int projectionY = (int) (y * height) + OFFSET;
            BufferedImage bi = null;
            if (i < imageList.size()) bi = imageList.get(i);
            if (bi != null) {
                g2.drawImage(bi, projectionX - bi.getWidth() / 2, projectionY - bi.getHeight() / 2, null);
            } else {
                g2.fillOval(projectionX - 2, projectionY - 2, 4, 4);
            }
        }
        // restore old transformations:
        g2.setTransform(old);
    }


    /**
     * Invoked when a mouse button is pressed on a component and then
     * dragged.  <code>MOUSE_DRAGGED</code> events will continue to be
     * delivered to the component where the drag originated until the
     * mouse button is released (regardless of whether the mouse position
     * is within the bounds of the component).
     * <p/>
     * Due to platform-dependent Drag&Drop implementations,
     * <code>MOUSE_DRAGGED</code> events may not be delivered during a native
     * Drag&Drop operation.
     */
    public void mouseDragged(MouseEvent e) {
//        System.out.println("Dragged: " + e.getPoint());
        if (lastPoint==null) lastPoint = e.getPoint();
        if (state == MouseState.BUTTON1_PRESSED) {
            moveX += e.getPoint().x-lastPoint.x;
            moveY += e.getPoint().y-lastPoint.y;
            repaint();
        }
        lastPoint = e.getPoint();
    }

    /**
     * Invoked when the mouse cursor has been moved onto a component
     * but no buttons have been pushed.
     */
    public void mouseMoved(MouseEvent e) {
//        System.out.println("Moved: " + e.getPoint());
//        if (lastPoint==null) lastPoint = e.getPoint();
//        if (state == MouseState.BUTTON1_PRESSED) {
//            moveX += e.getPoint().x-lastPoint.x;
//            moveY += e.getPoint().y-lastPoint.y;
//        }
//        lastPoint = e.getPoint();
    }

    /**
     * Invoked when the mouse button has been clicked (pressed
     * and released) on a component.
     */
    public void mouseClicked(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON1 && e.getModifiers() == MouseEvent.ALT_DOWN_MASK) {
        }

    }

    /**
     * Invoked when a mouse button has been pressed on a component.
     */
    public void mousePressed(MouseEvent e) {
        if (e.getButton()==MouseEvent.BUTTON1) state = MouseState.BUTTON1_PRESSED;
    }

    /**
     * Invoked when a mouse button has been released on a component.
     */
    public void mouseReleased(MouseEvent e) {
        state = MouseState.NONE;
    }

    /**
     * Invoked when the mouse enters a component.
     */
    public void mouseEntered(MouseEvent e) {

    }

    /**
     * Invoked when the mouse exits a component.
     */
    public void mouseExited(MouseEvent e) {

    }
}

class LoaderThread implements Runnable {
    private Visualization2DPanel panel;

    public LoaderThread(Visualization2DPanel panel) {
        this.panel = panel;
    }

    public void run() {
        while (panel.initNextImage()) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -