두 개의 다른 방법으로 끌어서 놓기 개체에서 놓기를 허용 할 두 개의 자식 창이 있습니다.자바/스윙 : 두 자식 창에 드래그 앤 드롭 문제가 발생했습니다.
하나는 파일 목록을 허용하려는 JPanel입니다. 그것은 잘 작동합니다.
다른 하나는 문자열 목록을 허용하려는 JTable입니다. JPanel을 드롭 대상으로 사용하지 않으면 잘 작동합니다.
둘 다 사용하려고하면 JPanel 놓기 대상이 JTable 놓기 대상을 가리는 것 같습니다. JTable이 JPanel의 자식 창이 아니며 두 구성 요소가 겹치지 않는 영역에도 있습니다.
또한 JFrame 둘 다 포함 된 드롭 아이콘이 표시됩니다. 이유는 확실하지 않습니다.
어떤 조언이 필요합니까? 이것은 디버그하기가 어렵습니다.
샘플 응용 프로그램은 다음과 유사합니다. 여기서는 JTable에서 드랍을 받아 들일 수 없습니다. :/
내가 알고 싶은 또 다른 질문이 있습니다. "소스 1 끌어 오기"에서 "드롭 대상 1"로 드래그하지만 마우스를 놓지 않으면 끌기 소스 1 레이블이 변경 될 때마다 내 커서가 깜박입니다 (이 테스트 응용 프로그램에서 초당 한 번). 왜 이렇게합니까? 깜박임을 막을 수있는 방법이 있습니까?
package com.example.test.gui;
import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
public class DragAndDropQuestion {
public enum Color {
RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, WHITE, BLACK;
@Override public String toString()
{ return this.name().toLowerCase(); }
static public Color randomColor(Random r)
{
Color[] colors = Color.values();
return colors[r.nextInt(colors.length)];
}
}
public static class SampleBean
{
final private Color color;
final private char letter;
final static public DataFlavor dataFlavor =
new DataFlavor(SampleBean.class, "SampleBean");
public Color getColor() { return this.color; }
public char getLetter() { return this.letter; }
private SampleBean(Color color, char letter)
{
this.color = color;
this.letter = letter;
}
static public SampleBean randomBean(Random r)
{
String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return new SampleBean(Color.randomColor(r),
letters.charAt(r.nextInt(letters.length())));
}
@Override public String toString() {
return this.color.toString()+" "+this.letter;
}
}
public static class BorderPanel extends JPanel {
public BorderPanel(String title)
{
setBorder(BorderFactory.createTitledBorder(title));
}
}
public static class BeanTransferable implements Transferable
{
final private SampleBean value;
static final private List<DataFlavor> flavors = Arrays.asList(
DataFlavor.stringFlavor,
SampleBean.dataFlavor
);
public BeanTransferable(SampleBean x) { this.value=x; }
@Override public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
if (flavors.get(0).equals(flavor))
{
return this.value.toString();
}
else if (flavors.get(1).equals(flavor))
{
return this.value;
}
else
{
throw new UnsupportedFlavorException(flavor);
}
}
@Override public DataFlavor[] getTransferDataFlavors() {
return flavors.toArray(new DataFlavor[0]);
}
@Override public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavors.contains(flavor);
}
}
public abstract static class SimpleDropTarget
implements DropTargetListener
{
final private String debugString;
public SimpleDropTarget(String debugString) {
this.debugString=debugString;
}
@Override public void dragEnter(DropTargetDragEvent event)
{ System.out.println(this.debugString+":dragEnter"); }
@Override public void dragExit(DropTargetEvent event) {}
{ System.out.println(this.debugString+":dragExit"); }
@Override public void dragOver(DropTargetDragEvent event) {}
@Override public void dropActionChanged(DropTargetDragEvent event) {}
public void install(JComponent component) {
new DropTarget(component, this);
}
}
public abstract static class SimpleDragSource
implements DragSourceListener, DragGestureListener
{
final private String debugString;
final private DragSource ds = new DragSource();
public SimpleDragSource(String debugString) {
this.debugString=debugString;
}
@Override public void dragDropEnd(DragSourceDropEvent event) {}
@Override public void dragEnter(DragSourceDragEvent event)
{ System.out.println(this.debugString+":dragEnter"); }
@Override public void dragExit(DragSourceEvent event)
{ System.out.println(this.debugString+":dragExit"); }
@Override public void dragOver(DragSourceDragEvent event) {}
@Override public void dropActionChanged(DragSourceDragEvent event) {}
public void install(JComponent component) {
DragGestureRecognizer dgr =
this.ds.createDefaultDragGestureRecognizer(component,
DnDConstants.ACTION_COPY, this);
}
abstract public Transferable prepareTransferable();
@Override public void dragGestureRecognized(DragGestureEvent dge)
{
this.ds.startDrag(dge,
DragSource.DefaultCopyDrop, prepareTransferable(), this);
}
}
public static class BeanListModel implements TableModel {
final private List<SampleBean> list = new ArrayList<SampleBean>();
enum ColumnType {
COLOR(Color.class, "color") {
@Override public Color extractValue(SampleBean sampleBean) {
return sampleBean.getColor();
}
},
LETTER(String.class, "letter") {
@Override public String extractValue(SampleBean sampleBean) {
return Character.toString(sampleBean.getLetter());
}
},
;
final private Class<?> cl;
final private String name;
public Class<?> getColumnClass() { return this.cl; }
public String getColumnName() { return this.name; }
ColumnType(Class<?> cl, String name)
{ this.cl=cl; this.name=name; }
abstract public Object extractValue(SampleBean sampleBean);
}
final static private ColumnType[] columns
= new ColumnType[]{ColumnType.COLOR, ColumnType.LETTER};
@Override
public void addTableModelListener(TableModelListener arg0) {}
@Override
public void removeTableModelListener(TableModelListener arg0) {}
@Override public Class<?> getColumnClass(int column) {
return columns[column].getColumnClass();
}
@Override public int getColumnCount() {
return columns.length;
}
@Override public String getColumnName(int column) {
return columns[column].getColumnName();
}
@Override public int getRowCount() { return list.size(); }
@Override public Object getValueAt(int row, int column) {
return columns[column].extractValue(list.get(row));
}
@Override public boolean isCellEditable(int row, int column) {
return false;
}
@Override public void setValueAt(Object obj, int row, int column) {
throw new UnsupportedOperationException();
}
public void addBean(SampleBean bean)
{
this.list.add(bean);
}
}
public static class BeanTablePanel extends BorderPanel {
final private JTable table;
final private BeanListModel tableModel;
public BeanTablePanel(String title)
{
super(title);
this.table = new JTable();
this.tableModel = new BeanListModel();
this.table.setModel(this.tableModel);
add(new JScrollPane(this.table));
SimpleDropTarget dt = new SimpleDropTarget("BeanTable"){
@Override public void drop(DropTargetDropEvent dtde) {
Transferable tr = dtde.getTransferable();
if (tr.isDataFlavorSupported(SampleBean.dataFlavor))
{
try {
SampleBean b = (SampleBean)
tr.getTransferData(SampleBean.dataFlavor);
addBean(b);
}
catch (UnsupportedFlavorException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
};
dt.install(this.table);
// !!! This doesn't seem to work...
}
void addBean(SampleBean b) {
this.tableModel.addBean(b);
}
}
public static class BeanLabelPanel extends BorderPanel {
final private JLabel label;
public BeanLabelPanel(String title)
{
super(title);
this.label = new JLabel("drop item here");
add(this.label);
SimpleDropTarget dt = new SimpleDropTarget("BeanLabel"){
@Override public void drop(DropTargetDropEvent dtde) {
Transferable tr = dtde.getTransferable();
if (tr.isDataFlavorSupported(DataFlavor.stringFlavor))
{
try {
String s = (String)
tr.getTransferData(DataFlavor.stringFlavor);
setLabel(s);
}
catch (UnsupportedFlavorException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
};
dt.install(this.label);
}
void setLabel(String s) { this.label.setText(s); }
}
public static class BeanSourcePanel extends BorderPanel {
final private JLabel label;
final private Random randomizer;
private SampleBean x;
public BeanSourcePanel(
String title, ScheduledExecutorService scheduler)
{
super(title);
this.label = new JLabel(" ");
this.randomizer = new Random();
add(this.label);
scheduler.scheduleAtFixedRate(new Runnable()
{ public void run() { changeBean(); } },
0, 1000, TimeUnit.MILLISECONDS);
(new SimpleDragSource("RandomBean"){
@Override public Transferable prepareTransferable() {
return new BeanTransferable(getBean());
}
}).install(this.label);
}
public SampleBean getBean() { return this.x; }
void changeBean()
{
this.x = SampleBean.randomBean(this.randomizer);
this.label.setText(this.x.toString());
}
}
public static class DNDQFrame extends JFrame
{
public DNDQFrame(String title, ScheduledExecutorService scheduler)
{
setTitle(title);
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS)
);
add(new JLabel("Drag and Drop Question"));
add(new BeanSourcePanel("drag source 1", scheduler));
add(new BeanLabelPanel("drop target 1"));
add(new BeanTablePanel("drop target 2"));
}
@Override public Component add(Component component)
{
if (component instanceof JComponent)
((JComponent) component).setAlignmentX(0.0f);
return super.add(component);
}
}
static public void main(String[] args)
{
ScheduledExecutorService scheduler =
new ScheduledThreadPoolExecutor(1);
DNDQFrame frame = new DNDQFrame("DragAndDropQuestion", scheduler);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
간단한 코드를 게시 할 수 있습니까? DnD 코드의 발췌 부분 일지라도 도움이 될 것입니다. 많은 코드가 있다면 pastebin을 사용하십시오. UI 코드를 사용하여 빌드하고 실행할 수 있다면 더 빨리 디버깅 할 수 있습니다. – Kylar
지금 작업 중입니다. (btw은 무엇입니까?) –
더 많은 코드 발췌 부분을 붙여 넣을 수있는 사이트이며 http://mysticpaste.com/new 또는 http : //와 같은 URL을 제공합니다. pastebin.com/. 이렇게하면 인 페이지 코드 2 페이지가 없어도 질문을 읽을 수 있습니다. – Kylar