1

私はJPanelにグリッドのように画像を表示する方法を探していましたが、この解決策に出くわしました。jpgコードは非常にうまく機能しますが、長方形を描く代わりに画像を使用してコードを変更しようとすると、機能させることができませんでした。私の変更は次のとおりです。

/*
 * courtesy of https://stackoverflow.com/questions/7222988/java-drag-and-drop-images-  in-a-list
 */

import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.io.Serializable;
import javax.swing.*;
import javax.swing.border.Border;

public class ImagePreviewList {

public static void main(String[] args) throws Exception {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    JFrame frame = new JFrame("Image panel");
    frame.setSize(800, 300);
    frame.setLocationByPlatform(true);
    JList imageList = createImageList();
    frame.getContentPane().add(new JScrollPane(imageList));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

private static JList createImageList() {

    JList imageList = new JList(createModel());
    imageList.setCellRenderer(new ImageCellRenderer());
    imageList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
    imageList.setVisibleRowCount(-1);
    imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    imageList.setFixedCellWidth(240);
    imageList.setFixedCellHeight(120);

    imageList.setDragEnabled(true);
    imageList.setDropMode(DropMode.INSERT);
    imageList.setTransferHandler(new ImageTransferHandler(imageList));

    return imageList;
}

private static DefaultListModel createModel() {
    DefaultListModel model = new DefaultListModel();
    model.addElement(new RTS_image("3-Way_Stop_sign"));
    model.addElement(new RTS_image("4-Way_Stop_sign"));
    model.addElement(new RTS_image("No_Entry_sign"));
    model.addElement(new RTS_image("One-Way_Roadway_sign-0"));
    model.addElement(new RTS_image("One-Way_Roadway_sign-1"));
    model.addElement(new RTS_image("One-Way_Roadway_sign-3"));
    model.addElement(new RTS_image("Pedestrian-Priority_sign"));
    model.addElement(new RTS_image("Stop#Go_sign"));
    model.addElement(new RTS_image("Stop_and_Yield_sign"));
    model.addElement(new RTS_image("Stop_sign-0"));
    model.addElement(new RTS_image("Stop_sign-1"));
    model.addElement(new RTS_image("Yield_at_Mini-Circle_sign"));
    model.addElement(new RTS_image("Yield_sign"));
    model.addElement(new RTS_image("Yield_to_Pedestrians_sign"));
    model.addElement(new RTS_image("Yield_to_oncoming_traffic_sign"));
    return model;
}

static class ImageTransferHandler extends TransferHandler {

    private static final DataFlavor DATA_FLAVOUR = new DataFlavor(RTS_image.class,  "Images");

    private final JList previewList;
    private boolean inDrag;

    ImageTransferHandler(JList previewList) {
        this.previewList = previewList;
    }

    public int getSourceActions(JComponent c) {
        return TransferHandler.MOVE;
    }

    protected Transferable createTransferable(JComponent c) {
        inDrag = true;
        return new Transferable() {
            public DataFlavor[] getTransferDataFlavors() {
                return new DataFlavor[] {DATA_FLAVOUR};
            }

            public boolean isDataFlavorSupported(DataFlavor flavor) {
                return flavor.equals(DATA_FLAVOUR);
            }

            public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
                return previewList.getSelectedValue();
            }
        };
    }

    public boolean canImport(TransferSupport support) {
        if (!inDrag || !support.isDataFlavorSupported(DATA_FLAVOUR)) {
            return false;
        }

        JList.DropLocation dl = (JList.DropLocation)support.getDropLocation();
        if (dl.getIndex() == -1) {
            return false;
        } else {
            return true;
        }
    }

    public boolean importData(TransferSupport support) {
        if (!canImport(support)) {
            return false;
        }

        Transferable transferable = support.getTransferable();
        try {
            Object draggedImage = transferable.getTransferData(DATA_FLAVOUR);

            JList.DropLocation dl = (JList.DropLocation)support.getDropLocation();
            DefaultListModel model = (DefaultListModel)previewList.getModel();
            int dropIndex = dl.getIndex();
            if (model.indexOf(draggedImage) < dropIndex) {
                dropIndex--;
            }
            model.removeElement(draggedImage);
            model.add(dropIndex, draggedImage);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    protected void exportDone(JComponent source, Transferable data, int action) {
        super.exportDone(source, data, action);
        inDrag = false;
    }
}

static class ImageCellRenderer extends JPanel implements ListCellRenderer {

    DefaultListCellRenderer defaultListCellRenderer = new DefaultListCellRenderer();
    JLabel imageLabel = new JLabel();
    JLabel descriptionLabel = new JLabel();

    ImageCellRenderer() {
        setLayout(new BorderLayout());
        Border emptyBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
        imageLabel.setBorder(emptyBorder);
        descriptionLabel.setBorder(emptyBorder);
        add(imageLabel, BorderLayout.CENTER);
        add(descriptionLabel, BorderLayout.SOUTH);
    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        defaultListCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        setBorder(defaultListCellRenderer.getBorder());
        setBackground(defaultListCellRenderer.getBackground());
        imageLabel.setIcon((Icon)value);
        descriptionLabel.setText("Description");
        return this;
    }
}

static class RTS_image implements Icon, Serializable {
    private String Name_of_RoadSign; 

    RTS_image(String name_of_roadsign) {
        this.Name_of_RoadSign = name_of_roadsign;
    }

    java.net.URL imgURL = com.umusebo.RTS.ImagePreviewList.class.getResource("images/01_Regulatory_Signs/01_Control_Signs/reg_cont_" + Name_of_RoadSign + ".jpg");

    Image img = Toolkit.getDefaultToolkit().createImage(imgURL);

    public void paintIcon(Component c, Graphics g, int x, int y) {
        g.drawImage(img, x, y, c);
    }

    public int getIconWidth() {
        return 114;
    }

    public int getIconHeight() {
        return 125;
    }

    public String getName_of_RoadSign() {
        return Name_of_RoadSign;
    }

    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        return Name_of_RoadSign.equals(((RTS_image)o).Name_of_RoadSign);
    }

}

}

実行すると、次のエラーが発生します(表示しようとしている15枚の画像に対して15回繰り返されます)。

Uncaught error fetching image:
java.lang.NullPointerException
at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:115)
at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:125)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:263)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:205)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:169)

