将文件从操作系统拖放到 Java 应用程序 (Swing)

2023-11-22

首先我要说的是我一直在阅读拖放教程以及类似的问题,但不幸的是我对这件事变得更加困惑。我想要实现的目标相对简单,所以我很惊讶它已经给我带来了这么多麻烦。我正在编写一个小型实用程序应用程序,它将把一堆结果文件(自定义定义的 xml 类型)合并到一个大型的制表符分隔的文本文件中。大多数功能已经编码,但我想为其制作一个像样的 GUI。

我想要的是能够将文件拖放到组件中(例如JTextArea)以一种美好而亲切的方式(阅读:不是完整路径,而是一个小图标和名称)。我希望能够提供JFileChooser也可以浏览文件。然后我将按顺序解析文件以生成我想要的矩阵。

到目前为止我了解到的是框架已经存在,但是任何附加功能都需要定制。我在 Netbeans 中创建了一个测试 GUI,并尝试将一堆文件拖到JTextArea,但它们显示为文件路径,并且不可否认它看起来非常难看。

我真的很感激任何关于如何以简洁的方式解决(或澄清)这个问题的提示和指导。请注意,我确实打算在多个不同的操作系统(Mac、Win 和 Linux)上使用该软件。

EDIT:到目前为止,我的代码基于 Sun 教程中的示例之一,如下所示

import java.awt.datatransfer.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.*;

public class ConsolidatorDemo extends JPanel implements ActionListener {
    private static final long serialVersionUID = -4487732343062917781L;
    JFileChooser fc;
    JButton clear;
    JTextArea dropZone, console;
    JSplitPane childSplitPane, parentSplitPane;
    PrintStream ps;

  public ConsolidatorDemo() {
    super(new BorderLayout());

    fc = new JFileChooser();;
    fc.setMultiSelectionEnabled(true);
    fc.setDragEnabled(true);
    fc.setControlButtonsAreShown(false);
    fc.setFileSelectionMode(JFileChooser.FILES_ONLY);               


    JPanel fcPanel = new JPanel(new BorderLayout());
    fcPanel.add(fc, BorderLayout.CENTER);

    clear = new JButton("Clear All");
    clear.addActionListener(this);
    JPanel buttonPanel = new JPanel(new BorderLayout());
    buttonPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    buttonPanel.add(clear, BorderLayout.LINE_END);

    JPanel leftUpperPanel = new JPanel(new BorderLayout());
    leftUpperPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    leftUpperPanel.add(fcPanel, BorderLayout.CENTER);
    leftUpperPanel.add(buttonPanel, BorderLayout.PAGE_END);


    JScrollPane leftLowerPanel = new javax.swing.JScrollPane();
    leftLowerPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    dropZone = new JTextArea();
    dropZone.setColumns(20);
    dropZone.setLineWrap(true);
    dropZone.setRows(5);
    dropZone.setDragEnabled(true);
    dropZone.setDropMode(javax.swing.DropMode.INSERT);
    dropZone.setBorder(new TitledBorder("Selected files/folders"));
    leftLowerPanel.setViewportView(dropZone);

    childSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
            leftUpperPanel, leftLowerPanel);
    childSplitPane.setDividerLocation(400);
    childSplitPane.setPreferredSize(new Dimension(480, 650));

    console = new JTextArea();
    console.setColumns(40);
    console.setLineWrap(true);
    console.setBorder(new TitledBorder("Console"));

    parentSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                    childSplitPane, console);
    parentSplitPane.setDividerLocation(480);
    parentSplitPane.setPreferredSize(new Dimension(800, 650));

    add(parentSplitPane, BorderLayout.CENTER);

}

public void setDefaultButton() {
    getRootPane().setDefaultButton(clear);
}

public void actionPerformed(ActionEvent e) {
    if (e.getSource() == clear) {
        dropZone.setText("");

    }
}

/**
 * Create the GUI and show it. For thread safety,
 * this method should be invoked from the
 * event-dispatching thread.
 */
