如何在JList Java中更改描述图像 [英] How to change description image in JList java

查看:109
本文介绍了如何在JList Java中更改描述图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的代码,该代码在JList中显示图像.我想通过JList中显示的每个图像来编辑描述.我不知道该怎么做需要帮忙.谢谢...

Below is my code that displays images in a JList. I want to edit the description by each of the images shown in the JList. I don't know how to do it & need help. Thanks...

import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Serializable;

public class DesignPicture2 {

    private static String imageName;
    static ArrayList<String> imgName = new ArrayList<String>();

    public static void main(String[] args) throws Exception {
        DesignPicture2 mm = new DesignPicture2();
        mm.getImageName("C:\\Images 2 display");

        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        JFrame frame = new JFrame("Image panel");
        frame.setSize(800, 500);
        //frame.setLocationByPlatform(true);
        frame.setLocation(600, 300);

        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("C:\\Images 2 display"));
        imageList.setCellRenderer(new ImageCellRenderer());
        imageList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        imageList.setVisibleRowCount(0);
        imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        imageList.setFixedCellWidth(240);
        imageList.setFixedCellHeight(120);

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

        return imageList;
    }

    private static DefaultListModel createModel(String path) {

        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();
        DefaultListModel model = new DefaultListModel();

        int count = 0;
        for (int i = 0; i < listOfFiles.length - 1; i++) {
            System.out.println("check path: " + listOfFiles[i]);
            imageName = imgName.get(i).toString();
            String name = listOfFiles[i].toString();
            //load only JPEGS

            if (name.endsWith("jpg")) {
                try {
                    ImageIcon ii = new ImageIcon(ImageIO.read(listOfFiles[i]));
                    model.add(count, ii);

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        return model;
    }

    static class ImageTransferHandler extends TransferHandler {

        private static final DataFlavor DATA_FLAVOUR = new DataFlavor(ColorIcon.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 {

        int count = 0;
        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.AFTER_LINE_ENDS);
            add(descriptionLabel, BorderLayout.SOUTH);

            // imageLabel.setText(imgName.get(0).toString());
        }

        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);

            if (count > imgName.size() - 1) {
                count = 0;
            } else {
                descriptionLabel.setText(imgName.get(count).toString());

            }
            return this;
        }

    }

    public void getImageName(String path) {
        int c = 0;
        final File dir = new File(path);

        // array of supported extensions (use a List if you prefer)
        final String[] EXTENSIONS = new String[]{
            "jpg", "gif", "png", "bmp" // and other formats you need
        // filter to identify images based on their extensions
        };
        final FilenameFilter IMAGE_FILTER = new FilenameFilter() {

            @Override
            public boolean accept(final File dir, final String name) {
                for (final String ext : EXTENSIONS) {
                    if (name.endsWith("." + ext)) {
                        return (true);
                    }
                }
                return (false);
            }
        };

        if (dir.isDirectory()) { // make sure it's a directory
            for (final File f : dir.listFiles(IMAGE_FILTER)) {
                BufferedImage img = null;
                c++;
                try {
                    img = ImageIO.read(f);

                    // you probably want something more involved here
                    // to display in your UI
                    System.out.println("image: " + f.getName());
                    imgName.add(f.getName().toString());

                } catch (final IOException e) {
                    // handle errors here
                    System.out.println("Error!");
                }
            }
            System.out.println("C: " + c);
        } else {
            System.out.println("Invalid Directory!");
        }
    }

    static class ColorIcon implements Icon, Serializable {

        private Color color;

        ColorIcon(Color color) {
            this.color = color;
        }

        public void paintIcon(Component c, Graphics g, int x, int y) {
            g.setColor(color);
            g.fillRect(x, y, getIconWidth(), getIconHeight());
        }

        public int getIconWidth() {
            return 200;
        }

        public int getIconHeight() {
            return 100;
        }

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

}

运行上面的代码时,它以正确的方式显示图像,但是每个图像的描述都是固定的,我不知道如何更改.希望任何人都能帮助我.

When I run the above code, it show the image in proper way, but the description of each image is fixed and I don't know how to change it. Hope anyone can help me.

推荐答案

我同意垃圾桶"(他的建议+1),JTable将是一个更简单的解决方案,这就是为什么...

I agree with trashgod (+1 to his suggestion), a JTable will be a simpler solution, here's why...

JList不支持可编辑性,因此您需要创建它...

JList doesn't support editability, so you'd need to create it...

因此,首先,我们需要某种ListModel,它提供一些附加功能,尤其是能够在特定索引处设置值的功能.

So, first, we'd need some kind of ListModel that provided some additional functionality, in particular, the ability to set the value at a particular index...

import javax.swing.ListModel;

public interface MutableListModel<E> extends ListModel<E> {

    public void setElementAt(E value, int index);

    public boolean isCellEditable(int index);

}

接下来,我们需要某种类型的编辑器,在这种情况下,遵循标准的Swing API约定,这需要某种基本的interface

Next, we'd need some kind editor, in this case, following standard Swing API conventions, this asks for some kind of base interface

import java.awt.Component;
import javax.swing.CellEditor;
import javax.swing.JList;

public interface ListCellEditor<E> extends CellEditor {

    public Component getListCellEditorComponent(
            JList<E> list,
            E value,
            boolean isSelected,
            int index);

    public void applyEditorValue(E value);

}

现在,我们需要为自己创建一个自定义JList,它能够实际执行编辑单元格值所需的所有功能...

Now, we need to create ourselves a custom JList capable of actually performing all the required functionality of editing a cell value...

类似...

  • 识别开始编辑"事件
  • 确定是否可以编辑单元格
  • 管理编辑过程,准备并显示编辑器,知道编辑器何时停止或取消并适当清理...
  • 在编辑过程中处理选择发生变化
  • 处理组件焦点更改(我还没有做,因为它本身就带来了很多乐趣……)

例如...

import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JList;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class EditableList<E> extends JList<E> {

    private ListCellEditor<E> editor;
    private int editingCell = -1;
    private Component editorComponent;

    private CellEditorHandler handler;

    public EditableList(MutableListModel<E> model) {
        this();
        setModel(model);
    }

    public EditableList() {
        InputMap im = getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "editorCell");

        ActionMap am = getActionMap();
        am.put("editorCell", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Edit baby");
                int cell = getSelectedIndex();
                editCellAt(cell);
            }
        });

        addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (isEditing()) {

                    if (!stopCellEditing()) {

                        cancelCellEditing();

                    }

                }
            }
        });
    }

    public boolean isEditing() {

        return editorComponent != null;

    }

    public void cancelCellEditing() {

        getEditor().cancelCellEditing();

    }

    public boolean stopCellEditing() {

        return getEditor().stopCellEditing();

    }

    public CellEditorHandler getCellEditorHandler() {
        if (handler == null) {
            handler = new CellEditorHandler();
        }
        return handler;
    }

    public void setEditor(ListCellEditor<E> value) {
        if (value != editor) {
            ListCellEditor old = editor;
            editor = value;
            firePropertyChange("editor", old, editor);
        }
    }

    public ListCellEditor<E> getEditor() {
        return editor;
    }

    public boolean isCellEditable(int cell) {

        boolean isEditable = false;

        ListModel model = getModel();
        if (model instanceof MutableListModel) {

            MutableListModel mcm = (MutableListModel) model;
            isEditable = mcm.isCellEditable(cell);

        }

        return isEditable;

    }

    protected void editCellAt(int index) {

        if (isCellEditable(index)) {

            ListCellEditor<E> editor = getEditor();
            if (editor != null) {

                Rectangle cellBounds = getCellBounds(index, index);
                E value = getModel().getElementAt(index);
                boolean selected = isSelectedIndex(index);
                editingCell = index;

                editor.addCellEditorListener(getCellEditorHandler());
                editorComponent = editor.getListCellEditorComponent(this, value, selected, index);
                editorComponent.setBounds(cellBounds);

                ensureIndexIsVisible(index);

                add(editorComponent);

                revalidate();

            }

        }

    }

    public int getEditingCell() {
        return editingCell;
    }

    protected void editingHasStopped(ListCellEditor editor) {

        editingCell = -1;

        if (editorComponent != null) {
            remove(editorComponent);
        }

        if (editor != null) {

            editor.removeCellEditorListener(getCellEditorHandler());

        }

    }

    public class CellEditorHandler implements CellEditorListener {

        @Override
        public void editingStopped(ChangeEvent e) {

            E value = getModel().getElementAt(getEditingCell());

            getEditor().applyEditorValue(value);
            ((MutableListModel) getModel()).setElementAt(value, getEditingCell());

            editingHasStopped((ListCellEditor)e.getSource());

        }

        @Override
        public void editingCanceled(ChangeEvent e) {

            editingHasStopped((ListCellEditor)e.getSource());

        }

    }

}

