有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java拖放以在JPanel上移动JTextArea

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

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

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) {

        }
    }
}

共 (1) 个答案

  1. # 1 楼答案

    你真的不想在JTextComponent上尝试和“拖动”,它们已经启用了允许用户点击和拖动以突出显示文本的功能,你真的不想在这个范围内竞争

    相反,您希望在组件周围定义一个“热区”区域,该区域允许您在某些位置“高亮显示”组件,并允许用户通过它拖动组件

    例如

    Move Handel

    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<HotZone> 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来检测用户何时拖拽,但是你需要向它添加更多的功能来确定拖拽的实际含义(调整大小或移动);)