好的,我所设置的内容如下。我有一个java 1.7项目,它为ui使用javax.swing。这是我在以下教程之外的第一个项目,它是那些熟悉桌面的人的主动跟踪器。我有一个扩展JPanel的类(并实现了Comparable<>),因此我可以动态添加它并为每个类记录不同的数据。
面板将添加到布局中,其y位置取决于已存在的面板数量。它们也被添加到ArrayList中以按顺序对它们进行排序。 该列表可以按类的一个属性进行排序。
我现在遇到的是我想手动拖放它们来改变布局和ArrayList中的顺序。附加说明我不能删除并重新添加一个,因为我会丢失类中保存的值。
为此,我制作了一个需要执行以下操作的JButton:
我尝试了一些拖放教程,但我似乎无法找到一个可以调整到我想要的内容。
Edit1:这就是我的尝试。
MouseListener listener = new DragMouseAdapter();
dragButton.addMouseListener(listener);
dragButton.setTransferHandler(new TransferHandler("text"));
然后
class DragMouseAdapter extends MouseAdapter {
public void mousePressed(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.COPY);
// TODO make it a swap location drag and drop
}
}
这是来自一个教程,它成功地改变了文本,但这完全不是我想要的,我不知道如何改变它以做我想做的事。
Edit2:This tutorial描述了我想要做的事情,除了它不起作用。它给出了以下错误:
Step 1 of 7: Mouse pressed. Going to export our RandomDragAndDropPanel so that it is draggable.
Step 2 of 7: Returning the acceptable TransferHandler action. Our RandomDragAndDropPanel accepts Copy only.
Step 3 of 7: Casting the RandomDragAndDropPanel as Transferable. The Transferable RandomDragAndDropPanel will be queried for acceptable DataFlavors as it enters drop targets, as well as eventually present the target with the Object it transfers.
Step 4 of 7: Querying for acceptable DataFlavors to determine what is available. Our example only supports our custom RandomDragAndDropPanel DataFlavor.
Problem lazy loading: RandomDragAndDropPanel
java.lang.ClassNotFoundException: RandomDragAndDropPanel
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at java.awt.datatransfer.DataFlavor.tryToLoadClass(Unknown Source)
at java.awt.datatransfer.DataFlavor.initialize(Unknown Source)
at java.awt.datatransfer.DataFlavor.<init>(Unknown Source)
at DnD.DragAndDropPanelsDemo.getDragAndDropPanelDataFlavor(DragAndDropPanelsDemo.java:197)
at DnD.RandomDragAndDropPanel.getTransferDataFlavors(DragAndDropPanelsDemo.java:392)
at sun.awt.datatransfer.DataTransferer.getFormatsForTransferable(Unknown Source)
at sun.awt.dnd.SunDragSourceContextPeer.startDrag(Unknown Source)
at java.awt.dnd.DragSource.startDrag(Unknown Source)
at java.awt.dnd.DragSource.startDrag(Unknown Source)
at java.awt.dnd.DragGestureEvent.startDrag(Unknown Source)
at javax.swing.TransferHandler$DragHandler.dragGestureRecognized(Unknown Source)
at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(Unknown Source)
at javax.swing.TransferHandler$SwingDragGestureRecognizer.gestured(Unknown Source)
at javax.swing.TransferHandler.exportAsDrag(Unknown Source)
at DnD.DraggableMouseListener.mousePressed(DragAndDropPanelsDemo.java:456)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
答案 0 :(得分:4)
以下是拖放更改面板顺序的示例(不支持排序)。
DragMouseAdapter#mouseDragged(...)
:搜索拖动面板,删除表单父面板并打开光标窗口。DragMouseAdapter#mouseReleased(...)
:搜索放置位置,插入拖动面板,关闭光标窗口。import java.awt.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
public class RearrangeOrderOfPanelsTest2 {
public JComponent makeUI() {
Box box = Box.createVerticalBox();
DragMouseAdapter dh = new DragMouseAdapter();
box.addMouseListener(dh);
box.addMouseMotionListener(dh);
int idx = 0;
for (JComponent c : Arrays.asList(
new JLabel("<html>111<br>11<br>11"),
new JButton("2"), new JCheckBox("3"), new JTextField(14))) {
box.add(createToolbarButton(idx++, c));
}
JPanel p = new JPanel(new BorderLayout());
p.add(box, BorderLayout.NORTH);
return p;
}
private static JComponent createToolbarButton(int i, JComponent c) {
JLabel l = new JLabel(String.format(" %04d ", i));
l.setOpaque(true);
l.setBackground(Color.RED);
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5),
BorderFactory.createLineBorder(Color.BLUE, 2)));
p.add(l, BorderLayout.WEST);
p.add(c);
p.setOpaque(false);
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new RearrangeOrderOfPanelsTest2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class DragMouseAdapter extends MouseAdapter {
private static final int xoffset = 16;
private static final Rectangle R1 = new Rectangle();
private static final Rectangle R2 = new Rectangle();
private static Rectangle prevRect;
private final JWindow window = new JWindow();
private Component draggingComonent;
private int index = -1;
private Component gap;
private Point startPt;
private Point dragOffset;
private final int gestureMotionThreshold = DragSource.getDragThreshold();
public DragMouseAdapter() {
super();
window.setBackground(new Color(0, true));
}
@Override public void mousePressed(MouseEvent e) {
JComponent parent = (JComponent) e.getComponent();
if (parent.getComponentCount() <= 1) {
startPt = null;
return;
}
startPt = e.getPoint();
}
private void startDragging(JComponent parent, Point pt) {
//get a dragging panel
Component c = parent.getComponentAt(pt);
index = parent.getComponentZOrder(c);
if (Objects.equals(c, parent) || index < 0) {
return;
}
draggingComonent = c;
Dimension d = draggingComonent.getSize();
Point dp = draggingComonent.getLocation();
dragOffset = new Point(pt.x - dp.x, pt.y - dp.y);
//make a dummy filler
gap = Box.createRigidArea(d);
swapComponentLocation(parent, c, gap, index);
//make a cursor window
window.add(draggingComonent);
window.pack();
updateWindowLocation(pt, parent);
window.setVisible(true);
}
private void updateWindowLocation(Point pt, JComponent parent) {
Point p = new Point(pt.x - dragOffset.x, pt.y - dragOffset.y);
SwingUtilities.convertPointToScreen(p, parent);
window.setLocation(p);
}
private static int getTargetIndex(Rectangle r, Point pt, int i) {
int ht2 = (int)(.5 + r.height * .5);
R1.setBounds(r.x, r.y, r.width, ht2);
R2.setBounds(r.x, r.y + ht2, r.width, ht2);
if (R1.contains(pt)) {
prevRect = R1;
return i - 1 > 0 ? i : 0;
} else if (R2.contains(pt)) {
prevRect = R2;
return i;
}
return -1;
}
private static void swapComponentLocation(
Container parent, Component remove, Component add, int idx) {
parent.remove(remove);
parent.add(add, idx);
parent.revalidate();
parent.repaint();
}
@Override public void mouseDragged(MouseEvent e) {
Point pt = e.getPoint();
JComponent parent = (JComponent) e.getComponent();
//MotionThreshold
double a = Math.pow(pt.x - startPt.x, 2);
double b = Math.pow(pt.y - startPt.y, 2);
if (draggingComonent == null &&
Math.sqrt(a + b) > gestureMotionThreshold) {
startDragging(parent, pt);
return;
}
if (!window.isVisible() || draggingComonent == null) {
return;
}
//update the cursor window location
updateWindowLocation(pt, parent);
if (prevRect != null && prevRect.contains(pt)) {
return;
}
//change the dummy filler location
for (int i = 0; i < parent.getComponentCount(); i++) {
Component c = parent.getComponent(i);
Rectangle r = c.getBounds();
if (Objects.equals(c, gap) && r.contains(pt)) {
return;
}
int tgt = getTargetIndex(r, pt, i);
if (tgt >= 0) {
swapComponentLocation(parent, gap, gap, tgt);
return;
}
}
parent.remove(gap);
parent.revalidate();
}
@Override public void mouseReleased(MouseEvent e) {
startPt = null;
if (!window.isVisible() || draggingComonent == null) {
return;
}
Point pt = e.getPoint();
JComponent parent = (JComponent) e.getComponent();
//close the cursor window
Component cmp = draggingComonent;
draggingComonent = null;
prevRect = null;
startPt = null;
dragOffset = null;
window.setVisible(false);
//swap the dragging panel and the dummy filler
for (int i = 0; i < parent.getComponentCount(); i++) {
Component c = parent.getComponent(i);
if (Objects.equals(c, gap)) {
swapComponentLocation(parent, gap, cmp, i);
return;
}
int tgt = getTargetIndex(c.getBounds(), pt, i);
if (tgt >= 0) {
swapComponentLocation(parent, gap, cmp, tgt);
return;
}
}
if (parent.getParent().getBounds().contains(pt)) {
swapComponentLocation(parent, gap, cmp, parent.getComponentCount());
} else {
swapComponentLocation(parent, gap, cmp, index);
}
}
}