問題はどこにあるのでしょうか?

4

1 に答える 1

3

他の変数の値を使用して初期化しようとしている多くのクラス レベル フィールドを宣言しました。null

たとえばimgURL、変数を宣言して初期化Name_of_RoadSignすると、 になりますnull

java.net.URL imgURL = com.umusebo.RTS.ImagePreviewList.class.getResource(
    "images/01_Regulatory_Signs/01_Control_Signs/reg_cont_"
    + Name_of_RoadSign + ".jpg");

クラスのコンストラクターが実行される前に、クラスのフィールドが初期化されることを覚えておく必要があります。

代わりに、コンストラクター内でこれらのクラス変数を初期化してみてください

RTS_image(String name_of_roadsign) {
    this.Name_of_RoadSign = name_of_roadsign;
    imgURL = com.umusebo.RTS.ImagePreviewList.class.getResource(
        "images/01_Regulatory_Signs/01_Control_Signs/reg_cont_"
        + Name_of_RoadSign + ".jpg");
    img = Toolkit.getDefaultToolkit().createImage(imgURL);
}

ToolKit#createImageエラーを黙って無視する傾向がありnull、画像をロードできない場合でも none 値を返します。ImageIO代わりに使用する方がはるかに優れています。より広い範囲の画像形式をサポートするという事実とは別に、より意味のある例外をスローするため、問題の診断が容易になります。

例えば...

img = ImageIO.read(imgURL);

忘れないでください。これは をスローするIOExceptionので、それをキャッチするか、(さらに良いことに) 呼び出し元に渡す必要があります。

また、Java プログラミング言語のコード規約をよく理解することをお勧めします。無視して友達を作ったり、人々に影響を与えたりすることはできません。;)

于 2013-02-03T19:30:14.173 に答える