2013-02-28 62 views
0

我正在爲我製作的音樂應用程序製作一個跟蹤欄。基本上它是一個Rectangle2D,它將Horizo​​ntaly移動到一個JPanel擴展類'TrackBar'中,ActionListener在另一個類'TrackBarAction'中,它由'TrackBar'類中的Timer移動,這次是在'Toolbar'類PLay和Pause按鈕在哪裏。不能從不同課程開始動畫到另一個

  • 我遇到的問題是它不動。我添加了調試打印到控制檯,看它是否正在讀取代碼,它是,除了由於某種原因不重繪(),所以它讀取的代碼,但不repaint()。

這裏是簡化的代碼:

public class Toolbar extends JPanel implements ActionListener { 

public static boolean IS_PLAYING = false; 

public Toolbar(){ 

     (...) 

      pauseicon = new ImageIcon(getClass().getResource("Icons/Pause.png"));  
      playicon = new ImageIcon(getClass().getResource("Icons/Play.png")); 
      play = new JToggleButton(new ImageIcon(playicon.getImage().getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH)), false);    
     play.setOpaque(false); 
     play.setContentAreaFilled(false); 
     play.setBorderPainted(false); 
     play.addItemListener (new ItemListener() { 

       @Override 
       public void itemStateChanged(ItemEvent e) { 
        if(play.isSelected()){ 
         play.setIcon((Icon)new ImageIcon(pauseicon.getImage().getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH))); 
         IS_PLAYING = true; 
         MainFrame.tb.t.start();  // THIS is where timer is called 
        } else { 
         play.setIcon((Icon)new ImageIcon(playicon.getImage().getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH))); 
         IS_PLAYING = false; 
         MainFrame.tb.t.stop(); 
        } 
       }}); 


     (...) 

} // end of constructor 

} // end of class 

下一個類是的TrackBar類:

public class TrackBar extends JPanel{ 

private TrackBarAction tba = new TrackBarAction(this); 
public static int TIME = 8; 

public Timer t = new Timer(TIME, tba); 
public static double x = 0, y = 0, velX = 0.5, velY = 0; 


@Override 
public void paintComponent(Graphics g){ 

    System.out.println("1"); // debug 

      super.paintComponent(g); 

      Graphics2D g2d = (Graphics2D)g; 
      //g2d.drawRect((int)x, (int)y, 10, 800); 

      Rectangle2D r2d = new Rectangle2D.Double(x, y, 10.0, 800.0); // x,x, w, h 
      g2d.setPaint(Color.DARK_GRAY); 
      g2d.fill(r2d); 
      g2d.draw(r2d); 

      System.out.println("2"); // debug 
} 

} 

下一個類是TrackBarAction其具有動作偵聽器:

public class TrackBarAction implements ActionListener{ 

private TrackBar tb; 

public TrackBarAction(TrackBar tb){ 

    this.tb = tb; 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    System.out.println("3"); 

    // When it gets to the end, return to start point 
     if(tb.x == 1024){ 
      tb.x = 0; 
      tb.y = 0; 
     } 

     tb.x += tb.velX; 
     tb.y += tb.velY; 
     tb.repaint(); 
     System.out.println("4"); 
} 

} 

這是主框架:

public class MainFrame extends JFrame { 

public static ColourToolbar colourBar; 

public static TrackBar tb; 

public MainFrame(){ 

    super("VIPE by Prestige WorldWide"); 

    // Top colour toolbar for tones 
    colourBar = new ColourToolbar(); 
    this.getContentPane().add(colourBar, BorderLayout.NORTH); 

    // The center where the drawing is done 
    ImagePanel bg = new ImagePanel(); 
     bg.setLayout(new BorderLayout()); 
     Dimension size = getPreferredSize(); 
     size.setSize(1024,800); //w, h 
     bg.setPreferredSize(size); 
    this.getContentPane().add(bg, BorderLayout.CENTER); 

    tb = new TrackBar(); 
    bg.add(tb, BorderLayout.CENTER); 

    //DrawBoard dboard = new DrawBoard(); 
    //bg.add(dboard, BorderLayout.CENTER); 

    //Image bgimage = (new ImageIcon(getClass().getResource("Icons/background.jpg"))).getImage(); 
    //JPanel bg = new JPanelWithBackground(bgimage); 
    //this.getContentPane().add(bg, BorderLayout.CENTER); 


    // The control toolbar where the settings and control buttons are. 
    Toolbar toolBar = new Toolbar(); 
    this.getContentPane().add(toolBar, BorderLayout.SOUTH); 
} 

public static void main(String[] args){ 

    MainFrame frame = new MainFrame(); 

    frame.setBackground(Color.WHITE); 
    frame.setSize(1024,768); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setResizable(false); 
    //frame.pack(); 
    frame.setVisible(true); 

} 

} 
+0

