Permítanme comenzar diciendo que he estado leyendo el drag'n drop tutorial y preguntas similares en SO, pero desafortunadamente solo me he confundido más acerca de este asunto. Lo que quiero lograr es relativamente simple, así que estoy sorprendido de que ya me haya metido en tantos problemas. Estoy escribiendo una pequeña aplicación de utilidad que consolidará un grupo de archivos de resultados (tipo xml definido a medida) en un archivo de texto separado por pestañas. La mayoría de la funcionalidad ya está codificada, sin embargo, quería hacer una GUI decente para ello.Arrastrar archivos desde el sistema operativo a la aplicación Java (Swing)
Lo que quiero es poder arrastrar y soltar archivos en un componente (por ejemplo JTextArea
) de una manera agradable y elegante (léase: rutas no completas, sino un pequeño icono y nombre). Me gustaría poder proporcionar un JFileChooser
para buscar también archivos. Luego analizaré los archivos secuencialmente para producir la matriz que quiero.
Lo que he aprendido hasta ahora es que el framework ya está allí, sin embargo, cualquier funcionalidad adicional debe ser personalizada. He creado una GUI de prueba en Netbeans e intenté arrastrar un grupo de archivos a un JTextArea
, pero aparecen como rutas de archivos, y ciertamente se ve muy feo.
Realmente agradecería cualquier consejo y orientación sobre cómo resolver (o aclarar) este problema de una manera ordenada. Tenga en cuenta que tengo la intención de utilizar el software en múltiples SO diferentes (Mac, Win y Linux).
EDIT: el código que tengo hasta ahora se basa en uno de los ejemplos de tutoriales de Sun y es el siguiente
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();
}
});
}
Bueno, sí, tal vez no hice la pregunta clara; "¿Cómo hago para agregar una función de arrastrar y soltar a mi GUI, donde los archivos arrastrados se representan bien con sus nombres de archivo y un pequeño icono (los iconos del sistema harían, no tengo intención de diseñar íconos personalizados)?" He llegado a decir que los archivos DnD'd están representados con sus rutas (que creo que es más o menos el comportamiento predeterminado). – posdef
Gracias por recordar, código agregado ahora. – posdef
¿por qué un area de texto como dropZone? Yo usaría una lista con un renderizador personalizado (mostrando el icono/displayName provisto por FileSystemView) – kleopatra