private static void createAndShowGUI() {
    //Make sure we have nice window decorations.
    JFrame.setDefaultLookAndFeelDecorated(true);
    try {
      //UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaBlackStarLookAndFeel");
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    }catch (Exception e){
      e.printStackTrace();
    }

    //Create and set up the window.
    JFrame frame = new JFrame("Consolidator!");
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    //Create and set up the menu bar and content pane.
    ConsolidatorDemo demo = new ConsolidatorDemo();
    demo.setOpaque(true); //content panes must be opaque
    frame.setContentPane(demo);

    //Display the window.
    frame.pack();
    frame.setVisible(true);
    demo.setDefaultButton();
}

public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}

这里有一个快速片段,用于将实际文件导入到 JList 中(而不是将其字符串表示形式导入到文本组件中)并使用自定义渲染器来很好地呈现它。它改编自 BasicDnD(在教程中):

    fileDropper = new JList(new DefaultListModel());
    fileDropper.setDragEnabled(true);
    leftLowerPanel.setViewportView(fileDropper);
    
    TransferHandler handler =   new TransferHandler() {

        @Override
        public boolean canImport(TransferHandler.TransferSupport info) {
            // we only import FileList
            if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                return false;
            }
            return true;
        }

        @Override
        public boolean importData(TransferHandler.TransferSupport info) {
            if (!info.isDrop()) {
                return false;
            }
            
            // Check for FileList flavor
            if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                displayDropLocation("List doesn't accept a drop of this type.");
                return false;
            }

            // Get the fileList that is being dropped.
            Transferable t = info.getTransferable();
            List<File> data;
            try {
                data = (List<File>)t.getTransferData(DataFlavor.javaFileListFlavor);
            } 
            catch (Exception e) { return false; }
            DefaultListModel model = (DefaultListModel) fileDropper.getModel();
            for (File file : data) {
                model.addElement(file);
            }
            return true;
        }
        
        private void displayDropLocation(String string) {
            System.out.println(string);
        }
    };
    fileDropper.setTransferHandler(handler);
    fileDropper.setCellRenderer(new DefaultListRenderer(
          StringValues.FILE_NAME, IconValues.FILE_ICON));

