调用mouseClicked()后JComponents消失

我正在用Swing编写Java GUI程序。 界面如下所示:

程序

当用户点击右侧的其中一张图片时,我希望它的小预览显示在左上角的橙色区域中。 我通过SwingWorker线程从计算机上的目录中提取所有图像文件。 在SwingWorker的done()方法中 ,我向每个对象添加一个mouseClicked侦听器(来自我创建的类的TaggableImage对象。它具有BufferedImage并扩展JComponent,覆盖paintComponent()方法)。 在mouseClicked监听器中,我调用橙色面板的add()方法并将其传递给TaggableImage。

我的问题:

当我点击其中一个图像时,它不会被添加到橙色面板,它会从右侧的面板中消失。 如果我单击所有图像,我将留下一个空白的右侧面板。 为什么会这样?

这是我的整个SwingWorker线程:

SwingWorker<ArrayList, Void> loadImagesAsyncWorker = new SwingWorker<ArrayList, Void>() { ArrayList img_list = new ArrayList(); @Override protected ArrayList doInBackground() throws Exception { File currentDirectory = new File("."); getFileInDirectory(currentDirectory); return null; } // recursively get all files in this directory and child directories private void getFileInDirectory(File cd) { File[] file_list = cd.listFiles(); for (File f : file_list) { if (f.isDirectory()) { getFileInDirectory(f); } else if (f.isFile()) { BufferedImage bf = null; String extension = ""; int i = f.getName().lastIndexOf('.'); int p = Math.max(f.getName().lastIndexOf('/'), f.getName() .lastIndexOf('\\')); if (i > p) { extension = f.getName().substring(i + 1); } System.out.println(f.getName()); if (extension.equals("jpg")) { try { bf = ImageIO.read(f); TaggableImage ti = new TaggableImage(bf); img_list.add(ti); } catch (IOException e) { } } } } } public void done() { for (TaggableImage ti : img_list) { final TaggableImage final_ti = ti; ti.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { final_ti.setMaximumSize(new Dimension(30, 30)); BorderLayout layout = (BorderLayout) getContentPane() .getLayout(); if (layout.getLayoutComponent(BorderLayout.CENTER) != null) { img_prev_panel.remove(layout .getLayoutComponent(BorderLayout.CENTER)); } //img_prev_panel = the orange panel img_prev_panel.add(final_ti, BorderLayout.CENTER); }); } } }; 

这是我的TaggableImage类:

 import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; import javax.swing.JComponent; public class TaggableImage extends JComponent { private static final long serialVersionUID = 1L; private BufferedImage bufferedImage; private int height; private int width; public TaggableImage(BufferedImage bufferedImage) { this.bufferedImage = bufferedImage; } public TaggableImage(BufferedImage bufferedImage, int width, int height) { this.bufferedImage = bufferedImage; this.width = width; this.height = height; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(bufferedImage, 0, 0, null); } } 

考虑使用右侧面板的JList来利用灵活的布局选项和选择处理,如下所示。

在此处输入图像描述

 import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.ListSelectionModel; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; /** * @see https://stackoverflow.com/a/25170471/230513 */ public class ListDisplayPanel { private static final Icon icon = UIManager.getIcon("html.pendingImage"); private ListPanel listPanel = new ListPanel(); private DisplayPanel displayPanel = new DisplayPanel(); private class DisplayPanel extends JPanel { private static final int SIZE = 256; private JLabel label = new JLabel(); public DisplayPanel() { this.add(label); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); BufferedImage img = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D temp = (Graphics2D) img.getGraphics(); icon.paintIcon(this, temp, 0, 0); temp.dispose(); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.drawImage(img, 0, 0, getWidth(), getHeight(), this); } @Override public Dimension getPreferredSize() { return new Dimension(SIZE, SIZE); } } private class ListPanel extends JPanel { private static final int N = 5; private DefaultListModel dlm = new DefaultListModel(); private JList list = new JList(dlm); public ListPanel() { super(new GridLayout()); for (int i = 0; i < N * N; i++) { String name = "Cell-" + String.format("%02d", i); dlm.addElement(name); } list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setLayoutOrientation(JList.HORIZONTAL_WRAP); list.setVisibleRowCount(N); list.setCellRenderer(new ListRenderer()); list.addListSelectionListener(new SelectionHandler()); this.add(list); } private class ListRenderer extends DefaultListCellRenderer { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = (JLabel) super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); label.setBorder(BorderFactory.createEmptyBorder(N, N, N, N)); label.setIcon(icon); label.setHorizontalTextPosition(JLabel.CENTER); label.setVerticalTextPosition(JLabel.BOTTOM); return label; } } private class SelectionHandler implements ListSelectionListener { @Override public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { displayPanel.label.setText((String) dlm.getElementAt(e.getLastIndex())); } } } } private void display() { JFrame f = new JFrame("Test"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JSplitPane jsp = new JSplitPane(); jsp.setRightComponent(new JScrollPane(listPanel)); jsp.setLeftComponent(displayPanel); f.add(jsp); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(() -> { new ListDisplayPanel().display(); }); } }