现在,完成所有这些之后,您将需要更改程序结构的方式,而不是使用ListListModel分别管理描述和图像,您应该将概念合并到单个可管理对象,例如...

Now, having done all that, you will need change the way you've structured your program, instead of using a List and ListModel to manage the descriptions and images separately, you should probably merge the concept into a single, manageable object, for example...

public class ImagePreview {

    private String name;
    private ImageIcon image;

    public ImagePreview(String name, ImageIcon image) {
        this.name = name;
        this.image = image;
    }

    public String getDescription() {
        return name;
    }

    public ImageIcon getImage() {
        return image;
    }

    protected void setDescription(String description) {
        this.name = description;
    }

}

即使您选择使用JTable,您也会发现它更易于管理...

Even if you choose to use a JTable instead, you'll find this easier to manage...

现在我们需要某种方式来渲染和编辑这些值,为此,我选择从一个基本组件开始,该组件可以显示图像和文本...

Now we need some way to render and edit these values, to this end, I choose to start with a base component which could display the image and text...

public class ImagePreviewPane extends JPanel {

    private JLabel imageLabel = new JLabel();
    private JLabel descriptionLabel = new JLabel();

    public ImagePreviewPane() {
        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);
    }

    protected JLabel getDescriptionLabel() {
        return descriptionLabel;
    }

    protected JLabel getImageLabel() {
        return imageLabel;
    }

    public void setImage(ImageIcon icon) {
        imageLabel.setIcon(icon);
    }

    public void setDescription(String text) {
        descriptionLabel.setText(text);
    }

}

