简体   繁体   English

Java Swing-拖放drawString文本

[英]Java Swing - Drag & Drop drawString text

I've had a look around for this problem but couldn't find an answer... 我到处都在寻找这个问题,但是找不到答案...

I currently have a JPanel in which I'm painting a load of unicode characters (music notes) using the Graphics2D g2.drawString() method. 我目前有一个JPanel,其中使用Graphics2D g2.drawString()方法绘制了许多Unicode字符(音符)。

I have an ArrayList of KeyPress objects, each of which contains one or more g2.drawString() calls. 我有一个KeyPress对象的ArrayList ,每个对象包含一个或多个g2.drawString()调用。

So each KeyPress object is a music note and is painted on the JPanel. 因此,每个KeyPress对象都是一个音符,并绘制在JPanel上。

How would I go about adding the functionality to enable the user to select and drag the objects? 我将如何添加使用户能够选择和拖动对象的功能?

Why not put your Strings in JLabels and simply drag them... 为什么不将您的Strings放入JLabels并简单地将其拖动...

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class DragLabelEg {
   private static final String[] LABEL_STRINGS = { "Do", "Re", "Me", "Fa",
         "So", "La", "Ti" };
   private static final int HEIGHT = 400;
   private static final int WIDTH = 600;
   private static final Dimension MAIN_PANEL_SIZE = new Dimension(WIDTH, HEIGHT);
   private static final int LBL_WIDTH = 60;
   private static final int LBL_HEIGHT = 40;
   private static final Dimension LABEL_SIZE = new Dimension(LBL_WIDTH,
         LBL_HEIGHT);
   private JPanel mainPanel = new JPanel();
   private Random random = new Random();

   public DragLabelEg() {
      mainPanel.setPreferredSize(MAIN_PANEL_SIZE);
      mainPanel.setLayout(null);

      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      for (int i = 0; i < LABEL_STRINGS.length; i++) {
         JLabel label = new JLabel(LABEL_STRINGS[i], SwingConstants.CENTER);
         label.setSize(LABEL_SIZE);
         label.setOpaque(true);
         label.setLocation(random.nextInt(WIDTH - LBL_WIDTH),
               random.nextInt(HEIGHT - LBL_HEIGHT));
         label.setBackground(new Color(150 + random.nextInt(105), 150 + random
               .nextInt(105), 150 + random.nextInt(105)));
         label.addMouseListener(myMouseAdapter);
         label.addMouseMotionListener(myMouseAdapter);

         mainPanel.add(label);
      }
   }

   public JComponent getMainPanel() {
      return mainPanel;
   }

   private class MyMouseAdapter extends MouseAdapter {
      private Point initLabelLocation = null;
      private Point initMouseLocationOnScreen = null;

      @Override
      public void mousePressed(MouseEvent e) {
         JLabel label = (JLabel) e.getSource();
         // get label's initial location relative to its container
         initLabelLocation = label.getLocation();

         // get Mouse's initial location relative to the screen
         initMouseLocationOnScreen = e.getLocationOnScreen();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         initLabelLocation = null;
         initMouseLocationOnScreen = null;
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         // if not dragging a JLabel
         if (initLabelLocation == null || initMouseLocationOnScreen == null) {
            return;
         }
         JLabel label = (JLabel) e.getSource();

         // get mouse's new location relative to the screen
         Point mouseLocation = e.getLocationOnScreen();

         // and see how this differs from the initial location.
         int deltaX = mouseLocation.x - initMouseLocationOnScreen.x;
         int deltaY = mouseLocation.y - initMouseLocationOnScreen.y;

         // change label's position by the same difference, the "delta" vector
         int labelX = initLabelLocation.x + deltaX;
         int labelY = initLabelLocation.y + deltaY;

         label.setLocation(labelX, labelY);
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createGui();
         }
      });
   }

   private static void createGui() {
      JFrame frame = new JFrame("App");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new DragLabelEg().getMainPanel());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }
}

See the tutorial on supporting user interaction. 请参阅有关支持用户交互的教程 It comes down to determining which (if any) objects were underneath the mouse when it was clicked and held. 归结为确定在单击并按住鼠标时哪些对象(如果有)在鼠标下方。 On a drag event, the selected object is moved and the canvas is repainted. 发生拖动事件时,将移动所选对象,并重新绘制画布。

You can obtain the bounds of the string by using FontMetrics : 您可以使用FontMetrics获得字符串的边界:

String text = "Hello world!";
Rectangle2D bounds = g2.getFontMetrics().getStringBounds(text, g2);

I assume the rectangle top-left will be (0, 0), so you need to add (x, y) to it (where x, y are the parameters you passed to drawString). 我假设矩形的左上角将是(0,0),因此您需要向其添加(x,y)(其中x,y是您传递给drawString的参数)。

This example shows one way to select multiple objects, using keyboard or mouse, and drag them as a group. 示例显示了一种使用键盘或鼠标选择多个对象并将其作为一组拖动的方法。 It manipulates arbitrary nodes rather than glyphs, but you may find it instructive. 它操纵任意节点而不是字形,但是您可能会发现它具有启发性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM