2013-03-19 242 views
0

我需要使用3個按鈕(啓動,反向,停止)和滾動條來模擬運行風扇來控制速度。 我寫了一個代碼,但他們沒有錯誤,但它不工作。 首先,類擴展了Jframe,並且帶有按鈕和扇形弧的窗口出現了,但是當它擴展Japplet時,它沒有出現。 但它沒有雙向工作。使用java的運行風扇

package Ass3_10203038; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import java.awt.Graphics; 
import javax.swing.JButton; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.Adjustable; 
import java.awt.event.AdjustmentEvent; 
import java.awt.event.AdjustmentListener; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class Ass3_10203038 extends JApplet implements Runnable { 
private static 
    Lock lock = new ReentrantLock(); 
Graphics fan; 
JButton start = new JButton("Start"); 
JButton stop = new JButton("Stop"); 
JButton reverse = new JButton("Reverse"); 
JScrollBar speed = new JScrollBar(); 
Thread timer = new Thread(); 
int thr=50; 
int strtpt=0; 
JFrame frame= new JFrame(); 

@Override 
public void run() { 
    repaint(); 
    while (true) { 
     try { 
      Thread.sleep(thr); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    } 

    public Ass3_10203038() { 
    final ArcsPanel arcs = new ArcsPanel(); 

    JPanel p = new JPanel(); 

    p.setSize(500, 500); 
    p.add(arcs); 
    // p.setSize(5000, 5000); 
    p.add(start); 
    p.add(stop); 
    p.add(reverse); 
    p.add(speed); 
    p.setLayout(new GridLayout()); 

    frame.add(p); 
    add(frame); 

    frame.setTitle("Fan"); 
    start.addActionListener(new ActionListener(){ 
    public void actionPerformed(ActionEvent e){ 
    timer.start(); 

    for(int x=strtpt;x<362;x++) 
{if(x==361) 
x=0; 
else   
    arcs.initializex(x); 
    arcs.paintComponent(fan); 
strtpt=x; 
    } 


} 
}); 

     stop.addActionListener(new ActionListener(){ 
public void actionPerformed(ActionEvent e){ 

    lock.lock(); 

    timer.start(); 

} 
}); 

     reverse.addActionListener(new ActionListener(){ 
    public void actionPerformed(ActionEvent e){ 
    timer.start(); 
    for(int x=strtpt;x>-1;x--) 
    {if(x==0) 
    x=360; 

    else 
    arcs.initializex(x); 
     arcs.paintComponent(fan); 
    strtpt=x; 

    } 


     }}); 

      speed.addAdjustmentListener(new AdjustmentListener(){ 
        public void adjustmentValueChanged(AdjustmentEvent ae){ 
         try { 
          switch (thr){ 
            case AdjustmentEvent.UNIT_INCREMENT: 
            Thread.sleep(thr+=2); 
           break; 

            case AdjustmentEvent.UNIT_DECREMENT: 
             Thread.sleep(thr-=2); 
             break; 
              } 
          int value = ae.getValue(); 
         } catch (InterruptedException ex) { 
          Logger.getLogger(Ass3_10203038.class.getName()).log(Level.SEVERE, null, ex); 
         } 
        } 

      }); 

    } 
    /** 
    * Main method 
    */ 
    public static void main(String[] args) { 
    Ass3_10203038 window = new Ass3_10203038(); 

    window.setSize(500, 500); 

    window.setLocation(50, 50); // Center the frame 
    // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setVisible(true); 

    } 
    } 

// The class for drawing arcs on a panel 
    class ArcsPanel extends JPanel { 
    // Draw four blades of a fan 

    public int initializex(int x){ 

    return x; 
    } 

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

    int xCenter = getWidth()/2; 
    int yCenter = getHeight()/2; 
    int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4); 


    int x = xCenter - radius; 
    int y = yCenter - radius; 

    { 
     g.fillArc(x, y, 2 * radius, 2 * radius, 0+initializex(x), 30); 
     g.fillArc(x, y, 2 * radius, 2 * radius, 90+initializex(x), 30); 
     g.fillArc(x, y, 2 * radius, 2 * radius, 180+initializex(x), 30); 
     g.fillArc(x, y, 2 * radius, 2 * radius, 270+initializex(x), 30); 

    } 

    } 
    } 

回答

1

這個代碼有很多問題,我不會試圖解決所有問題。但是,我會列出我注意到的並描述發生了什麼問題。

首先,你的代碼崩潰與一個例外:

java.lang.IllegalArgumentException: adding a window to a container 

這發生在Ass3_10203038構造,在那裏你嘗試將JFrame添加到新Ass3_10203038實例(這是一個JApplet,從而容器)。由於JFrame僅包含JPanel,因此可以通過將JPanel直接添加到Ass3_10203038實例來解決此問題。這將至少顯示您的用戶界面作爲Applet運行時。