创建可以处理编辑内容的扩展版本...

Create an extended version that could handle editing...

public static class ImagePreviewEditorPane extends ImagePreviewPane {

    private JTextField editor;

    public ImagePreviewEditorPane() {
        super();
        editor = new JTextField();
        remove(getDescriptionLabel());
        add(editor, BorderLayout.SOUTH);
    }

    @Override
    public void setDescription(String text) {
        editor.setText(text);
    }

    public String getDescription() {
        return editor.getText();
    }

    public void setImagePreview(ImagePreview preview) {
        setImage(preview.getImage());
        setDescription(preview.getDescription());
    }

    @Override
    public void addNotify() {
        super.addNotify();
        editor.requestFocusInWindow();
    }

}

这样做是为了使以后更容易修改组件...

This is done to try and make it easier to modify the components later...

接下来,一个ListCellRenderer

public class ImageCellRenderer extends ImagePreviewPane implements ListCellRenderer {

    public ImageCellRenderer() {
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Color bg = null;
        Color fg = null;

        JList.DropLocation dropLocation = list.getDropLocation();
        if (dropLocation != null
                && !dropLocation.isInsert()
                && dropLocation.getIndex() == index) {

            bg = DefaultLookup.getColor(this, getUI(), "List.dropCellBackground");
            fg = DefaultLookup.getColor(this, getUI(), "List.dropCellForeground");

            isSelected = true;
        }

        if (isSelected) {
            setBackground(bg == null ? list.getSelectionBackground() : bg);
            setForeground(fg == null ? list.getSelectionForeground() : fg);
        } else {
            setBackground(list.getBackground());
            setForeground(list.getForeground());
        }

        if (value instanceof ImagePreview) {
            ImagePreview ip = (ImagePreview) value;
            setImage(ip.getImage());
            setDescription(ip.getDescription());
        } else {
            setImage(null);
            setDescription("??");
        }

        setEnabled(list.isEnabled());
        setFont(list.getFont());

        return this;
    }

}

