2013-04-12 125 views
1

我有一個圖像列表。我需要在一個框架中添加小縮略圖。我目前有框架SpringLayout。如何使用滾動窗格在時尚網格中添加縮略圖。照片列表可能很大,所以我需要一個滾動窗格。我不知道如何用SpringLayout來解決這個問題。我知道如何添加縮略圖;真正的問題是如何在SpringLayout中顯示縮略圖網格。將圖像縮略圖添加到網格中的佈局?

import java.awt.Color; 
import java.awt.Container; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SpringLayout; 

public class grid { 

    /** 
    * @param args 
    */ 
    public grid() { 

     JFrame frame = new JFrame("Hello"); 
     Container pane = frame.getContentPane(); 

     pane.setBackground(Color.WHITE); 
     SpringLayout layout = new SpringLayout(); 
     pane.setLayout(layout); 

     JPanel photoPanel = new JPanel(); 
     JScrollPane photoScroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 
     photoPanel.add(photoScroll); 
     pane.add(photoPanel); 

     layout.putConstraint(SpringLayout.WEST, photoPanel, 260, SpringLayout.WEST, pane); 
     layout.putConstraint(SpringLayout.NORTH, photoPanel, 40, SpringLayout.SOUTH, pane); 

     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     frame.pack(); 
     //frame.setSize(frame.getMaximumSize()); 
     frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
     frame.setLocationRelativeTo(null); 
     frame.setResizable(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 

     new grid(); 
    } 
} 
+1

我不明白爲什麼需要擔心彈簧鋪排。只需將'JScrollPane'的視圖(使用'setViewportView')設置爲想要在需要時佈置照片的組件,只需按照通常的方式添加組件即可。爲簡單起見,我會建議使用像[WrapLayout](http://tips4java.wordpress.com/2008/11/06/wrap-layout/)或'GridLayout' – MadProgrammer

+0

這是不是整個代碼,我已經有一個Jframe與springlayout我該如何去添加該框架中的縮略圖。在那個框架中,我已經有了Jscrollpane和Jlist – jrdnsingh89

+0

那麼你想添加圖像在哪裏?在滾動窗格中或直接到框架?滾動窗格中的 – MadProgrammer

回答

7

因此,基本上,你需要某種容器,生活在滾動窗格(俗稱視圖)。

對此,您應該添加圖像。

enter image description here

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.Insets; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.AffineTransform; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileFilter; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class ImageGrid { 

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

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

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

    public class TestPane extends JPanel { 

     private JPanel imagesPane; 

     public TestPane() { 
      setLayout(new BorderLayout()); 
      imagesPane = new JPanel(new WrapLayout()); 
      add(new JScrollPane(imagesPane)); 
      JButton scan = new JButton("Scan"); 
      scan.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        String path = "C:\\Users\\shane\\Dropbox\\Ponies"; 
        File[] files = new File(path).listFiles(new FileFilter() { 
         @Override 
         public boolean accept(File pathname) { 
          String name = pathname.getName().toLowerCase(); 
          return pathname.isFile() && (name.endsWith(".png") 
            || name.endsWith(".jpg") 
            || name.endsWith(".gif")); 
         } 
        }); 
        imagesPane.removeAll(); 
        for (File file : files) { 
         try { 
          ImagePane pane = new ImagePane(file); 
          imagesPane.add(pane); 
         } catch (Exception exp) { 
          exp.printStackTrace(); 
         } 
        } 
        imagesPane.revalidate(); 
        imagesPane.repaint(); 
       } 
      }); 
      add(scan, BorderLayout.SOUTH); 
     } 
    } 

    public class ImagePane extends JPanel { 

     private Image img; 

     public ImagePane(File source) throws IOException { 
      img = ImageIO.read(source); 
      if (img.getWidth(this) > 200 || img.getHeight(this) > 200) { 
       int width = img.getWidth(this); 
       int height = img.getWidth(this); 
       float scaleWidth = 200f/width; 
       float scaleHeight = 200f/height; 
       if (scaleWidth > scaleHeight) { 
        width = -1; 
        height = (int)(height * scaleHeight); 
       } else { 
        width = (int)(width * scaleWidth); 
        height = -1; 
       } 
       img = img.getScaledInstance(width, height, Image.SCALE_SMOOTH); 
      } 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      if (img != null) { 
//    int width = img.getWidth(); 
//    int height = img.getHeight(); 
//    float scale = 1f; 
//    AffineTransform at = new AffineTransform(); 
//    at.translate(
//      (getWidth()/2) - ((img.getWidth() * scale)/2), 
//      (getHeight()/2) - ((img.getHeight() * scale)/2)); 
//    at.scale(scale, scale); 
//    g2d.setTransform(at); 
       g2d.drawImage(img, 0, 0, this); 
      } 
      g2d.dispose(); 
     } 
    } 

    /** 
    * FlowLayout subclass that fully supports wrapping of components. 
    */ 
    public class WrapLayout extends FlowLayout { 

     private Dimension preferredLayoutSize; 

     /** 
     * Constructs a new 
     * <code>WrapLayout</code> with a left alignment and a default 5-unit 
     * horizontal and vertical gap. 
     */ 
     public WrapLayout() { 
      super(); 
     } 

     /** 
     * Constructs a new 
     * <code>FlowLayout</code> with the specified alignment and a default 5-unit 
     * horizontal and vertical gap. The value of the alignment argument must be 
     * one of 
     * <code>WrapLayout</code>, 
     * <code>WrapLayout</code>, or 
     * <code>WrapLayout</code>. 
     * 
     * @param align the alignment value 
     */ 
     public WrapLayout(int align) { 
      super(align); 
     } 

     /** 
     * Creates a new flow layout manager with the indicated alignment and the 
     * indicated horizontal and vertical gaps. 
     * <p> 
     * The value of the alignment argument must be one of 
     * <code>WrapLayout</code>, 
     * <code>WrapLayout</code>, or 
     * <code>WrapLayout</code>. 
     * 
     * @param align the alignment value 
     * @param hgap the horizontal gap between components 
     * @param vgap the vertical gap between components 
     */ 
     public WrapLayout(int align, int hgap, int vgap) { 
      super(align, hgap, vgap); 
     } 

     /** 
     * Returns the preferred dimensions for this layout given the 
     * <i>visible</i> components in the specified target container. 
     * 
     * @param target the component which needs to be laid out 
     * @return the preferred dimensions to lay out the subcomponents of the 
     * specified container 
     */ 
     @Override 
     public Dimension preferredLayoutSize(Container target) { 
      return layoutSize(target, true); 
     } 

     /** 
     * Returns the minimum dimensions needed to layout the <i>visible</i> 
     * components contained in the specified target container. 
     * 
     * @param target the component which needs to be laid out 
     * @return the minimum dimensions to lay out the subcomponents of the 
     * specified container 
     */ 
     @Override 
     public Dimension minimumLayoutSize(Container target) { 
      Dimension minimum = layoutSize(target, false); 
      minimum.width -= (getHgap() + 1); 
      return minimum; 
     } 

     /** 
     * Returns the minimum or preferred dimension needed to layout the target 
     * container. 
     * 
     * @param target target to get layout size for 
     * @param preferred should preferred size be calculated 
     * @return the dimension to layout the target container 
     */ 
     private Dimension layoutSize(Container target, boolean preferred) { 
      synchronized (target.getTreeLock()) { 
       // Each row must fit with the width allocated to the containter. 
       // When the container width = 0, the preferred width of the container 
       // has not yet been calculated so lets ask for the maximum. 

       int targetWidth = target.getSize().width; 

       if (targetWidth == 0) { 
        targetWidth = Integer.MAX_VALUE; 
       } 

       int hgap = getHgap(); 
       int vgap = getVgap(); 
       Insets insets = target.getInsets(); 
       int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2); 
       int maxWidth = targetWidth - horizontalInsetsAndGap; 

       // Fit components into the allowed width 

       Dimension dim = new Dimension(0, 0); 
       int rowWidth = 0; 
       int rowHeight = 0; 

       int nmembers = target.getComponentCount(); 

       for (int i = 0; i < nmembers; i++) { 
        Component m = target.getComponent(i); 

        if (m.isVisible()) { 
         Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize(); 

         // Can't add the component to current row. Start a new row. 

         if (rowWidth + d.width > maxWidth) { 
          addRow(dim, rowWidth, rowHeight); 
          rowWidth = 0; 
          rowHeight = 0; 
         } 

         // Add a horizontal gap for all components after the first 

         if (rowWidth != 0) { 
          rowWidth += hgap; 
         } 

         rowWidth += d.width; 
         rowHeight = Math.max(rowHeight, d.height); 
        } 
       } 

       addRow(dim, rowWidth, rowHeight); 

       dim.width += horizontalInsetsAndGap; 
       dim.height += insets.top + insets.bottom + vgap * 2; 

       // When using a scroll pane or the DecoratedLookAndFeel we need to 
       // make sure the preferred size is less than the size of the 
       // target containter so shrinking the container size works 
       // correctly. Removing the horizontal gap is an easy way to do this. 

       Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target); 

       if (scrollPane != null && target.isValid()) { 
        dim.width -= (hgap + 1); 
       } 

       return dim; 
      } 
     } 

     /* 
     * A new row has been completed. Use the dimensions of this row 
     * to update the preferred size for the container. 
     * 
     * @param dim update the width and height when appropriate 
     * @param rowWidth the width of the row to add 
     * @param rowHeight the height of the row to add 
     */ 
     private void addRow(Dimension dim, int rowWidth, int rowHeight) { 
      dim.width = Math.max(dim.width, rowWidth); 

      if (dim.height > 0) { 
       dim.height += getVgap(); 
      } 

      dim.height += rowHeight; 
     } 
    } 
} 

