2016-10-21 47 views
1

我在JFrame中有一個簡單的JPanel和JButton。當按下按鈕時,我希望它閃爍幾次。主要的問題是我嘗試了幾種不同的方法來實現它,使用Thread.sleep(200)和for循環的numBlinks。然而,這只是「暫停」面板,而它切換顏色,只顯示最終結果。在按下JButton後讓JPanel「閃爍」幾次

謝謝。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class BlinkingJPanel implements ActionListener{ 

    private JFrame window; 
    private JPanel panel; 
    private JButton button; 

    private final Color BACKGROUND1 = Color.GRAY; 
    private final Color BACKGROUND2 = Color.WHITE; 
    private final Color BORDER_COLOR = Color.BLACK; 
    private final int BORDER_SIZE = 1; 

    private final int WINDOW_SIZE = 200; 
    private final int PANEL_SIZE = 100; 
    private final int BUTTON_SIZE = 100; 

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

    public BlinkingJPanel() { 
     setUpWindow(); 
     setUpPanel(); 
     setUpButton(); 

     window.add(panel, BorderLayout.CENTER); 
     window.add(button, BorderLayout.NORTH); 
    } 

    private void setUpWindow() { 
     window = new JFrame("Blinking JPanel"); 

     window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     window.setBackground(BACKGROUND1); 
     window.setSize(WINDOW_SIZE, WINDOW_SIZE); 
     window.setVisible(true); 
    } 

    private void setUpPanel() { 
     panel = new JPanel(); 

     panel.setSize(PANEL_SIZE, PANEL_SIZE); 
     panel.setBorder(BorderFactory.createLineBorder(BORDER_COLOR, BORDER_SIZE)); 
     panel.setBackground(BACKGROUND1); 
     panel.setVisible(true); 
    } 

    private void setUpButton() { 
     button = new JButton("Blink"); 

     button.setSize(BUTTON_SIZE, BUTTON_SIZE/2); 
     button.setActionCommand("Button1"); 
     button.addActionListener(this); 
     button.setVisible(true); 
    } 

    public void actionPerformed(ActionEvent e) { 

     switch(e.getActionCommand()) { 
     case "Button1": blink(1); 
      break; 
     default: System.out.println("Default Case"); 
      break; 
     } 

    } 

    private void blink(int numBlinks) { 
     // TODO: make panel blink on it's own 

     if(panel.getBackground() == BACKGROUND1) { 
      panel.setBackground(BACKGROUND2); 
     } else { 
      panel.setBackground(BACKGROUND1); 
     } 

    } 


} 
+5

您需要使用javax.swing.Timer – ControlAltDel

+1

https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html @ControlAltDel引用的文檔 –

回答

1

我使用Timer創建了一個解決方案。 Iv'e試圖保持簡單。我所做的只是添加一個計時器,當你開始計時時(它們每隔幾毫秒持續彈出一次,將其設置爲300ms)以及一個我剛剛使用該類的actionlistener時,它會花費你想要的時間。當計時器彈出時,它會觸發actionlistener,使其閃爍,直到頂部的BLINK_AMOUNT中的金額已被收回。然後停止計時器並將閃爍計數重置爲0.僅當您按下按鈕時計時器纔會啓動。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class BlinkingJPanel implements ActionListener{ 

private JFrame window; 
private JPanel panel; 
private JButton button; 

private final Color BACKGROUND1 = Color.GRAY; 
private final Color BACKGROUND2 = Color.WHITE; 
private final Color BORDER_COLOR = Color.BLACK; 
private final int BORDER_SIZE = 1; 

private final int WINDOW_SIZE = 200; 
private final int PANEL_SIZE = 100; 
private final int BUTTON_SIZE = 100; 

private final int BLINK_AMOUNT = 1; 
private Timer blinkTimer; 
private int blinkCount; 

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

public BlinkingJPanel() { 
    setUpWindow(); 
    setUpPanel(); 
    setUpButton(); 

    window.add(panel, BorderLayout.CENTER); 
    window.add(button, BorderLayout.NORTH); 

    //Timer constructor takes pop time and action listener 
    blinkTimer = new Timer(300, this); 
    blinkCount = 0; 

    window.setVisible(true); 
} 

private void setUpWindow() { 
    window = new JFrame("Blinking JPanel"); 

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setBackground(BACKGROUND1); 
    window.setSize(WINDOW_SIZE, WINDOW_SIZE); 
} 

private void setUpPanel() { 
    panel = new JPanel(); 

    panel.setSize(PANEL_SIZE, PANEL_SIZE); 
    panel.setBorder(BorderFactory.createLineBorder(BORDER_COLOR, BORDER_SIZE)); 
    panel.setBackground(BACKGROUND1); 
    panel.setVisible(true); 
} 

private void setUpButton() { 
    button = new JButton("Blink"); 

    button.setSize(BUTTON_SIZE, BUTTON_SIZE/2); 
    button.setActionCommand("Button1"); 
    button.addActionListener(this); 
    button.setVisible(true); 
} 

public void actionPerformed(ActionEvent e) { 
    if(e.getSource().equals(button)){ 
     blinkTimer.start(); 
    } 
    else if(e.getSource() instanceof Timer){ 
     if(blinkCount == BLINK_AMOUNT){ 
      blinkCount = 0; 
      blinkTimer.stop(); 
     } 
     blink(); 
     blinkCount++; 
    }else{ 
     System.out.println("Default"); 
    } 
} 

private void blink() { 
    if(panel.getBackground() == BACKGROUND1) { 
     panel.setBackground(BACKGROUND2); 
    } else { 
     panel.setBackground(BACKGROUND1); 
    } 

} 
} 

如果有任何疑惑,請隨時詢問。

正如你所說,thread.sleep()不會像所有的swing在一個線程上運行那樣工作,所以調用該函數將使整個線程停止運行(執行代碼),然後運行代碼的下一部分。

希望這會有所幫助。

+0

謝謝Kyal Bond,此工作。我想我理解這一切。我必須做出的唯一改變是在actionPerformed(...){... –

+0

,以便每次重置。 blink(); blinkCount ++; if(blinkCount == BLINK_AMOUNT){blkCount = 0; blinkTimer.stop(); } –

+0

哦,你想連續閃爍?但如果問題得到解決,請接受答案,讓其他人知道:) –