2015-12-15 32 views
0

好的,所以我試圖製作一個笑臉表情程序,當它第一次啓動它應該顯示默認的笑臉(這部分工作,這是很好,我猜)如何從Java中的多個方法中繪製?

但是,那麼它應該給你兩個按鈕從微笑中挑選,皺眉按鈕應該重新繪製臉部以顯示一個微笑或皺眉,但由於某種原因它不起作用。

我一直在閱讀有關的圖形和我知道你不應該從油漆(外界稱他們)方法,因此我適時改變我的代碼,我可以告訴這些按鈕的工作,因爲我讓他們打印出來的東西每次但實際重繪都不起作用。我試過使用repaint()和revalidate()。由於某種原因,如果使用repaint(),每次都會重新繪製越來越多的奇怪圖片,但也許它應該是這樣的?

可有人請看看代碼,讓我知道你在想什麼是問題或者我應該尋找一個解決方案,我用java一段時間,但我從來沒有使用圖形:/我已經閱讀你應該在最後使用setVisible/setSize(或pack()),這實際上幫助我解決了一些問題,但是當你想繪製多個東西時,我不知道該怎麼做。大多數示例只顯示繪製一個東西。

import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 

public class JSmileFacePanel2 extends JFrame { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

JButton smile = new JButton("SMILE"); 
JButton frown = new JButton("FROWN"); 

public JSmileFacePanel2() { 
    setLayout(new FlowLayout()); 
    setTitle("JSmileFace-V2: Jose M. Tobar"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    add(frown); 
    add(smile); 

    setSize(800, 800); 
    setVisible(true); 
} 

public void paint(Graphics g) { 
    super.paint(g); 
    //by default should show smiling 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 

    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      drawSmile(g); 

     } 
    }); 

    frown.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("FROWN BUTTON CLICKED"); 
      drawFrown(g); 
     } 
    }); 
} 

public void drawSmile(Graphics g) { 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 
    repaint(); 
} 

public void drawFrown(Graphics g) { 
    g.setColor(Color.WHITE); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 
    repaint(); 
} 


public static void main(String[] args) { 
    JSmileFacePanel2 js = new JSmileFacePanel2(); 
} 

} 

回答

1

您仍在調用paint方法之外的繪畫方法,因爲actionPerformed方法的方法與paint方法不同。它們在文本上並不重要,它仍然是一種不同的方法。

此外,您反覆添加每次有一個重繪事件,這將下降到停止減緩你的應用程序,它也不會正確重繪時的動作偵聽器。

所以,請檢查您是否微笑或皺眉的paint方法內,並添加構造函數中的動作監聽器。然後

的代碼變爲:

import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 

public class JSmileFacePanel2 extends JFrame { 

    private static final long serialVersionUID = 1L; 

    // by default should show smiling 
    private boolean doSmile = true; 

    JButton smile = new JButton("SMILE"); 
    JButton frown = new JButton("FROWN"); 

    public JSmileFacePanel2() { 
     setLayout(new FlowLayout()); 
     setTitle("JSmileFace-V2: Jose M. Tobar"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     add(frown); 
     add(smile); 

     smile.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("SMILE BUTTON CLICKED"); 
       doSmile = true; 
       repaint(); 
      } 
     }); 

     frown.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("FROWN BUTTON CLICKED"); 
       doSmile = false; 
       repaint(); 
      } 
     }); 

     setSize(800, 800); 
     setVisible(true); 
    } 

    public void paint(final Graphics g) { 
     super.paint(g); 

     if (doSmile) { 
      drawSmile(g); 
     } else { 
      drawFrown(g); 
     } 
    } 

    public void drawSmile(Graphics g) { 
     g.setColor(Color.YELLOW); 
     g.fillOval(200, 200, 500, 500); 
     g.setColor(Color.BLUE); 
     g.fillOval(300, 360, 50, 50); 
     g.setColor(Color.BLUE); 
     g.fillOval(600, 360, 50, 50); 
     g.drawArc(400, 400, 100, 40, 180, 185); 
    } 

    public void drawFrown(Graphics g) { 
     g.setColor(Color.WHITE); 
     g.fillOval(200, 200, 500, 500); 
     g.setColor(Color.BLUE); 
     g.fillOval(300, 360, 50, 50); 
     g.setColor(Color.BLUE); 
     g.fillOval(600, 360, 50, 50); 
     g.drawArc(400, 400, 100, 40, 180, 185); 
    } 

    public static void main(String[] args) { 
     JSmileFacePanel2 js = new JSmileFacePanel2(); 
    } 

} 
0

