Hãy để tôi bắt đầu bằng cách nói rằng tôi đã đọc số drag'n drop tutorial và các câu hỏi tương tự được hỏi trên SO, nhưng tiếc là tôi chỉ trở nên bối rối hơn về vấn đề này. Những gì tôi muốn đạt được là tương đối đơn giản vì vậy tôi ngạc nhiên rằng nó đã cho tôi trong rất nhiều rắc rối rồi. Tôi đang viết một ứng dụng tiện ích nhỏ sẽ hợp nhất một loạt các tệp kết quả (loại xml được định nghĩa tùy chỉnh) thành một tệp văn bản được phân tách bằng tab lớn. Hầu hết các chức năng đã được mã hóa, tuy nhiên tôi muốn tạo một GUI phong nha cho nó.Kéo thả các tập tin từ ứng dụng OS sang Java (Swing)
Điều tôi muốn là có thể kéo thả tệp vào thành phần (ví dụ JTextArea
) theo cách đẹp và duyên dáng (đọc: không phải đường dẫn đầy đủ, thay vào đó là biểu tượng và tên nhỏ). Tôi muốn có thể cung cấp một số JFileChooser
để duyệt các tệp. Sau đó tôi sẽ phân tích cú pháp các tập tin tuần tự để tạo ra ma trận mà tôi muốn.
Điều tôi đã học được từ trước đến nay là khung công tác đã có sẵn, tuy nhiên, bất kỳ chức năng bổ sung nào cũng cần phải được tạo tùy chỉnh. Tôi đã tạo ra một thử nghiệm GUI trong Netbeans và cố gắng kéo một loạt các tập tin vào một JTextArea
, nhưng chúng xuất hiện như là đường dẫn tập tin, và thừa nhận nó trông rất xấu xí.
Tôi thực sự đánh giá cao mọi mẹo và hướng dẫn về cách giải quyết (hoặc làm rõ) vấn đề này một cách gọn gàng. Lưu ý rằng tôi có ý định sử dụng phần mềm trên nhiều hệ điều hành khác nhau (Mac, Win và Linux).
EDIT: mã tôi đã cho đến nay được dựa trên một trong những ví dụ từ Sun hướng dẫn và thực hiện như sau
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();
}
});
}
Vâng vâng, có lẽ tôi đã không làm cho các câu hỏi rõ ràng; "Làm cách nào để thêm tính năng kéo thả vào GUI, nơi các tệp được kéo được thể hiện độc đáo với tên tệp và biểu tượng nhỏ (biểu tượng hệ thống sẽ làm, tôi không có ý định thiết kế biểu tượng tùy chỉnh)?" Tôi đã đi xa như các tập tin DnD'd được đại diện với đường dẫn của họ (mà tôi tin là khá nhiều hành vi mặc định). – posdef
Cảm ơn bạn đã nhắc nhở, mã được thêm ngay bây giờ. – posdef
tại sao textArea là dropZone? Tôi sẽ sử dụng một danh sách với một renderer tùy chỉnh (hiển thị biểu tượng/displayName được cung cấp bởi FileSystemView) – kleopatra