还有编辑...

public class ImagePreviewListCellEditor extends AbstactListCellEditor<ImagePreview> {

    private ImagePreviewEditorPane previewPane;

    public ImagePreviewListCellEditor() {
        previewPane = new ImagePreviewEditorPane();
        InputMap im = previewPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "accept");
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");

        ActionMap am = previewPane.getActionMap();
        am.put("accept", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                stopCellEditing();
            }
        });
        am.put("cancel", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                cancelCellEditing();
            }
        });
    }

    public void applyEditorValue(ImagePreview preview) {
        preview.setDescription(previewPane.getDescription());
    }

    @Override
    public Component getListCellEditorComponent(JList<ImagePreview> list, ImagePreview value, boolean isSelected, int index) {

        Color bg = null;
        Color fg = null;

        JList.DropLocation dropLocation = list.getDropLocation();
        if (dropLocation != null
                && !dropLocation.isInsert()
                && dropLocation.getIndex() == index) {

            bg = DefaultLookup.getColor(previewPane, previewPane.getUI(), "List.dropCellBackground");
            fg = DefaultLookup.getColor(previewPane, previewPane.getUI(), "List.dropCellForeground");

            isSelected = true;
        }

        if (isSelected) {
            previewPane.setBackground(bg == null ? list.getSelectionBackground() : bg);
            previewPane.setForeground(fg == null ? list.getSelectionForeground() : fg);
        } else {
            previewPane.setBackground(list.getBackground());
            previewPane.setForeground(list.getForeground());
        }

        if (value instanceof ImagePreview) {
            ImagePreview preview = (ImagePreview)value;
            previewPane.setImagePreview(preview);
        } else {
            previewPane.setImagePreview(null);
        }

        return previewPane;
    }

}

最后,把它放在一起……

And finally, putting it altogether...

public class DesignPicture2 {

    public static void main(String[] args) throws Exception {

        DesignPicture2 mm = new DesignPicture2();

        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        JFrame frame = new JFrame("Image panel");
        frame.setSize(800, 500);
        frame.setLocation(600, 300);

        JList imageList = createImageList();

        frame.getContentPane().add(new JScrollPane(imageList));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static JList createImageList() {

        EditableList<ImagePreview> imageList = new EditableList(createModel("..."));
        imageList.setEditor(new ImagePreviewListCellEditor());
        imageList.setCellRenderer(new ImageCellRenderer());
        imageList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        imageList.setVisibleRowCount(0);
        imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        imageList.setFixedCellWidth(240);
        imageList.setFixedCellHeight(120);

        return imageList;
    }

    private static MutableListModel<ImagePreview> createModel(String path) {

        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();
        DefaultMutableListModel<ImagePreview> model = new DefaultMutableListModel<>();

        int count = 0;
        for (int i = 0; i < listOfFiles.length - 1; i++) {
            System.out.println("check path: " + listOfFiles[i]);
            String name = listOfFiles[i].toString();

            if (name.endsWith("jpg")) {
                try {
                    ImageIcon ii = new ImageIcon(ImageIO.read(listOfFiles[i]));
                    model.addElement(new ImagePreview(name, ii));

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        return model;
    }
}

这篇关于如何在JList Java中更改描述图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