HOWTO · Java

在 Java 中建立影象圖示

本教程演示瞭如何在 Java 中建立影象圖示。

本頁內容

在 Swing 中,ImageIcon 可代表要繪製在元件上或附加到 JButton 的影像。下方範例示範這兩種用法;在可正常使用圖形介面的環境中加上 --show 執行,即可在視窗中查看。範例會在記憶體中建立影像;若要載入影像檔,請使用應用程式能存取的路徑或類別路徑資源。

在 Java 中使用 ImageIcon 繪製影像

若要在自訂面板中繪製圖示,請載入或建立 ImageIcon,依圖示尺寸設定面板的偏好大小,並覆寫 paintComponent。呼叫 paintIcon(this, g, x, y) 前,先呼叫 super.paintComponent(g),讓 Swing 在繪圖前準備好面板。此範例會在記憶體中建立一張小影像,並在 Swing 的事件派送執行緒上啟動 GUI 設定。若要在無頭模式下安全地執行並繪製,請不要提供引數;若要在可正常使用圖形介面的環境中於框架視窗顯示面板,請加上 --show:

執行此範例:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main {
  private static class IconPanel extends JPanel {
    private final ImageIcon icon;

    IconPanel(ImageIcon icon) {
      this.icon = icon;
      setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      icon.paintIcon(this, g, 0, 0);
    }
  }

  public static void main(String[] args) {
    boolean showWindow = args.length > 0 && "--show".equals(args[0]);
    if (!showWindow) {
      System.setProperty("java.awt.headless", "true");
    }

    BufferedImage source = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
    Graphics2D sourceGraphics = source.createGraphics();
    sourceGraphics.setColor(Color.BLUE);
    sourceGraphics.fillRect(0, 0, 16, 16);
    sourceGraphics.dispose();

    ImageIcon icon = new ImageIcon(source);
    SwingUtilities.invokeLater(() -> {
      if (showWindow) {
        JFrame frame = new JFrame("Paint an ImageIcon");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new IconPanel(icon));
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
      }
      System.out.println("Icon size: " + icon.getIconWidth() + "x" + icon.getIconHeight());
    });
  }
}
Icon size: 16x16

面板會使用圖示的寬度與高度,而 paintComponent 會從左上角開始繪製。不帶參數執行時,程式只在無頭模式下建立圖示並印出其尺寸;只有在圖形工作階段中帶 --show 執行時,圖示才會真正繪製到面板中。若要改為載入影像檔,請使用路徑建立圖示,例如 new ImageIcon("delftstack.jpg");將檔案放在應用程式的工作目錄中,或提供正確路徑。若檔案不存在或無法讀取,就無法顯示預期的圖示,因此請確認路徑是相對於程序的工作目錄。封裝應用程式時,使用類別路徑資源通常比相對於工作目錄的路徑可靠。此範例使用記憶體中的影像,不依賴該外部檔案。

將 ImageIcon 加到 Java 按鈕

將 ImageIcon 傳入 JButton 建構子,即可在按鈕上顯示影像。此範例會在記憶體中建立三個圖示,並將按鈕加到使用 FlowLayout 的 JPanel。若要在無頭模式下安全地建立按鈕,請不要提供引數;若要在可正常使用圖形介面的環境中於框架視窗顯示按鈕,請加上 --show:

執行此範例:

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main {
  private static ImageIcon makeIcon(Color color) {
    BufferedImage image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
    image.setRGB(8, 8, color.getRGB());
    return new ImageIcon(image);
  }

  public static void main(String[] args) {
    boolean showWindow = args.length > 0 && "--show".equals(args[0]);
    if (!showWindow) {
      System.setProperty("java.awt.headless", "true");
    }

    SwingUtilities.invokeLater(() -> {
      JButton facebookButton = new JButton(makeIcon(Color.BLUE));
      JButton twitterButton = new JButton(makeIcon(Color.CYAN));
      JButton emailButton = new JButton(makeIcon(Color.RED));
      JPanel buttonPanel = new JPanel(new FlowLayout());
      buttonPanel.add(facebookButton);
      buttonPanel.add(twitterButton);
      buttonPanel.add(emailButton);

      if (showWindow) {
        JFrame frame = new JFrame("ImageIcon Buttons");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(buttonPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
      }

      System.out.println("Buttons created: "
          + facebookButton.getIcon().getIconWidth() + ", "
          + twitterButton.getIcon().getIconWidth() + ", "
          + emailButton.getIcon().getIconWidth());
    });
  }
}
Buttons created: 16, 16, 16

若要載入影像檔,請將每個 makeIcon(...) 呼叫改成使用圖示,例如 new ImageIcon("facebook.png")、new ImageIcon("twitter.png") 或 new ImageIcon("email.png")。請將這些檔案放在應用程式使用的路徑下,或改用類別路徑資源,並確認從應用程式的工作目錄能找到每個檔案。FlowLayout 會將三個按鈕排成一列;面板再加入框架視窗中顯示。此範例將 Facebook、Twitter 與電子郵件按鈕的用途,與在自訂面板中繪製圖示分開示範。