我不認爲'TrackBarAction'應該從'TrackBar'擴展,因爲它不是引用當前在屏幕上的組件。相反,將'TrackBar'的引用傳遞給'TrackBarAction',以便直接在其上執行操作。我可能是錯的,但沒有足夠的代碼可以確定 – MadProgrammer 2013-02-28 22:45:10

+0

我發送了'TrackBar'的引用到'TrackBarAction'(更新了代碼),但我還沒有得到結果 – nullwriter 2013-02-28 22:55:59

+0

您現在需要翻譯x/y值到'TrackBar',在你的'actionPerformed'方法中,你不需要'x','y','velX'和'velY'值,因爲這些值應該來自被設置爲'TrackBar' 。你還應該在'TrackBar'實例上調用'repaint'。靜態變量的使用會讓你的生活變得非常困難,並且爲了你的使用目的,我會避免它們,並依靠「TrackBar」的實例來管理它們。 – MadProgrammer 2013-02-28 23:17:08

回答

2

正如MadProgrammer指出的那樣,你擁有的複雜的繼承結構是不必要的。

什麼是打破您的發佈的代碼是您的計時器正在操縱第二個屏幕外TrackBar的繪圖座標。由於TrackBarAction是通過繼承TrackBar的,所以代碼在各種動畫變量都存在的情況下編譯得很好。但是,它們屬於未渲染的TrackBar,而不是您實際使用的原始TrackBar實例。

public class TrackBarAction implements ActionListener 
{ 

private TrackBar tb; 

public TrackBarAction(TrackBar tb) 
{ 

    this.tb = tb; 
} 

@Override 
public void actionPerformed(ActionEvent e) 
{ 
    System.out.println("3"); 

    // When it gets to the end, return to start point 
    if (tb.x == 1024) { 
    tb.x = 0; 
    tb.y = 0; 
    } 

    tb.x += tb.velX; 
    tb.y += tb.velY; 
    tb.repaint(); 
    System.out.println("4"); 
} 

} 

編輯:這是你更新的TrackBarAction應該看起來像什麼。你在概念上錯誤的是,你的版本的TrackBarAction的原始實例變量是按值傳遞而不是按對象傳遞的。所以,你正在操作你的版本中的錯誤變量。

+0

我明白你的意思了,我迷惑了自己並更新了代碼,調試打印仍然在打印,Trackbar完全沒有移動=/ – nullwriter 2013-02-28 23:16:28

+0

你正在通過TrackBar的錯誤實例。請注意,在對您的TrackBarAction構造函數的調用中,您將創建一個TrackBar的匿名新實例。所以,你最終會更新這個未使用的,未渲染的TrackBar的座標。你想傳遞一個引用到最終在GUI中的引用。對此的快速解決方案是刪除Timer變量前面的static關鍵字,並將「this」傳遞給TrackBarAction構造函數。 – Creakazoid 2013-02-28 23:21:41

+0

好吧,我感到困惑,因爲我不認爲我可以從'MainFrame'調用'TrackBar',因此我可以訪問它,但事實上我可以,現在我可以從'TrackBar中取出靜態變量'班。所以它工作!我已經更新了參考代碼!非常感謝! – nullwriter 2013-02-28 23:26:58

1

private static TrackBarAction tba = new TrackBarAction(new TrackBar());

TrackBar tb = new TrackBar(); 
bg.add(tb, BorderLayout.CENTER); 

一些問題。 TrackBarAction具有的參考不再是屏幕上的參考。

以這種方式使用靜態變量是壞的設計有問題......

public class TrackBar extends JPanel{ 

    private TrackBarAction tba; 
    private int TIME = 8; 

    private Timer t = new Timer(TIME, tba); 
    private double x = 0, y = 0, velX = 0.5, velY = 0; 

    public TrackBar() { 
     tba = = new TrackBarAction(this); 
    } 

    @Override 
    public void paintComponent(Graphics g){ 
     System.out.println("1"); // debug 

     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D)g; 
     //g2d.drawRect((int)x, (int)y, 10, 800); 

     Rectangle2D r2d = new Rectangle2D.Double(x, y, 10.0, 800.0); // x,x, w, h 
     g2d.setPaint(Color.DARK_GRAY); 
     g2d.fill(r2d); 
     g2d.draw(r2d); 

     System.out.println("2"); // debug 
    } 
} 

然後每個需要與TrackBar互動類應該得到相同的實例(實例的,他們需要與工作)

+0

是!感謝您的投入,您和Creakazoid啓發了我並找到了解決方案。從'TrackBar'中取出靜態變量,將'MainFrame'中'TrackBar'的對象變成一個靜態變量,並從那裏啓動計時器,它就起作用了!謝謝 :) – nullwriter 2013-02-28 23:30:41

相關問題