拖放以在JPanel上移动JTextArea

我希望能够单击JTextArea并将其拖动到我的JPanel周围。 我不确定这样做的方法。 我想要做的是在拖动时更改JTextArea的x,y坐标,我不是在另一个上面或下面拖动JTextArea 。 就在屏幕上,类似于在Microsoft PowerPoint等程序中移动文本框

我能想到的唯一方法是使用MouseListener但我想知道除了检测JTextArea上的hover/按下/拖动之外是否有更简单的方法来实现它。 关于如何开始的任何想法?

 import java.awt.Color; import java.awt.Cursor; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JTextArea; public class UMLEditor { public static void main(String[] args) { JFrame frame = new UMLWindow(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(30, 30, 1000, 700); frame.getContentPane().setBackground(Color.white); frame.setVisible(true); frame.setLocationRelativeTo(null); frame.setVisible(true); } } class UMLWindow extends JFrame { Canvas canvas = new Canvas(); private static final long serialVersionUID = 1L; public UMLWindow() { addMenus(); } public void addMenus() { getContentPane().add(canvas); JMenuBar menubar = new JMenuBar(); JMenuItem newTextBox = new JMenuItem("New Text Box"); newTextBox.setMnemonic(KeyEvent.VK_E); newTextBox.setToolTipText("Exit application"); newTextBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent event) { canvas.addTextBox(); } }); menubar.add(newTextBox); setJMenuBar(menubar); setSize(300, 200); setLocationRelativeTo(null); setDefaultCloseOperation(EXIT_ON_CLOSE); } } class Canvas extends JPanel { JTextArea commentTextArea = new JTextArea(10, 10); public Canvas() { this.setOpaque(true); MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); addMouseListener(myMouseAdapter); addMouseMotionListener(myMouseAdapter); } public void addTextBox() { commentTextArea.setLineWrap(true); commentTextArea.setWrapStyleWord(true); commentTextArea.setVisible(true); commentTextArea.setLocation(0, 0); this.add(commentTextArea); commentTextArea.setBounds(0, 0, 100, 100); revalidate(); repaint(); } class MyMouseAdapter extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { } } } 

你真的不想尝试“拖拽” JTextComponent ,它们已经启用了function,允许用户点击并拖动以突出显示文本,你真的不想在其中竞争。

相反,您希望在组件周围定义“热区”区域,以允许您“突出显示”某些组件,并允许用户通过它拖动组件。

例如…

移动亨德尔

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; public class DragMe { public static void main(String[] args) { new DragMe(); } public DragMe() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JTextArea ta = new JTextArea(10, 20); ta.setText("Bananas in pajamas"); JScrollPane sp = new JScrollPane(ta); DragProxyPane proxy = new DragProxyPane(sp); proxy.setSize(proxy.getPreferredSize()); proxy.setLocation(100 - proxy.getWidth() / 2, 100 - proxy.getHeight()/ 2); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } }); frame.add(proxy); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public static class DragProxyPane extends JPanel { public static final int BUFFER_ZONE = 10; private boolean mouseInHouse; private JComponent component; private List hotZones; public DragProxyPane(JComponent comp) { MouseAdapter ma = new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { mouseInHouse = true; repaint(); } @Override public void mouseExited(MouseEvent e) { mouseInHouse = false; repaint(); } @Override public void mouseMoved(MouseEvent e) { Cursor cursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR); for (HotZone hz : hotZones) { if (hz.getBounds(getSize()).contains(e.getPoint())) { cursor = hz.getCursor(); break; } } setCursor(cursor); } }; addMouseListener(ma); addMouseMotionListener(ma); setOpaque(false); setLayout(new BorderLayout()); add(comp); setBorder(new EmptyBorder(BUFFER_ZONE, BUFFER_ZONE, BUFFER_ZONE, BUFFER_ZONE)); hotZones = new ArrayList<>(8); // Top left, middle, right hotZones.add(new HotZone(0f, 0f, Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR))); hotZones.add(new HotZone(0.5f, 0f, Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR))); hotZones.add(new HotZone(1f, 0f, Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR))); // Left, right hotZones.add(new HotZone(0f, 0.5f, Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR))); hotZones.add(new HotZone(1f, 0.5f, Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR))); // Bottom left, middle, right hotZones.add(new HotZone(0f, 1f, Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR))); hotZones.add(new HotZone(0.5f, 1f, Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR))); hotZones.add(new HotZone(1f, 1f, Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR))); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); if (mouseInHouse) { g2d.setColor(Color.BLACK); for (HotZone hotZone : hotZones) { g2d.draw(hotZone.getBounds(getSize())); } } g2d.dispose(); } public class HotZone { private float x, y; private Cursor cursor; public HotZone(float x, float y, Cursor cursor) { this.x = x; this.y = y; this.cursor = cursor; } public Cursor getCursor() { return cursor; } public Rectangle getBounds(Dimension size) { return getBounds(size.width - 1, size.height - 1); } public Rectangle getBounds(int width, int height) { int halfBuffer = BUFFER_ZONE / 2; float xPos = (width * x) - halfBuffer; float yPos = (height * y) - halfBuffer; xPos = Math.min(Math.max(0, xPos), width - BUFFER_ZONE); yPos = Math.min(Math.max(0, yPos), height - BUFFER_ZONE); return new Rectangle(Math.round(xPos), Math.round(yPos), BUFFER_ZONE, BUFFER_ZONE); } } } } 

这将设置一个简单的代理组件,它充当热区管理器,检测进出该鼠标的鼠标,并根据光标在其中的位置更新光标,但不会破坏组件的正常操作。

现在,这个例子没有拖动,对不起,你有很多其他的例子应该可以让你通过线,但是,你可以简单地添加一个MouseListener / MouseMoitionListener到代理来检测用户何时拖动,但你将需要添加更多function,以确定拖动实际意味着什么(resize或移动);)