2012-02-28 79 views
1

我有一個到處尋找這個問題,但未能找到答案......的Java Swing - 拖放文本drawString之

我現在有一個JPanel在我畫的unicode的負載字符(音符)使用Graphics2Dg2.drawString()方法。

我有一個ArrayListKeyPress對象,其中每個對象都包含一個或多個g2.drawString()調用。

因此,每個KeyPress對象是一個音樂筆記,並繪製在JPanel上。

我該如何去添加功能以使用戶能夠選擇和拖動對象?

+0

我不太確定這是一個真正的拖放問題(使用拖放數據傳輸支持的問題),但我覺得它更可能是一個簡單的MouseListener - 單擊並拖動一個屏幕圖形或精靈型問題。那麼,你有什麼嘗試?你熟悉使用MouseListeners和MouseMotionListeners嗎? – 2012-02-28 03:19:06

+0

我試過用邊界拖動矩形和其他形狀的示例,但我不知道如何判斷鼠標單擊是否在字符串區域內。 – 2012-02-28 03:30:25

回答

1

請參閱supporting user interaction.上的教程關於確定單擊並保持鼠標下方的哪些(如果有)對象時需要考慮的問題。在拖動事件中,所選對象將被移動並且畫布被重新繪製。

您可以通過使用FontMetrics獲取字符串的邊界:

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

我假設左上角的矩形將是(0,0),所以你需要添加(X,Y),將​​它(其中x,y是您傳遞給drawString的參數)。

+0

謝謝,但我如何獲得字符串的邊界? – 2012-02-28 03:29:15

+0

正在更新答案... – sjr 2012-02-28 03:33:39

+0

感謝您的更新,目前我正在翻譯「邊界」矩形,有沒有辦法設置矩形的座標? – 2012-02-28 04:10:36

3

爲什麼不把你的字符串中的JLabel和簡單地將他們...

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); 
    } 
} 
+0

我認爲作者可能想要選擇一堆「標籤」,然後一起移動,在這種情況下,鼠標向下,鼠標移動事件需要測試我們是否有任何「選定的項目」或不 – Dapeng 2012-02-28 04:11:00

1

example顯示了一種方式來選擇多個對象,使用鍵盤或鼠標,拖動 他們作爲一個羣體。它操作任意節點而不是字形,但是您可能會發現它有啓發性。