Я пытаюсь закодировать JPanel как пространство для рисования фигур. для этого я установил для макета значение null
mainPanel.setLayout(null);
затем я вставил несколько кнопок в главную панель, чтобы попытаться реализовать функцию перетаскивания.
btn.setTransferHandler(new TransferHandler("text"));
btn.addMouseListener(new MouseAdapter(){
public void mouseDragged(MouseEvent e){
Dimension size=btn.getPreferredSize();
JButton button = (JButton)e.getSource();
TransferHandler handle = button.getTransferHandler();
handle.exportAsDrag(button, e, TransferHandler.COPY);
}
});
у меня вопрос, могу ли я использоватьTransferHandler в нулевом макете? как только я начинаю перетаскивать объекты, курсор мыши принимает такую форму: запрещенное действие




TransferHandler предназначен для передачи данных, а не для перемещения кнопки по панели. Таким образом, макет не имеет никакого значения.
В вашем случае вы устанавливаете TransferHandler для «текста», что означает, что вы пытаетесь передать «текст» кнопки в какой-то другой компонент.
btn.addMouseListener(new MouseAdapter(){
public void mouseDragged(MouseEvent e){
Dimension size=btn.getPreferredSize();
JButton button = (JButton)e.getSource();
TransferHandler handle = button.getTransferHandler();
handle.exportAsDrag(button, e, TransferHandler.COPY);
}
});
В MouseListener нет события mouseDragged. Событие mouseDragged генерируется в MouseMotionListener.
Когда я добавляю MouseListener к компоненту для поддержки DnD, я всегда добавляю логику к событию mousePressed.
Прочтите раздел руководства по Swing на Перетаскивание и передача данных для получения дополнительной информации и примеров, которые помогут вам начать работу.
@MicheleFattoruso: Тем не менее, ваш оригинальный вопрос был посвящен использованию обработчика передачи, и ответ, который вы даете, является ответом, но на другой вопрос / проблему. Я по-прежнему считаю, что вы также должны принять ответ Камикера, поскольку его ответ фактически касался ваших первоначальных опасений.
@HovercraftFullOfEels Я пробовал, но не тестировал полностью.
Прочитав предыдущие ответы и прочитав документацию, опубликованную @camickr, я заметил, что transferHandler - это не совсем то, что я искал. Мне нужно было перемещать компонент по одной панели JPanel, а не перетаскивать его копию на другую панель или компонент. в итоге я просто использовал функцию setLocation компонента с комбинацией MouseEvents и mouseMotionListeners.
protected class DragProcessor extends MouseAdapter implements MouseListener, MouseMotionListener {
Point pressPoint;
Point releasePoint;
@Override
public void mouseDragged(MouseEvent e) {
Point dragPoint = e.getPoint();
int xDiff = pressPoint.x - dragPoint.x;
int yDiff = pressPoint.y - dragPoint.y;
Rectangle b = button.getBounds();
Point p = b.getLocation();
SwingUtilities.convertPointToScreen(p, button.getParent());
p.x -= xDiff;
p.y -= yDiff;
SwingUtilities.convertPointFromScreen(p, button.getParent());
button.setLocation(p);
repaint();
}
@Override
public void mousePressed(MouseEvent e){
pressPoint = e.getPoint();
button = (JButton)e.getSource();
}
@Override
public void mouseReleased(MouseEvent e){
releasePoint = e.getPoint();
if (e.getButton() == MouseEvent.BUTTON3) {
// do whatever it is when the right button is pressed
} else {
int xDiff = pressPoint.x - releasePoint.x;
int yDiff = pressPoint.y - releasePoint.y;
Rectangle b = button.getBounds();
Point p = b.getLocation();
SwingUtilities.convertPointToScreen(p, panel.getParent());
p.x -= xDiff;
p.y -= yDiff;
SwingUtilities.convertPointFromScreen(p, panel.getParent());
if (p.x <= 0) {
p.x = 1;
}
if (p.x > panel.getParent().getWidth() - b.width) {
p.x = panel.getParent().getWidth() - b.width;
}
if (p.y <= 0) {
p.y = 1;
}
if (p.y > panel.getParent().getHeight() - b.height) {
p.y = panel.getParent().getHeight() - b.height;
}
button.setLocation(p);
getParent().repaint();
}
}
}
DragProcessor dragProcessor = new DragProcessor();
myButton.getMainButton().addMouseMotionListener(dragProcessor);
myButton.getMainButton().addMouseListener(dragProcessor);
What I needed was to move a component around a single JPanel, - это то, что я думал, что вы хотели, но ваш вопрос не был ясен, поэтому я объяснил, для чего использовался dnd. Я ожидал, что вы проясните свой вопрос, как только что. В этом случае я бы указал вам на Перемещение окон, который предоставляет базовый код многократного использования для перетаскивания компонента по панели, а также более продвинутый класс для дополнительных функций. Вам не нужно ссылаться на какие-либо внешние переменные, как это делает ваш текущий код.
Спасибо, я прочту документацию и свяжусь с вами, если у меня возникнут проблемы.
Спасибо за ответ, я прочитал документацию и понял, что это не то, что я искал. В качестве ответа я добавил способ решения своей проблемы. Так, на всякий случай