Drag ' N ' drop von Dateien aus dem Betriebssystem Java-Anwendung (Swing)
Lassen Sie mich zunächst sagen, dass ich seit dem Lesen der drag ' N ' drop-tutorial und ähnliche Fragen auf, SO, aber leider habe ich nur noch mehr verwirrt über diese Frage. Was ich erreichen will ist relativ einfach, also ich bin überrascht, dass es mich so viel Mühe schon. Ich Schreibe eine kleine Anwendung, die Konsolidierung einer Reihe von Ergebnis-Dateien (benutzerdefinierte xml-Typ) in einen großen Tabulator-getrennte text-Datei. Der Großteil der Funktionen ist bereits codiert, aber ich wollte eine anständige GUI dafür.
Was ich will, ist in der Lage sein, um drag ' N ' drop von Dateien in einer Komponente (z.B. JTextArea
) in einem netten und freundlichen Art und Weise (Lesen: nicht vollständige Pfade, aber stattdessen ein kleines Symbol und name). Ich möchte in der Lage sein zu liefern eine JFileChooser
durchsuchen für Dateien, als auch. Ich werde dann analysieren die Dateien der Reihe nach zu erzeugen, die matrix, die ich möchte.
Was ich bisher gelernt habe ist, dass das Gerüst bereits gibt jedoch zusätzliche Funktionen benötigt werden, um benutzerdefinierte gebaut. Habe ich eine test-GUI in Netbeans und versucht, ziehen Sie einen Haufen von Dateien auf eine JTextArea
, aber Sie scheinen wie Dateipfade, und zugegeben, es sieht sehr hässlich aus.
Ich würde wirklich zu schätzen jede Tipps und Anleitung, wie das zu lösen (bzw. zu klären) dieses problem auf elegante Weise. Beachten Sie, dass ich verwenden möchten, die software auf mehreren verschiedenen OS (Mac,Win und Linux).
EDIT: den code habe ich so weit ist, basiert auf einem der Beispiele von Sun-tutorials und ist wie folgt
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();
}
});
}
- Na ja, vielleicht habe ich auch nicht mehr die Frage klar; "Wie gehe ich über das hinzufügen von drag' N ' drop-Funktion, um meine GUI, wo die gezogenen Dateien vertreten sind schön mit Ihren Dateinamen und ein kleines icon (system-icons tun würde, ich habe keine Absichten zu entwerfen, die benutzerdefinierte Symbole)?" Ich bin gekommen, so weit zu DnD würde-Dateien vertreten sind, mit deren Pfade (die ich glaube, ist so ziemlich das Standard-Verhalten).
- Danke für die Erinnerung, code Hinzugefügt, jetzt.
- warum eine textArea als dropZone? Ich würde eine Liste mit custom renderer (Darstellung der Symbol/displayName zur Verfügung gestellt von der FileSystemView)
- nun, ich dachte, es wäre der einfachste Fall. Nicht sicher, was Sie bedeuten, durch eine Liste mit einem benutzerdefinierten renderer, ich würde schätzen, wenn Sie geben konnte, ein kurzes Beispiel.
Du musst angemeldet sein, um einen Kommentar abzugeben.
hier ein kurzer snippet zu importieren, die tatsächlichen Dateien in einer JList (im Gegensatz zu importieren, seine String-Darstellung in eine text-Komponente) und eine custom-renderer zu präsentieren es schön. Es ist angepasst an die BasicDnD (im tutorial):
Konnte nicht widerstehen, um zu zeigen, SwingX-renderer config 🙂 In core java, Sie würden es manuell machen, so etwas wie
MyRenderer
soll an der StellefileDropper.setCellRenderer(new DefaultListRenderer(StringValues.FILE_NAME, IconValues.FILE_ICON));
zu Sehen, wieStringValues.FILE_NAME
, undIconValues.FILE_ICON
sind nicht definiert/nicht gelöst? Oder habe ich etwas falsch verstanden?Dies ist effektiv kleopatra Antwort1 (mit ein paar geringfügige änderungen, die nicht unbedingt zum besseren), ..mit einem screenshot!!!
TransferHandler
war sehr kaputt, ich benutzte Ihre. Obwohl ich meine version der Liste cell-renderer, die scheint nicht zu erfassen, die Feinheiten von dem, was Sie vorschlug. Ich war auch immer der Kompilierung Fehler auf die Erwähnung vonList
(angesichts der compiler war der Annahme, ich meinte eine AWT-list. Ich nur merkte, was Los war, nachdem ich änderte einige derList<File>
type-Anweisungen werden nicht-Generika - ich denke, die meisten von Ihnen sind mittlerweile wieder geändert.List
s, wenn ich versuchte, aus Ihrem Beispiel). Ich bin nicht sicher, ob ich voll verstehen, @kleopatraListCellRenderer
Vorschlag. Ich meine, ich verfolge deine version, aber ich glaube nicht, dass ich vollständig zu erfassen die finesse in Ihrer version.FileSystemView.getFileSystemView().getDisplayName(value)
was ich vermute, könnte zu einem besseren Namen (aber noch nicht getestet). BTW - wenn Sie Probleme mit der Entscheidung, die zu geben, die 'tick' zu, ich schlage vor, Ihr beantworten, da es richtig war und die erste.Hier ist der code ohne Konsole und extra-Taste