此示例包括WrapLayout。縮放是爲了速度和簡單性而完成的,但所使用的方法是不可視的,請參閱​​以獲得更好的方法。

我通常會在後臺線程中加載和縮放圖像,如SwingWorker,但這是一個想法的例子。

+0

我知道,我已經覆蓋了,問題如何顯示單擊按鈕上的縮略圖網格。我需要一個行動偵探。但idk如何在框架上顯示面板.. – jrdnsingh89

+0

我也加了一些代碼.. – jrdnsingh89

+0

非常好!我以前沒有注意到''''getScaledInstance()'中的重要性。我無恥地在這個[變化]中回收你的計算(http://stackoverflow.com/a/15982915/230513)。 – trashgod

6

對同一主題最近刪除的question提示此示例使用隨機大小的合成圖像來說明縮放對最大維度中的特定SIZE的影響。

image

import java.awt.*; 
import java.awt.image.BufferedImage; 
import java.util.Random; 
import javax.swing.*; 

/** @see https://stackoverflow.com/a/15982915/230513 */ 
public class Thumbnails { 

    private static final int SIZE = 128; 
    private static final Random r = new Random(); 

    // Get a randomly sized image 
    static private Image getImage() { 
     int w = r.nextInt(SIZE) + SIZE/2; 
     int h = r.nextInt(SIZE) + SIZE/2; 
     BufferedImage bi = new BufferedImage(
      w, h, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2d = bi.createGraphics(); 
     g2d.setPaint(Color.lightGray); 
     g2d.fillRect(0, 0, w, h); 
     g2d.setColor(Color.black); 
     String s = w + "\u00D7" + h; 
     int x = (w - g2d.getFontMetrics().stringWidth(s))/2; 
     g2d.drawString(s, x, 24); 
     g2d.dispose(); 
     return bi; 
    } 

    // Get a panel with an image scaled to SIZE in the largest dimension 
    // https://stackoverflow.com/a/15961424/230513 
    private static JPanel getPanel() { 
     Image original = getImage(); 
     int w = original.getWidth(null); 
     int h = original.getHeight(null); 
     float scaleW = (float) SIZE/w; 
     float scaleH = (float) SIZE/h; 
     if (scaleW > scaleH) { 
      w = -1; 
      h = (int) (h * scaleH); 
     } else { 
      w = (int) (w * scaleW); 
      h = -1; 
     } 
     Image scaled = original.getScaledInstance(w, h, Image.SCALE_SMOOTH); 
     JPanel p = new JPanel(new GridLayout()){ 

      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(SIZE, SIZE); 
      } 
     }; 
     p.add(new JLabel(new ImageIcon(scaled))); 
     p.setBorder(BorderFactory.createLineBorder(Color.red)); 
     return p; 
    } 

    private static void createAndShowGUI() { 
     JFrame f = new JFrame("PhotoAlbum55"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JPanel panel = new JPanel(new GridLayout(6, 6)); 
     for (int i = 0; i < 6 * 6; i++) { 
      panel.add(getPanel()); 
     } 
     f.add(new JScrollPane(panel)); 
     f.pack(); 
     f.setSize(4 * SIZE, 4 * SIZE); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 
相關問題