【问题标题】:createTransferable for JLabel or JPanel does not fireJLabel 或 JPanel 的 createTransferable 不会触发
【发布时间】:2015-07-12 01:42:56
【问题描述】:

缩小了一个我发现测试与JPanelJLabel 一起使用的样本。

createTransferable() 调用为JPanelJLabel 创建一个新的TransferHandler 对象。

由于没有setDraggable 方法,所以我包含了exportAsDrag(如果对象没有setDraggable 方法,我认为这是必需的)。

虽然createTransferable() 返回null 并且不会真正做任何事情我至少应该执行println,但是代码似乎没有进入该部分,这意味着既没有看到面板也没有看到标签作为一个可拖动的对象。

要让它被视为可拖动对象,缺少什么步骤。 如果您有一个带有一堆标签的面板,是否建议使面板可拖动并分类哪个标签或使每个单独的标签可拖动?

import java.awt.*;
import java.awt.datatransfer.Transferable;
import javax.swing.*;
import java.awt.event.InputEvent;

public class DnDTransferableTest {

public static void main(String[] args) {
    new DnDTransferableTest();
}

public DnDTransferableTest() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class TestPane extends JPanel {

    private JLabel label1;
    private JLabel label2;

    public TestPane() {

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weighty = 1;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        label1 = new JLabel("Drag Me.");
        add(label1, gbc);

        label2 = new JLabel("Drag Me too.");
        gbc.gridx++;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.NONE;
        add(label2, gbc);

        setTransferHandler(new TransferHandler()
        {
            @Override
            public Transferable createTransferable(final JComponent c)
            {
                System.out.println("Inside Panel : createTransferable");
                return null;
            }

            @Override
            public int getSourceActions(final JComponent c)
            {
                System.out.println("Inside Panel : getSourceActions()");
                return COPY;
            }

            @Override
            public void exportAsDrag(final JComponent comp, final InputEvent e,  final int action)
            {
                System.out.println("Inside Panel : getSourceActions()");
                  super.exportAsDrag(comp, e, action);
            }
        });

        label1.setTransferHandler(new TransferHandler()
        {
            @Override
            public Transferable createTransferable(final JComponent c)
            {
                System.out.println("Inside Label : createTransferable");
                return null;
            }

            @Override
            public int getSourceActions(final JComponent c)
            {
                System.out.println("Inside Label : getSourceActions()");
                return COPY;
            }

            @Override
            public void exportAsDrag(final JComponent comp, final InputEvent e,  final int action)
            {
                System.out.println("Inside Label : getSourceActions()");
                  super.exportAsDrag(comp, e, action);
            }
        });

    }
}
}

【问题讨论】:

  • 你想让用户专门拖动什么?一个图像?一个组件?
  • 我的实际对象要复杂得多,现在我只是想了解一下为什么这些项目不能被识别为可拖动。我正在寻找更直接的路线,而不必实现任何鼠标侦听器。
  • 我认为您需要一个 MouseListener 来允许 JLabel 接受拖动手势,因为它没有 setDragEnabled(...) 方法。

标签: java swing drag-and-drop jpanel jlabel


【解决方案1】:

我认为您需要一个 MouseListener 来允许 JLabel 接受拖动手势,因为它没有 setDragEnabled(...) 方法。

在 DnD 中使用 MouseListener:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.TransferHandler;

public class DnDTransferableTest {

   public static void main(String[] args) {
      new DnDTransferableTest();
   }

   public DnDTransferableTest() {
      EventQueue.invokeLater(new Runnable() {
         @Override
         public void run() {
            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
         }
      });
   }

   public class TestPane extends JPanel {

      private JLabel label3;
      private JTextField textField = new JTextField(15);

      public TestPane() {
         label3 = new JLabel("Fubars Rule!");
         add(label3);
         add(Box.createHorizontalStrut(35));
         add(textField);

         label3.setTransferHandler(new TransferHandler("text"));
         label3.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent mEvt) {
               JComponent component = (JComponent) mEvt.getSource();
               TransferHandler tHandler = component.getTransferHandler();
               tHandler.exportAsDrag(component, mEvt, TransferHandler.COPY);
            }
         });
      }
   }
}

【讨论】:

  • 啊,有趣。您对 exportAsDrag 的使用是有道理的。正如怀疑的那样,当 setDragEnabled(...) 不可用时使用该方法。一个问题是我的实现偏离了基础。
  • 添加了鼠标侦听器并收到异常,然后注意到仍然需要设置 setTransferHandler()。这样做并且有效,因为它是为“文本”设计的。然后我切换到使用我的匿名类,它覆盖了 createTransferable (),现在该方法触发了。酷!!!
猜你喜欢
  • 1970-01-01
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多