2014-07-24 69 views
-1

我的程序是將字母轉換爲一些信號。我的主要方法會生成一些隨機字母。該信件被傳遞給另一個方法,該方法根據生成的Letter調用repaint()方法。PaintComponent()方法用於繪製一個填充了白色的圓。當我執行程序時,我只得到一個Jframe。我看不到這個圈子,請幫忙。當某些條件得到滿足時畫圓圈

package morsecode; 

import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.util.Random; 
import java.awt.*; 


public class MorseCode extends Frame { 


    public static void main(String[] args) { 

       MorseCode mc = new MorseCode(); 
       MorseCode frame = new MorseCode(); 


     final String chars = "abcdefghijklmnopqrstuvwxyz1234567890"; 
     char word; 

       for(int i=1;i<=1;i++) 

       { 
      Random rand = new Random(); 
      int x = rand.nextInt(36); 
      word = chars.charAt(x); 
      System.out.print(word); 
         frame.setBackground(Color.BLACK); 
         frame.addWindowListener(
     new WindowAdapter() 
     { 
     @Override 
     public void windowClosing(WindowEvent we) 
     { 
      System.exit(0); 
     } 
     } 
    ); 

     frame.setSize(400, 400); 
     frame.setVisible(true); 
         mc.toMorseCode(word); 
       } 
    } 


    void toMorseCode(char letter) 
    { 

    switch(letter) 
    { 
     case 'A' | 'a': 
      repaint(); 
      Thread.sleep(1000); 
      repaint(); 
      Thread.sleep(2000); 
      break; 
     case 'B' | 'b': 
      repaint(); 
      Thread.sleep(1000); 
      repaint(); 
       Thread.sleep(1000); 
       repaint(); 
       Thread.sleep(1000); 
      repaint(); 
      Thread.sleep(2000); 
      break; .............. 
     } 
} 
    public void paintComponent(Graphics g) { 
    Graphics2D ga = (Graphics2D)g; 
    ga.setColor(Color.white); 
    ga.fillOval(125,125,150,150); 

    } 
} 
+0

使用邏輯和一致的代碼格式風格!代碼縮進旨在幫助人們遵循程序流程。 –

回答

3

兩件事情......

首先,調用事件分派線程中Thread.sleep(2000);將阻止EDT從事件隊列中處理事件,包括油漆事件。

其次,Frame沒有paintComponent

添加@Override註釋並嘗試調用super.paintComponent會突出顯示此問題,因爲代碼不會編譯。

@Override 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); 

首先,首先使用JPanel來保存您的核心邏輯並執行自定義繪畫。

其次,使用javax.swing.Timer進行動畫。有關詳細信息,

更新

的基本概念是相對簡單的見How to use Swing Timers。你需要某種第二/後臺線程,它可以產生輸出變化之間的延遲。然後,您需要根據您嘗試顯示的信息類型在每次延遲之前更新UI。

實現變得棘手,因爲鞦韆,最喜歡的GUI框架,是單線程的,而不是線程安全的。

這意味着,您不能阻止GUI線程,這樣做會阻止UI被重新繪製等等,並且您必須在GUI線程的上下文內更新任何UI組件的狀態。

這意味着雖然您可以使用Thread在後臺運行,但您必須確保只對EDT中的所有UI進行更改/修改。

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingWorker; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class MorseCodeTest { 

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

    public MorseCodeTest() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static final int GAP = 500; 
    public static final int DOT = 1000; 
    public static final int DASH = 4000; 

    public interface Transmitter { 

     public void setTap(boolean tap); 

    } 

    public class TestPane extends JPanel implements Transmitter { 

     private MorseCode code; 
     private boolean tapped; 

     public TestPane() { 

      code = MorseCode.create('A').addDot().addDash(); 

      addMouseListener(new MouseAdapter() { 

       @Override 
       public void mouseClicked(MouseEvent e) { 
        Signalar signalar = new Signalar(TestPane.this, code); 
        signalar.execute(); 
       } 

      }); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (tapped) { 
       Graphics2D g2d = (Graphics2D) g.create(); 
       int diameter = Math.min(getWidth(), getHeight())/2; 
       int x = (getWidth() - diameter)/2; 
       int y = (getHeight() - diameter)/2; 
       g2d.fillOval(x, y, diameter, diameter); 
       g2d.dispose(); 
      } 
     } 

     @Override 
     public void setTap(boolean tap) { 
      tapped = tap; 
      repaint(); 
     } 

    } 

    public class Signalar extends SwingWorker<Void, Boolean> { 

     private final MorseCode code; 
     private final Transmitter transmitter; 

     public Signalar(Transmitter transmitter, MorseCode code) { 
      this.code = code; 
      this.transmitter = transmitter; 
     } 

     @Override 
     protected void process(List<Boolean> chunks) { 
      transmitter.setTap(chunks.get(chunks.size() - 1)); 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for (Tone tone : code.getTones()) { 
       publish(true); 
       Thread.sleep(tone.getDelay()); 
       publish(false); 
       Thread.sleep(GAP); 
      } 
      return null; 
     } 

    } 

    public static class Tone { 

     private final int delay; 

     public Tone(int delay) { 
      this.delay = delay; 
     } 

     public int getDelay() { 
      return delay; 
     } 

    } 

    public static class DashTone extends Tone { 

     public DashTone() { 
      super(DASH); 
     } 

    } 

    public static class DotTone extends Tone { 

     public DotTone() { 
      super(DOT); 
     } 

    } 

    public static class MorseCode { 

     private final char value; 
     private final List<Tone> tones; 

     public static MorseCode create(char value) { 
      MorseCode code = new MorseCode(value); 
      return code; 
     } 

     public MorseCode(char value) { 
      this.value = value; 
      this.tones = new ArrayList<>(25); 
     } 

     public char getValue() { 
      return value; 
     } 

     public MorseCode addDash() { 
      return addTone(new DashTone()); 
     } 

     public MorseCode addDot() { 
      return addTone(new DotTone()); 
     } 

     public MorseCode addTone(Tone tone) { 
      tones.add(tone); 
      return this; 
     } 

     public Iterable<Tone> getTones() { 
      return tones; 
     } 

    } 

} 
+0

Swing是一個單線程框架,這意味着如果你阻塞事件分派線程(主UI線程),它將無法繪製或響應用戶輸入。請參見[併發中的Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) – MadProgrammer

+0

我在paint方法內部添加了睡眠線程。我仍然沒有得到預期的結果。和案例A一樣,它應該閃爍三次。對於案例B,它應該閃爍兩次,依此類推。有什麼辦法可以實現它嗎?請幫助。 – user3857726

+0

Swing是一個單線程環境。任何阻塞Swing線程的東西(如'Thread.sleep')都會停止繪畫的發生。 – MadProgrammer

相關問題