拖放即可在JPanel上移动JTextArea [英] Dragging-and-dropping to move a JTextArea around on JPanel

查看:139
本文介绍了拖放即可在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(退出应用程序);
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扩展MouseAdapter {

@Override
public void mousePressed(MouseEvent e){

}

@Override
public void mouseDragged(MouseEvent e){

}

@Override
public void mouseMoved(MouseEvent e ){

}
}
}


解决方案

你真的不想尝试并拖动 JTextComponent ,它们已经启用了功能,允许用户点击并拖动以突出显示文本,您真的不想在此内进行竞争。



相反,您要在组件周围定义热区区域允许您在某些情况下突出显示组件,并允许用户通过它拖动组件。



例如...



  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(){
尝试{
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 - .getHeight()/ 2);

JFrame frame = new JFrame(Testing);
frame.setD efaultCloseOperation(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;
私有JComponent组件;

私人列表< HotZone>热区;

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);
(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);
//左上角,中间右侧
hotZones.add(新的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)));
//左,右
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)));
//左下中间,右边
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); (HotZone hotZone:hotZones)
{
g2d.draw(hotZone.getBounds(getSize()));
}
}
g2d.dispose();
}

public class HotZone {

private float x,y;
私人游标光标;

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

返回新的Rectangle(Math.round(xPos),Math.round(yPos),BUFFER_ZONE,BUFFER_ZONE);

}

}

}

}

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



现在,此示例不拖动,对不起,您有很多其他示例应该能够让你超越行,但是你可以简单地向代理添加一个 MouseListener / MouseMoitionListener 来检测用户何时拖动,但您需要添加一些更多的功能来确定拖动实际意味着什么(调整大小或移动);)


I want to be able to click on a JTextArea and drag it around my JPanel. I'm not sure the method on doing so. What I'm trying to do is change the x,y coordinates of the JTextArea as it is dragged, I'm not dragging a JTextArea above or below another. Just around on the screen, similar to moving Text Boxes in a program like Microsoft PowerPoint

The only method I can think of is using a MouseListener but I'm wondering if there is an easier way to implement it other than detecting a hover/press/drag on the JTextArea. Any ideas on how I can start?

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

        }
    }
}

解决方案

You don't really want to try and "drag" on JTextComponents, they already have functionality enabled which allows the user to click and drag to highlight text, you really don't want to be competing within this.

Instead, you want to define a "hot zone" area around the component which would allow you "highlight" the component in some and allow the user to drag the component via it.

For example...

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

            }

        }

    }

}

This sets up a simple proxy component which acts as the hot zone manager, detecting the mouse coming into or out of it and updating the cursor based on its location within in it, but it does not disrupt the normal operations of the component.

Now, this example doesn't drag, sorry, you have plenty of other examples which should be able to get you over the line, but, you could simply add a MouseListener/MouseMoitionListener to the proxy to detect when the user drags, but you will need to add some more functionality to it to determine what that drag actually means (resize or move) ;)

这篇关于拖放即可在JPanel上移动JTextArea的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