2017-12-18 185 views
2

我試圖創建一種圖形編輯器,允許用戶創建美式足球比賽的圖形描述。要做到這一點,用戶應該能夠做到以下幾點:在Java中拖動組件的Swing庫

1)單擊並用鼠標左鍵移動圖片點擊

2)改變圖像(圓形,方形和線)

3)重置所有物體的尺寸

理想情況下,我希望能夠添加可調整的顏色和線條粗細,但這是很遙遠的道路。

現在,我所能做的就是創建JButton,點擊時可以循環顯示圖像。我想我想將其更改爲JComboBox,以便用戶可以直接轉到正確的圖像。這裏是我的類名爲:FBButton

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

@SuppressWarnings("serial") 
public class FBButton extends JButton implements ActionListener { 
    ImageIcon SN, SL, SR, SC, CN, CL, CR, CC, IN; 
    byte value = 0; 
    FBMouseListener listener; 

    public FBButton() { 

     listener = new FBMouseListener(); 

     SN = new ImageIcon(this.getClass().getResource("square_null.png")); 
     SL = new ImageIcon(this.getClass().getResource("square_left.png")); 
     SR = new ImageIcon(this.getClass().getResource("square_right.png")); 
     SC = new ImageIcon(this.getClass().getResource("square_line.png")); 

     CN = new ImageIcon(this.getClass().getResource("circle_null.png")); 
     CL = new ImageIcon(this.getClass().getResource("circle_left.png")); 
     CR = new ImageIcon(this.getClass().getResource("circle_right.png")); 
     CC = new ImageIcon(this.getClass().getResource("circle_line.png")); 

     IN = new ImageIcon(this.getClass().getResource("invisible.png")); 

     addActionListener(this); 
    } 

    public void actionPerformed(ActionEvent e) { 
     value++; 
     value %= 9; 

     if (value == 1) { 
      setIcon(SN); 
     } else if (value == 2) { 
      setIcon(SL); 
     } else if (value == 3) { 
      setIcon(SR); 
     } else if (value == 4) { 
      setIcon(SC); 
     } else if (value == 5) { 
      setIcon(CN); 
     } else if (value == 6) { 
      setIcon(CL); 
     } else if (value == 7) { 
      setIcon(CR); 
     } else if (value == 8) { 
      setIcon(CC); 
     } else { 
      setIcon(IN); 
     } 


    } 

} 

這些按鈕的作用和圖像都可以找到。這裏是我的類FBPlayerFrame

package swing; 

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

public class FBPlayerFrame extends JFrame { 

    JPanel p = new JPanel(); 
    FBButton buttons[] = new FBButton[22]; 
    String choices[] = { "Hallo", "Bonjour", "Conichuwa" }; 
    JComboBox boxes[]; 
    JComboBox here = new JComboBox(choices); 
    FBComboBox vince; 

    Dimension dim = new Dimension(52, 52); 

    public static void main(String[] args) { 
     new FBPlayerFrame(); 
    } 

    public FBPlayerFrame() { 
     super("Football Start"); 
     setSize(400, 400); 
     setResizable(false); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     p.setLayout(null); 


     for (int i = 0; i < 4; i++) { 
      buttons[i] = new FBButton(); 
      buttons[i].setPreferredSize(dim); 
      buttons[i].setLocation(20, 40 + 60 * i); 
      p.add(buttons[i]); 


     } 


     add(p); 

     setVisible(true); 
    } 

} 

在保持特定的精神代碼,我所尋求的首先是右鍵單擊並拖動Jbutton將,或JComboBoxes,整個框架的能力。如果按鈕的座標可以在某個時候保存,那麼以後也會有所幫助,但現在這不是必要的。

我已經搜索了StackOverflow和youtube的類似問題,但有一個具有挑戰性的時間找到一些具體回答我的問題。

UPDATE:這裏是我的FBMouseListener

代碼
package swing; 

import java.awt.Component; 
import java.awt.Point; 
import java.awt.event.*; 
import javax.swing.event.MouseInputAdapter; 

public class FBMouseListener extends MouseInputAdapter { 
    Point location; 
    MouseEvent pressed; 

    public void mousePressed(MouseEvent me) { 
     pressed = me; 
     System.out.println("Found me"); 
    } 

    public void mouseDragged(MouseEvent me) { 
     Component component = me.getComponent(); 
     location = component.getLocation(location); 
     int x = location.x - pressed.getX() + me.getX(); 
     int y = location.y - pressed.getY() + me.getY(); 
     System.out.println("(" + x + ", " + y + ")"); 
     component.setLocation(x, y); 
    } 
} 
+0

setBounds和repaint應該能夠幫助你。我記得做了類似的事情,使得我的按鈕幾年前「可拖動」。 – Stultuske

回答

4

用於拖動組件的基本代碼是:

public class DragListener extends MouseInputAdapter 
{ 
    Point location; 
    MouseEvent pressed; 

    public void mousePressed(MouseEvent me) 
    { 
     pressed = me; 
    } 

    public void mouseDragged(MouseEvent me) 
    { 
     Component component = me.getComponent(); 
     location = component.getLocation(location); 
     int x = location.x - pressed.getX() + me.getX(); 
     int y = location.y - pressed.getY() + me.getY(); 
     component.setLocation(x, y); 
    } 
} 

創建類的一個實例,然後將其添加到您希望拖動的任何組件。

您還可以查看Component Mover課程。它允許你拖動桌面上的窗口或面板上的組件。它提供了一些更多的拖動功能。

編輯:

這需要我幾行代碼來測試這個解決方案:

JButton button = new JButton("hello"); 
button.setSize(button.getPreferredSize()); 

DragListener drag = new DragListener(); 
button.addMouseListener(drag); 
button.addMouseMotionListener(drag); 

JPanel panel = new JPanel(null); 
panel.add(button); 

JFrame frame = new JFrame(); 
frame.add(panel); 
frame.setSize(400, 400); 
frame.setVisible(true); 

把上面的代碼在main()方法,你有簡單的代碼進行測試。

+0

我對Java相當陌生。我通常使用C語言編寫代碼,而OOP對我來說還是比較新的。事實上,這是我對複雜代碼的第一次嘗試。 我創建了一個名爲'FBDragListener'的新類,基本上覆制了你的代碼。然後,在'FBButton'裏面增加了一條新線,如 ... 'FBDragListener listener' 'public FBButton(){' 'listener = new FBDragListener()'... 我認爲這會使按鈕能夠移動。我沒有得到任何錯誤,但程序似乎功能相同[按鈕在那裏,可點擊,但不能移動]。 – MDR

+0

您是否閱讀過提供的鏈接?您是否已將偵聽器添加到按鈕?您的面板是否使用空佈局? – camickr

+0

我沒看過提供的鏈接,非常感謝你使用該工具。我仍試圖綜合它,但我感謝你爲我採購它。 我將偵聽器添加到按鈕,並用'p.setLayout(null)'改變了Jpanel'p'。奇怪的是,現在我的按鈕根本沒有顯示出來,即使我使用setLocation()作爲按鈕。 我將編輯我的問題以反映更新的代碼。 – MDR