removeAll()
, add()
, revalidate()
을 처리하는 동안 드롭 DropTargetListener.drop()
을 처리하면 드롭이 성공하고 변경 사항이 적용되지만 두 번째 드래그를 절대 시작할 수 없음을 발견했습니다. 이후의 드래그 시도는 java.awt.dnd.InvalidDnDOperationException: Drag and drop in progress
이됩니다.스윙 드롭 콜백 중에 컴포넌트 계층 변경이 금지되어 있습니까?
계층 구조를 변경하면 끌기가 지워지지 않으며 스윙은 진행중인 드래그가 완료 될 때까지 계속 진행중인 것으로 생각합니다. 계층 구조 변경
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.dnd.*;
import javax.activation.*;
import java.awt.datatransfer.*;
import java.util.TooManyListenersException;
class MyWidget extends JComponent {
MyWidget() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
updateState();
}
void updateState() {
Runnable runnable = new Runnable() {
@Override
public void run() {
// System.out.println("Hello World on " + Thread.currentThread());
removeAll();
add(newButton("aaa"));
add(newButton("bbb"));
revalidate();
}
};
if (SwingUtilities.isEventDispatchThread()) {
runnable.run();
} else {
SwingUtilities.invokeLater(runnable);
}
}
JButton newButton(String text) {
JButton theButton = new JButton(text);
DragSource ds = new DragSource();
DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(theButton, DnDConstants.ACTION_COPY, new DragGestureListener() {
@Override
public void dragGestureRecognized(DragGestureEvent dge) {
Transferable transferable = new DataHandler("my text", "text/plain");
dge.startDrag(DragSource.DefaultCopyDrop, transferable);
}
});
DropTarget dt = new DropTarget();
dt.setComponent(theButton);
try {
dt.addDropTargetListener(new DropTargetAdapter() {
@Override
public void drop(DropTargetDropEvent dtde) {
System.out.println("drop accepted");
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
dtde.dropComplete(true);
updateState();
}
});
} catch (TooManyListenersException e) {}
return theButton;
}
}
public class App
{
static void createGUI() {
JFrame frame = new JFrame();
frame.setTitle("my app");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyWidget(), BorderLayout.CENTER);
frame.setSize(500,500);
// frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Hello World on " + Thread.currentThread());
createGUI();
}
});
}
}