gpt4 book ai didi

Java,拖放改变面板的顺序

转载 作者:行者123 更新时间:2023-11-30 07:04:52 24 4
gpt4 key购买 nike

好的,我的设置如下。我有一个使用 javax.swing 作为 ui 的 java 1.7 项目。这是我在跟随教程之外的第一个项目,它是那些熟悉桌面的人的主动跟踪器。我有一个扩展 JPanel(并实现 Comparable<>)的类,因此我可以动态添加它并为每个类添加故事不同的数据。

面板被添加到布局中,其 y 位置取决于已有的面板数量。它们也被添加到 ArrayList 中以按顺序对它们进行排序。该列表可以按类的属性之一排序。

我现在遇到的是,我希望能够手动拖放它们以更改布局和 ArrayList 中的顺序。需要注意的是,我不能只删除并重新添加一个,因为我会丢失类中保存的值。

为此,我制作了一个需要执行以下操作的 JButton:

  • 只要鼠标在按钮上按下,就需要用鼠标拖动它所属的面板。
  • 当鼠标被释放时,它需要检查其位置,并在必要时转到该位置。

So for example

我尝试了一些拖放教程,但我似乎找不到可以调整到我想要的内容的教程。

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)

最佳答案

这里是拖放改变面板顺序的例子(不支持排序)

enter image description here

  1. DragMouseAdapter#mouseDragged(...):搜索拖动面板,移除父面板并打开光标窗口。
  2. 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);
}
}
}

关于Java,拖放改变面板的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27245283/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com