2011-10-07 49 views
1

這裏我嘗試在我的自定義面板中拋棄一個球,同時用戶單擊自定義呼吸機組件(它只是一個藍色方塊,組件是從JButton繼承的)。Java Swing:管理組件上的「MousePressed」事件,直到它被髮布爲止

但問題是,只有當用戶點擊呼吸機時才能管理事件,而不是所有時間都是鼠標停在呼吸機上。

在這裏,我的不同類。提前謝謝

PhysicsPanel.java

package com.gmail.loloof64.java_swing.physics_panels; 

import com.gmail.loloof64.java_swing.physics_panels.gui.MainFrame; 

public class PhysicsPanels { 

    public static void main(String[] args) { 
     new MainFrame().setVisible(true); 
    } 

} 

MainFrame.java

package com.gmail.loloof64.java_swing.physics_panels.gui; 

import javax.swing.JFrame; 
import javax.swing.JTabbedPane; 

import com.gmail.loloof64.java_swing.physics_panels.gui.the_panels.VentilatorPanel; 

public class MainFrame extends JFrame { 

    public MainFrame(){ 
     setIntrinsicsProperties(); 
     addPanels(); 
    } 

    private void setIntrinsicsProperties() { 
     setSize(400, 300); 
     setTitle("Physics panels application"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
    } 

    private void addPanels() { 
     JTabbedPane mainContainer = new JTabbedPane(); 
     add(mainContainer); 
     mainContainer.addTab("Ventilator", new VentilatorPanel()); 
     /* 
     * This tab is not usefull for the question => 
     * mainContainer.addTab("Rotating plate", new RotatingPlatePanel()); 
     */ 
    } 

    private static final long serialVersionUID = 1L; 

} 

VentilatorPanel.java

package com.gmail.loloof64.java_swing.physics_panels.gui.the_panels; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Point; 

import javax.swing.JPanel; 

import com.gmail.loloof64.java_swing.physics_panels.custom_components.BallComponent; 
import com.gmail.loloof64.java_swing.physics_panels.custom_components.VentilatorComponent; 

public class VentilatorPanel extends JPanel { 

    public VentilatorPanel(){ 
     setBackground(Color.WHITE); 
     setLayout(null); 

     ventilatorObject.setSimpleTaskOnMousedPressed(new Runnable() { 

      @Override 
      public void run() { 
       repulseBall(); 
      } 

     }); 
     add(ventilatorObject); 
     add(ballObject); 
     ventilatorObject.setLocation(100, 80); 
     ballObject.setLocation(160, 90); 
    } 

    @Override 
    public void paint(Graphics graphics) { 
     super.paint(graphics); 
    } 

    private void repulseBall(){ 
     Point oldBallLocation = ballObject.getLocation(); 
     ballObject.setLocation(oldBallLocation.x + 5, oldBallLocation.y); 
     repaint(); 
    } 

    private VentilatorComponent ventilatorObject = new VentilatorComponent(60,60); 
    private BallComponent ballObject = new BallComponent(40); 
    private static final long serialVersionUID = 1L; 

} 

VentilatorComponent.java

package com.gmail.loloof64.java_swing.physics_panels.custom_components; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import javax.swing.JButton; 

public class VentilatorComponent extends JButton { 

    public VentilatorComponent(Dimension size){ 
     super(); 
     enableInputMethods(true); 
     addMouseListener(new MouseAdapter() { 

      @Override 
       public void mousePressed(MouseEvent event) { 
        doReactToClick(); 
       } 
     }); 
     setSize(size); 
    } 

    public VentilatorComponent(int width, int height){ 
     this(new Dimension(width, height)); 
    } 

    /** 
    * Sets the task that will be executed on mouse pressing. 
    * Be carefull !!! Must be a very simple task (no looping inside) 
    * @param r - Runnable 
    */ 
    public void setSimpleTaskOnMousePressed(Runnable task){ 
     taskOnClick = task; 
    } 

    protected void doReactToClick() { 
     new Thread(taskOnClick).run(); 
    } 

    @Override 
    protected void paintComponent(Graphics graphics) { 
     super.paintComponent(graphics); 
     graphics.setColor(Color.BLUE); 
     graphics.fillRect(0, 0, getWidth(), getHeight()); 
    } 

    private Runnable taskOnClick; 
    private static final long serialVersionUID = 1L; 

} 

BallComponent.java

package com.gmail.loloof64.java_swing.physics_panels.custom_components; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 

import javax.swing.JComponent; 

public class BallComponent extends JComponent { 

    public BallComponent(int diameter){ 
     setSize(new Dimension(diameter, diameter)); 
    } 

    @Override 
    public void paintComponent(Graphics graphics) { 
     graphics.setColor(Color.RED); 
     graphics.fillOval(0,0, getWidth(), getHeight()); 
    } 

    private static final long serialVersionUID = 1L; 

} 
+0

這麼多代碼... – michael667

+0

是的,這是因爲我開始我的項目計劃一方面添加其他選項卡式窗格,在這裏我贊成重複使用,並且通過創建組件而不是僅僅管理所有面板 – loloof64

回答

3

在不讀取所有代碼的情況下,問題可能如下所示:Mousepressed僅在用戶按下按鈕時觸發一次。您必須將該狀態保存在變量中(例如boolean pressed = true),然後對mousereleased事件作出反應,這會將您的變量設置爲false。通過你的變量的狀態,你知道鼠標按鈕當前是否被按下或釋放。

+0

哦,您是對的,但我認爲有一種方法可以在不保存狀態的情況下對其進行管理。不可能嗎?所以,我會去諮詢你的建議。感謝:) – loloof64

+0

不幸的是,在當前的類設計中,我不能避免在嘗試實現鼠標「按壓」功能時阻止UI線程。 – loloof64

+0

而不是布爾變量,你可以啓動一個新的線程,''reprapBall''上'mousepressed'並殺死'mousereleased'上的線程 – michael667

1

要獲得生成的事件當鼠標處於按下狀態你需要使用Mo useMotionListener並處理mouseDragged()事件。

+0

但是,如果鼠標沒有移動,你還會得到這些事件嗎? – michael667

+0

我嘗試過使用MouseDragged事件,但是我只有在按下按鈕時也進入呼吸機的情況下才有效:S – loloof64