主要問題:你加入了很多在你的代碼actionlisters的...

...每當repaint()被調用時,它調用內部的paint(Graphics g)方法和您的油漆方法內你」重(一遍又一遍又一遍,只要你重繪)添加的ActionListener

嘗試在構造函數中添加的ActionListener:

public JSmileFacePanel2() { 
    setLayout(new FlowLayout()); 
    setTitle("JSmileFace-V2: Jose M. Tobar"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    add(frown); 
    add(smile); 

    setSize(800, 800); 
    setVisible(true); 


    //here: 
    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      drawSmile(g); 

     } 
    }); 

    frown.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("FROWN BUTTON CLICKED"); 
      drawFrown(g); 
     } 
    }); 

} 
1

總之,沒有。但是,你仍然在正確的軌道上。

請記住,您正在事件驅動的環境中運行,這意味着發生了一些事情,然後您對此做出響應。

繪畫應該什麼都不做更多的則只是油漆的當前狀態,在你的榜樣,每次paint被調用時,您要添加新的ActionListener的按鈕,這樣你就可以用連接到每個3+ ActionListener s結尾了只有當屏幕變得可見時,纔會產生嚴重的奇怪行爲。

你也不應該直接或間接地從你的paint方法中修改組件的狀態,這可能會導致repaint被調度,這將導致你的paint方法被重複調用,最終會消耗你的CPU週期,至少可以說是凌亂。

您還應該避免從頂級容器延伸並覆蓋paint(通常),而不是使用JPanel並改爲使用paintComponent方法。

這樣做的兩個主要原因,首先,它會將您鎖定爲一個用例,這意味着您無法重新使用您的組件,然後直接將其繪製到頂級容器(如JFrame)可能會讓您在框架的裝飾下繪畫/邊界,並因爲繪畫的工作方式,甚至有幀內容畫在它上面。

Painting in AWT and SwingPerforming Custom Painting更多細節

一般的解決方法是使用一個標誌,以更改您的繪畫過程中的作品,當你需要相應地改變該標誌的方式(從按鈕的ActionListener秒鐘內例如)

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class JSmileFace { 

    private static final long serialVersionUID = 1L; 

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

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

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

    public class SmilyPane extends JPanel { 

     JButton smile = new JButton("SMILE"); 
     JButton frown = new JButton("FROWN"); 

     private boolean frowning = false; 

     public SmilyPane() { 
      setLayout(new FlowLayout()); 

      add(frown); 
      add(smile); 

      smile.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        frowning = false; 
        repaint(); 
       } 
      }); 

      frown.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("FROWN BUTTON CLICKED"); 
        frowning = true; 
        repaint(); 
       } 
      }); 
     } 

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

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.YELLOW); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 

      if (frowning) { 
       drawFrown(g); 
      } else { 
       drawSmile(g); 
      } 
     } 

     public void drawSmile(Graphics g) { 
      g.setColor(Color.YELLOW); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 
     } 

     public void drawFrown(Graphics g) { 
      g.setColor(Color.WHITE); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 
     } 

    } 

} 
0

一個小小的瑕疵: 不叫裏面drawFrown(g)drawSmile(g)actionListener(你不能了,你不知道graphics了),而不是調用repaint()

但你repaint()告訴你之前,你的圖形什麼將(我使用這一個int,更好的使用Enums但它會爲現在工作中得出

我只是做smile-一部分,皺眉部分是相同的

private int style = 0; 

public JSmileFacePanel2() { 

    //other code as above 
    ... 

    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      style = 1; //1=smile, 2=frown 
      repaint(); //this calls internally the paint(g) method 
     } 
    }); 
} 

和調整你的paint方法:

public void paint(Graphics g) { 
    super.paint(g); 
    //by default should show smiling 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 

    if(style == 1){ 
     drawSmile(g); 
    } 

    if(style == 2){ 
     drawFrown(g); 
    } 
}