java - 用Java创建一个漂亮的 ListView

标签 java swing jlist

我是 Java swing 新手,我正在尝试创建一个显示目录内容的 ListView 。我希望创建一个如下图所示的 View : enter image description here

我知道如何使用 JList,但我不知道如何显示与文件类型匹配的图标。正如您所看到的,从图像中,我们可以直观地区分 pdf 文件与文本文件等。我应该尝试使用 JList 或其他 UI 组件吗?

最佳答案

我也做过类似的事情;这是我的输出示例。

enter image description here

我为树使用了自定义渲染器;它会生成您在显示屏最左边一列的一个单元格中看到的缩进、图标和文本。这是其来源:

package spacecheck.ui.renderer;

import java.awt.Component;

import javax.swing.ImageIcon;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;

import spacecheck.filedata.FileCollection;
import spacecheck.images.TreeIcon;

/**
 * renders the name of a collection for the tree display.
 * @author rcook
 *
 */
public class CollectionNameRenderer extends DefaultTableCellRenderer // which implements JLabel
//    implements TableCellRenderer
{
  private static final long serialVersionUID = 1L;
  @SuppressWarnings({"unused"})
  private void say(String msg) { System.out.println(msg); }

  private static TreeIcon tIcon = null;

  /**
   * set the value of the CollectionName for the JTable; includes using
   * indent so that the correct icon can be obtained (icons are different widths
   * to implement different indent levels).
   */
  public void setValue(Object value)
  {
    FileCollection fc = (FileCollection)value;
    boolean expanded = fc.isExpanded();
    int level = fc.getDisplayLevel();
//    boolean isSelected = table.
    ImageIcon icon = tIcon.getIcon(level, expanded);
    if (icon != null) { setIcon(icon); }
    setText(value.toString());
  }

  /**
   * get the renderer component for a collection name.
   */
  public Component getTableCellRendererComponent
      (JTable table, Object value, boolean isSelected, boolean hasFocus, 
          int rowIndex, int colIndex)
  {
    if (tIcon == null) { tIcon = new TreeIcon(table.getBackground()); }
    return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, rowIndex, colIndex);
  }
}

该类使用我的另一个类,名为 TreeIcon;它实现了如图所示的文件夹图标的缩进,以及根据文件夹的展开/未展开状态选择图标。这是该类:

package spacecheck.images;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * represents an icon used in the directory tree; handles 'expanded' and
 * 'unexpanded' directories as well as indentation representing different
 * levels.
 * @author rcook
 *
 */
public class TreeIcon
{
  public static int UNEXPANDED = 1;
  public static int EXPANDED = 2;

  @SuppressWarnings({"unused"})
  private void say (String msg) { System.out.println(msg); }

  private static ImageIcon expandedIcon = null;
  private static ImageIcon unexpandedIcon = null;
  private static int       iconHeight = 0;
  private static int       iconWidth  = 0;

  private static ArrayList<ImageIcon> cachedExpandedIcons = new ArrayList<ImageIcon>();
  private static ArrayList<ImageIcon> cachedUnexpandedIcons = new ArrayList<ImageIcon>();

  static
  {
    expandedIcon = new ImageIcon(TreeIcon.class.getResource("images/Expanded.png"));
    unexpandedIcon = new ImageIcon(TreeIcon.class.getResource("images/Unexpanded.png"));
    iconHeight = unexpandedIcon.getIconHeight();
    iconWidth =  unexpandedIcon.getIconWidth();
  }

  public TreeIcon(Color givenColor)  {  }

  public static void main(String ... arguments)
  {
    JFrame frame = new JFrame("icon test");
    JLabel label = new JLabel("background test");
    label.setBackground(Color.blue);
    TreeIcon treeIcon = new TreeIcon(Color.black);
    ImageIcon icon = treeIcon.getIcon(2, false);
    label.setIcon(icon);
    frame.add(label);
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * return the icon for an expanded or unexpanded level
   * @param int level of folder relative to other levels displayed;
   * starts at 0 and increases with depth
   * @param boolean indicates whether this level is expanded or not.
   * @return ImageIcon appropriate for expansion flag and level.
   */
  public ImageIcon getIcon(int level, boolean expanded)
  {
    ImageIcon result = null;

    if (level < 0)
    { System.out.println("level is " + level + ", setting to 0");
      level = 0;
    }

    // set our list of icons depending on whether we are expanded.
    ArrayList<ImageIcon> cachedIcons = cachedUnexpandedIcons;
    if (expanded) { cachedIcons = cachedExpandedIcons; }

    // if we already have this icon in our cache, return it.
    if (cachedIcons.size() >= (level+1) && cachedIcons.get(level) != null)
    {
      result = cachedIcons.get(level);
    }
    else
    {
      // generate this icon and store it in the cache before returning it.
      ImageIcon baseIcon = unexpandedIcon;
      if (expanded) { baseIcon = expandedIcon; }
      int iconH = iconHeight;
      int iconW = iconWidth*(level+1);

      BufferedImage bufferedImage = new BufferedImage(iconW,iconH,BufferedImage.TYPE_INT_ARGB);
      Graphics g = bufferedImage.getGraphics();

      g.drawImage(baseIcon.getImage(), iconWidth*level, 0, null);

      result = new ImageIcon(bufferedImage);

      // we've created an icon that was not in the cached list; 
      // the cached list may have a null at this slot, or it may not yet be
      // long enough to have this slot.  Ensure that we have enough slots
      // in the list, and then add this icon.
      for (int i=cachedIcons.size(); i<=level; i++)
      {
        cachedIcons.add(null);
      }
//      if (cachedIcons.size() < level + 1) { cachedIcons.add(result); }
//                                     else { 
      cachedIcons.set(level, result); 
//      }
//      say("adding icon, level = " + level + (expanded ? " " : " un") + "expanded, width = " + iconW);
    }

    return result;
  }
}

要为不同类型的文件选择图标,您可以让渲染器和图标选择器查看文件扩展名(或其他内容)来确定要使用 map 中的哪个图标。

希望有帮助!

关于java - 用Java创建一个漂亮的 ListView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27668160/

相关文章:

java - 双重打印JList

java - 当通过鼠标更改值时,JList 会触发 valueChanged 两次

java - 如何将未选定的项目从列表移动到另一个列表?列表

java - 只允许使用 Android SQLite 输入唯一数据?

Java Swing 按钮 Action 事件

java - 从 Firebase 存储下载文件并在需要时显示它,即使应用程序处于离线状态也是如此

java - JTable 基于对象列表,如 TableView 的项目列表

java - Apache POI 工作簿中的多线程

java - 如何获取所选文件和文件夹的实际大小?

java - 在 Java Swing 应用程序中保留对象值