簡體   English   中英

在Swing / AWT GUI中移動正弦曲線

[英]Moving sine curve in Swing/AWT GUI

我使用雙向鏈表來創建此移動的正弦曲線(代碼可能非常原始且雜亂無章,但這只是初稿,我幾乎不知道如何使用Swing。):

import java.awt.*;  
import javax.swing.JFrame;  

public class DisplayGraphics extends Canvas{  

    public void paint(Graphics g) {   

        setForeground(Color.RED);  
        this.setSize(720,440);

        class list {
            int pos;
            list next; 
            list prev;

            list(){
                int pos;
                list next ;
                list prev;
            }

            list(int pos){
                this.pos = pos;
            }

            list(int pos, list next){
                this.pos = pos;
                this.next = next;
            }


            public void setpos(int pos){
                this.pos= pos;
            }

            public void setnext(list next){
                this.next= next;
                next.prev=this;
            }

            public void display(list head){
                list tracker = head;
                int y;
                //displays the sincurve momentarily
                for (int i = 1;i<721; i++){
                    y = (int)(Math.sin(Math.toRadians(tracker.pos))*200)+200;
                    g.fillOval(i,y,3,3);
                    tracker = tracker.next;
                }  
            }
        }

        list temp = new list();
        temp.setpos(1);
        list head = temp;

        for (int i =2; i<720; i++){
            list thing = new list();
            thing.setpos(i);
            temp.setnext(thing);
            temp = thing;

        }
        list tail = new list(720);
        temp.setnext(tail);
        tail.setnext(head);

        //creates the moving display
        boolean run = true;
        while(run==true){
            head.display(head);

            //try {
                //Thread.sleep(10);

            //} catch(InterruptedException ex) {
               // Thread.currentThread().interrupt();
            //}
            g.clearRect(0, 0, getWidth(), getHeight());
            head = head.next ;  
       }
    }

    public static void main(String[] args) {  
        DisplayGraphics m=new DisplayGraphics(); 

        JFrame f=new JFrame();  
        f.add(m);  
        f.setSize(720,400);  
        //f.setLayout(null);  
        f.setVisible(true);  
    }      
}  

但是,該程序運行得不太順利。 有什么建議可以使其運行更快,更流暢嗎?

好的,有一些缺陷必須糾正^^

1)通過線程觸發繪畫

//set isRunning=false to stop repaint
private boolean isRunning = true;
private void startUpdateThread(){
    Runnable r = new Runnable() {
        public void run() {

            while(isRunning){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //repaint calls the paint(Graphics g)-method
            repaint();
            }
        }
    };

    Thread t = new Thread(r);
    t.setDaemon(true);
    t.start();
}

2)不要使事情變得復雜:只需在繪制^^時計算f(x)= y
3)只做必須做的事情:不要在每次繪畫時都設置大小

private int xCount = 0;
public void paint(Graphics g) {

    //setSize(...)

    xCount = xCount + 1;
    for (int dx = 1; dx < 721; dx++) {

        int x = (xCount%721)+dx;
        int y = (int) (Math.sin(Math.toRadians(x)) * 200) + 200;
        g.fillOval(dx, y, 3, 3);
    }
}

還剩什么? 您的設置^^

public static void main(String[] args) {
    DisplayGraphic m = new DisplayGraphic();
    m.startUpdateThread();
    m.setSize(720, 440);

    JFrame f = new JFrame();
    f.add(m);
    f.setSize(720, 400);
    f.setVisible(true);
}

您可能想看看緩沖...如果您不喜歡這樣做,只需使用JPanel而不是Canvas(您將不得不覆蓋paintComponent(Graphics g)而不是paint(Graphics g)

public class DisplayGraphic extends JPanel {

    private int xCount = 0;
    public void paintComponent(Graphics g) {        
        super.paintComponent(g);
        //...
        //same as paint in above
        }
    }
}
public class DisplayGraphics extends Canvas{

不要混合使用Swing和AWT。 默認情況下,Swing組件(任何為JComponent )都是雙緩沖的。 這有助於避免渲染混亂。

public void paint(Graphics g) { 
    setForeground(Color.RED);

每當我們重寫任何paint方法時,都應立即調用super方法以刪除原始圖形。 但是對於Swing,我們將重寫paintComponent(Graphics)而不是paint(Graphics)

設置前景色應在構造函數中完成一次,然后再單獨設置。 再次調用它會觸發繪畫!

this.setSize(720,440);

這是另一件事,將觸發重新粉刷!

此外,最好是覆蓋的大小getPreferredSize()方法和pack()包含它..任何信息,網站,書你已經用頂層窗口,找到一個新的&比較好版本。 此代碼在許多重要部分中都顯示了不良做法。

有什么建議可以使其運行更快,更流暢嗎?

使用Swing組件(例如JPanel )代替Canvas 進行更改並覆蓋上述方法。 創建一個Swing Timer ,在循環部分中調用repaint()

有關更好的學習資源,請參見執行自定義繪畫如何使用擺動計時器

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM