2015-02-17 61 views
1

我在使用Java繪圖時遇到問題。我認爲我的代碼是正確的,但是當我把它放到循環計時器時,它不會打印任何東西。我想每秒重複doDrawing(g)方法。現在它只會打印文本prom system.out但不繪製。使用計時器繪圖不起作用

package src; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Calendar; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class surface extends JPanel{ 

private void doDrawing(Graphics g){ 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.setColor(Color.black); 

    //souradnice stredu ciferniku 
    final int sx = 250; 
    final int sy = 250; 

    // inicializace promennych 
    int uhel = 0; 
    int delka = 150; 
    int xHodina,xMinuta,xSekunda, 
     yHodina,yMinuta,ySekunda; 


    // získání aktuálního času 
    int HOUR = Calendar.getInstance().get(Calendar.HOUR); 
    int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1; 
    int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1 ; 

    //výpočet jednotlivých úhlů pro jednotlivé ručičky a jejich vykreslení 
    xSekunda = (int) ((int) sx + Math.round(Math.sin((6 * SECOND * Math.PI/180)) * delka)); 
    ySekunda = (int) ((int) sy - Math.round(Math.cos((6 * SECOND * Math.PI/180)) * delka)); 


    //vyhreslení ručiček 
    g2d.drawLine(sx, sy, xSekunda, ySekunda); 

    //info    
    System.out.print(" "+(6 * SECOND)+ " "+ HOUR+" "+MINUTE+" "+SECOND+"  "+xSekunda+" "+ySekunda+"\n"); 
    } 

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

    int delay = 1000; //milliseconds 
    //Somewhere there is that problem .. 

     ActionListener taskPerformer = new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
       doDrawing(g); 
      } 
     }; 
     new Timer(delay, taskPerformer).start(); 
} 
} 

問題出在這裏。

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

    int delay = 1000; //milliseconds 
    //Somewhere there is that problem .. 

     ActionListener taskPerformer = new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
       doDrawing(g); 
      } 
     }; 
     new Timer(delay, taskPerformer).start(); 
    } 
} 
+4

,切勿啓動的paintComponent內部的定時器。這種方法僅適用於繪圖和繪圖,沒有任何其他內容。 – 2015-02-17 21:46:40

回答

5

切勿在paintComponent內部啓動Timer。這種方法僅適用於繪圖和繪圖,沒有任何其他內容。

你應該在別處啓動你的計時器,也許在類的構造函數中,並且讓它改變你的類的字段,然後調用repaint()。 paintComponent方法應該使用這些字段來決定在哪裏繪製。

例如,您的doDrawing()方法(不帶Graphics參數)可以創建Line2D,將其添加到List<Line2D>,然後再調用repaint()。然後paintComponent(...)方法,可以通過這個列表繪製每個迭代行:

import java.awt.Color; 
import java.awt.Container; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Line2D; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.List; 

import javax.swing.JPanel; 
import javax.swing.Timer; 

public class surface extends JPanel { 

    private List<Line2D> lineList = new ArrayList<>(); 

    public surface() { 
     int delay = 1000; // milliseconds 
     // Somewhere there is that problem .. 

     ActionListener taskPerformer = new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      doDrawing(); 
     } 
     }; 
     new Timer(delay, taskPerformer).start(); 
    } 

    private void doDrawing() { 

     // souradnice stredu ciferniku 
     final int sx = 250; 
     final int sy = 250; 

     // inicializace promennych 
     int uhel = 0; 
     int delka = 150; 
     int xHodina, xMinuta, xSekunda, yHodina, yMinuta, ySekunda; 

     // získání aktuálního času 
     int HOUR = Calendar.getInstance().get(Calendar.HOUR); 
     int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1; 
     int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1; 

     // výpočet jednotlivých úhlů pro jednotlivé ručičky a jejich vykreslení 
     xSekunda = (int) ((int) sx + Math.round(Math 
      .sin((6 * SECOND * Math.PI/180)) * delka)); 
     ySekunda = (int) ((int) sy - Math.round(Math 
      .cos((6 * SECOND * Math.PI/180)) * delka)); 

     Line2D line = new Line2D.Double(sx, sy, xSekunda, ySekunda); 
     lineList.add(line); 
     repaint(); 

     // info 
     System.out.print(" " + (6 * SECOND) + " " + HOUR + " " + MINUTE + " " 
      + SECOND + "  " + xSekunda + " " + ySekunda + "\n"); 
    } 

    @Override 
    public void paintComponent(final Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.black); 

     for (Line2D line2d : lineList) { 
     g2d.draw(line2d); 
     } 

    } 
} 

編輯我不好,你只是想畫一個這一行代碼,而不是一個行的列表。如果是這樣,擺脫了列表,而是創建一個由你的定時器改變,繪製你的paintComponent一個的Line2D場:

import java.awt.Color; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Line2D; 
import java.awt.geom.Line2D.Double; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

// !! Class names should begin with upper-case letter 
public class Surface extends JPanel { 
    private static final double DELKA = 150; 
    private static final int SX = 250; 
    private static final int SY = SX; 
    private static final int DELAY = 1000; 
    // private List<Line2D> lineList = new ArrayList<>(); 
    private Timer timer = new Timer(DELAY, new TaskPerformer()); 
    private Line2D line; 

    public Surface() { 
     timer.start(); 
    } 

    private void doDrawing() { 
     int xSekunda, ySekunda; 

     int HOUR = Calendar.getInstance().get(Calendar.HOUR); 
     int MINUTE = Calendar.getInstance().get(Calendar.MINUTE) + 1; 
     int SECOND = Calendar.getInstance().get(Calendar.SECOND) + 1; 

     xSekunda = (int) ((int) SX + Math.round(Math 
      .sin((6 * SECOND * Math.PI/180)) * DELKA)); 
     ySekunda = (int) ((int) SY - Math.round(Math 
      .cos((6 * SECOND * Math.PI/180)) * DELKA)); 

     // Line2D line = new Line2D.Double(SX, SY, xSekunda, ySekunda); 
     line = new Line2D.Double(SX, SY, xSekunda, ySekunda); 
     // lineList.add(line); 
     repaint(); 

     // info 
     System.out.print(" " + (6 * SECOND) + " " + HOUR + " " + MINUTE + " " 
      + SECOND + "  " + xSekunda + " " + ySekunda + "\n"); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
     return super.getPreferredSize(); 
     } 
     return new Dimension(2 * SX, 2 * SY); 
    } 

    @Override 
    public void paintComponent(final Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.black); 

     // to give smoother lines 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     // iterate through our list and draw lines it holds 
     if (line != null) { 
     g2d.draw(line); 
     } 

    } 

    private class TaskPerformer implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
     if (!isShowing() && timer != null && timer.isRunning()) { 
      timer.stop(); 
     } else { 
      doDrawing(); 
     } 
     } 
    } 

    private static void createAndShowGui() { 
     Surface mainPanel = new Surface(); 

     JFrame frame = new JFrame("surface"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

Thx非常,你的代碼看起來很聰明!這幫助了我很多:) +1 – Krystofee 2015-02-18 13:10:20