接下來,單擊一個按鈕將生成一個NullPointerException。發生這種情況是因爲您直接調用paintComponent,並將fan作爲Graphics參數傳遞 - 但您永遠不會將fan初始化爲代碼中的任何內容,因此它始終爲空。作爲一種解決方案,您不應該直接撥打paintComponent,因爲您沒有 a Graphics可用於在屏幕上繪製的對象。 Swing的系統有這個對象,雖然如此,我們就可以要求它重新繪製,而不是直接調用paintComponent

arcs.repaint(); 

現在程序進入一個按鈕的按下一個無限循環,但。什麼情況是,這個循環永遠不會結束:

for (int x = strtpt; x < 362; x++) 
{ 
    if (x == 361) 
     x = 0; 
    else 
     arcs.initializex(x); 
    arcs.repaint(); 
    strtpt = x; 
} 

它始終保持循環,因爲X從未達到362既然你想風扇持續旋轉,使得有種感覺,但因爲你正在運行這個循環上UI線程,它會凍結整個窗口。除此之外,風扇將迅速旋轉真的,因爲在這個循環中沒有時間 - 它會像計算機一樣快速地運行,這確實非常快。

顯然,你試圖通過涉及Threadtimer來解決這個問題:

timer.start(); 

然而,由於timer僅僅是一個空白Thread對象這一行絕對沒有(至少,沒有任何重要的你程序)。爲了在線程中運行代碼,您必須擴展Thread並覆蓋run方法,或將Runnable傳遞給Thread的構造函數。不過,我不認爲原始的Thread會讓我們在這裏任何地方,因爲他們仍然沒有真正解決時間問題。我建議你看看javax.swing.Timer

儘管如此,您的風扇葉片仍然不動。這是因爲你的方法從來沒有將任何角度看作輸入。它看起來像你試圖通過調用initializex(x)在上面顯示的循環中和在paintComponent方法中傳遞一個角度,但initializex除了返回它的參數之外不會做任何事情 - 無論您傳入什麼,都會立即返回。所以在paintComponent方法中,initializex(x)只是返回x的值。這意味着,而不是你的代碼:

g.fillArc(x, y, 2 * radius, 2 * radius, 0 + initializex(x), 30); 

你也可以同樣有書面

g.fillArc(x, y, 2 * radius, 2 * radius, 0 + x, 30); 

完全一樣的效果。

我希望這解釋了一些出錯的事情。

0

我固定的代碼,但非常感謝你 我只是需要安排在我腦海中的邏輯

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package assign3_10203038; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.Image; 
import java.awt.Rectangle; 
import java.awt.Shape; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.AdjustmentEvent; 
import java.awt.event.AdjustmentListener; 
import java.awt.image.ImageObserver; 
import java.text.AttributedCharacterIterator; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JApplet; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollBar; 

public class Assign3_10203038 extends JFrame { 

private JButton start = new JButton("Start"); 
private JButton stop = new JButton("Stop"); 
private JButton reverse = new JButton("Reverse"); 
private JScrollBar speed = new JScrollBar(); 
private Thread timer; 
private final ArcsPanel arcs; 

public Assign3_10203038() { 
    arcs = new ArcsPanel(); 

    JPanel p = new JPanel(); 
    p.setSize(5000, 5000); 
    p.add(arcs); 
    p.add(start); 
    p.add(stop); 
    p.add(reverse); 
    p.add(speed); 
    p.setLayout(new GridLayout()); 
    add(p); 

    start.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      timer = new Thread(arcs); 
      timer.start(); 


     } 
    }); 

    speed.addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent ae) { 
      System.out.println(ae.getValue()); 
      arcs.speed(ae.getValue()); 
     } 
    }); 


    reverse.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      arcs.reverse(); 

     } 
    }); 

    stop.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      timer.stop(); 
     } 
    }); 
} 

public static void main(String[] args) { 
    Assign3_10203038 window = new Assign3_10203038(); 

    // (new Thread(window)).start(); 
    window.setSize(500, 500); 

    window.setLocation(50, 50); // Center the frame 
    // window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setVisible(true); 
} 
} 

class ArcsPanel extends JPanel implements Runnable { 
// Draw four blades of a fan 

int thr = 1000; 
int i = -20; 

public void run() { 
    while (true) { 
     starting_x = (starting_x + i) % 360; 
     repaint(); 
     try { 
      Thread.sleep(thr); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(Assign3_10203038.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

public void reverse() { 
    i = -i; 
} 

public void speed(int p) { 
    thr = 1000 - (p += p) * 5; 

} 
int starting_x; 

public void initializex(int x_val) { 
    starting_x = x_val; 
} 

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

    int xCenter = getWidth()/2; 
    int yCenter = getHeight()/2; 
    int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4); 


int x = xCenter - radius; 
int y = yCenter - radius; 

{ 
g.fillArc(x, y, 2 * radius, 2 * radius, 0 + starting_x, 30); 
g.fillArc(x, y, 2 * radius, 2 * radius, 90 + starting_x, 30); 
g.fillArc(x, y, 2 * radius, 2 * radius, 180 + starting_x, 30); 
g.fillArc(x, y, 2 * radius, 2 * radius, 270 + starting_x, 30); 

} 

} 
}