无法抗拒显示 SwingX 渲染器配置:-) 在核心 java 中,您将手动执行此操作,例如

   class MyRenderer extends DefaultListCellRenderer {
        
        @Override
        public Component getListCellRendererComponent(...) {
            super.getList...
            if (value instanceof File) {
                setText(FileSystemView.getFileSystemView().getSystemDisplayName(value);
                setIcon(FileSystemView.getFileSystemView().getSystemIcon(value);
            } 
            return this;
        }

   }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将文件从操作系统拖放到 Java 应用程序 (Swing) 的相关文章

随机推荐

  • 从手机浏览器获取位置数据

    我正在开发一个网络应用程序 该应用程序会经常受到移动浏览器的攻击 我想知道是否有办法从浏览器请求中获取足够的信息来查找位置数据 三角测量或 GPS 当然 不是直接来自请求 一位同事建议 一些运营商在请求标头中提供唯一标识符 该标识符可以发送
  • 使用 ggplot2 重现以下基本图

    I d like to reproduce the following base graph with ggplot2 以下是R生成该图的代码 set seed 12345 Data lt matrix data rnorm n 30 me
  • 类型错误:Ajv 不是构造函数

    我有这个课程 我尝试实例化Ajv使用 new 关键字 我收到此错误 类型错误 Ajv 不是构造函数 Code import as Ajv from ajv export class ValidateJsonService validateJ
  • 解决 Looper.java 中的非空和非空符号的问题

    我正在开发一个 Android 应用程序 请帮助我解决依赖错误 package android os import android support annotation NonNull import android support anno
  • 限制CPU负载或设置进程优先级

    这不是我第一次从我的主机收到 CPU 负载过高的警告 该代码只是一些带有 mysql 查询的随机 php 脚本 没什么花哨的 这些表格没什么特别的 最多几百行 如果需要的话我总是限制它们 我不介意它运行 0 15 秒而不是 0 05 秒 那
  • WPF中如何直接在位图(BitmapSource、WriteableBitmap)上绘图?

    在 GDI Winforms 中我会这样做 Bitmap b new Bitmap 32 32 Graphics g Graphics FromImage b some graphics code 如何使用 DrawingContext 在
  • 如果构造函数参数与 C++ 中的成员变量同名怎么办?

    首先是一些代码 class CInner public CInner const CInner another impl here private some member variables class COuter public COut
  • 大写 Unicode 的正则表达式与“Ó”不匹配?

    它似乎不将重音 识别为大写 usr bin env perl use strict use warnings use 5 14 0 use utf8 use feature unicode strings SIM N s p Upper u
  • VS2010命令提示符给出错误:无法确定 VS Common Tools 文件夹的位置

    我已经安装了VS2010 安装创建了 VS2010 命令提示符的快捷方式 但是当我打开命令提示符时出现错误 无法确定 VS Common Tools 文件夹的位置 我检查了环境变量 VS100COMNTOOLS 它有值 C Program
  • 我应该提交由 Eclipse 更改的文件吗?

    我以Eclipse项目的形式继承了一个Java项目 更改 Tomcat 配置 从 v6 到 v7 后 Subclipse 提示我提交以下文件 classpath org eclipse core prefs org eclipse comm
  • 为什么 Silverlight TextBox 使用 \r 作为换行符而不是 Environment.Newline (\r\n)?

    在 silverlight 中 如果 TextBox AcceptsReturn 则所有换行符均为 r 即使 Environment Newline 为 r n 为什么是这样 WPF 将 r n 作为文本框的换行符 我同意尔坦的回答 我遇到
  • 解码 Base64 图像

    我在 HTML 中嵌入了 Base64 图像 如何使用 C 或 VB net 对其进行解码 google com gt base64 图像解码 C gt http www eggheadcafe com community aspnet 2
  • 启用位置/GPS 设置而不使用 Play 服务 API

    大多数人可能已经知道 Google Play 服务中有一个新的位置设置对话框 API 对于那些不知道的人 这里是使用 Dialog API 的地图应用程序的屏幕截图 谷歌只在他们的播放服务中添加该 API 这有点不公平 另一方面 我认为如果
  • 仅静态链接某些库

    在与 GCC 链接时 如何将某些特定库静态链接到我的二进制文件 gcc static 尝试静态链接all链接库 但我还没有其中一些的静态版本 例如 libX11 gcc lsome dynamic lib code c some stati
  • CrossGeolocator 的 GetPositionAsync 不起作用

    我在用交叉地理定位器检索设备的当前纬度和经度 不过我在里面使用它出现时覆盖方法 但它不起作用 这异步获取位置方法挂起应用程序 protected override void OnAppearing base OnAppearing var
  • jQuery:如何更改标签名称?

    jQuery 如何更改标签名称 例如 tr 1 tr I need div 1 div 我可以 创建 DOM 元素 将tr内容复制到div 从 dom 中删除 tr 但我可以直接做吗 PS tr get 0 tagName div 结果是D
  • Liquibase Hibernate 插件不起作用

    如此处所述 https github com liquibase liquibase hibernate issues 74 我在使 liquibase hibernate 扩展正常工作时遇到问题 我想我已经设置好了一切 但似乎我一直遇到奇
  • Spring - mongodb - 聚合 - 需要“光标”选项

    执行以下聚合管道 public void getMostLikedItems UnwindOperation unwind Aggregation unwind favoriteItems GroupOperation group Aggr
  • 仅生成 8 个字符的 UUID

    UUID 库生成 32 个字符的 UUID 我想生成仅 8 个字符的 UUID 可以吗 这是不可能的 因为 UUID 每个定义都是 16 字节的数字 当然 您可以生成 8 个字符长的唯一字符串 请参阅其他答案 另外 生成较长的 UUID 并
  • 将文件从操作系统拖放到 Java 应用程序 (Swing)

    首先我要说的是我一直在阅读拖放教程以及类似的问题 但不幸的是我对这件事变得更加困惑 我想要实现的目标相对简单 所以我很惊讶它已经给我带来了这么多麻烦 我正在编写一个小型实用程序应用程序 它将把一堆结果文件 自定义定义的 xml 类型 合并到