1. 程式人生 > >Java:Java2D高階繪圖

Java:Java2D高階繪圖

知識要點: 

第一節  Java 2D的增強功能 

概述、AWT圖形能力的不足、Java 2D API 

第二節  圖形繪製的基本方法 

轉換Graphics2D物件、Graphics 類特性、繪圖的屬性和基本程式設計方法 

第三節  曲線問題的高階應用開發 

直線問題深入研究、貝塞爾(Bezier)曲線、自定義樣條曲線程式設計、 

使用者資料的曲線顯示、曲線用Applet顯示的資料來源問題 

第四節  字串的高階處理 

TextLayout類、LineMetrics類 

第五節  構造幾何形狀 

2D幾何形狀的設計、構造型區域幾何形狀、變換、緩衝的影象 

第六節  三維圖形處理的設計技術 

透視投影、透檢視形的顯示、隱蔽面消除問題 

第七節  同環境互動 

GraphicsEnvironment類、GraphicsDevice類、GraphicsConfiguration類 













































第一節  Java 2D的增強功能 



一、概述: 



由Sun公司與Adobe系統公司合作推出的Java 2D API,提供了一個功能強大而且非常靈活的二維圖形框架。Java 2D API擴充套件了java.awt包中定義的Graphics類和Image類,提供了高效能的二維圖形、影象和文字,同時又維持了對現有AWT應用的相容。 



二、AWT圖形能力的不足: 



在 AWT 的初始實現中,圖形能力並不十分完善。因為開發 JDK 是打算將其作為平臺中立的實現平臺,所以其原始的功能被限制於“最少公共功能”上,所有被支援的作業系統上保證提供這些公共功能; 

在 Java 2D 出現之前,對繪製能力、字型操作和影象控制的支援非常少。而對諸如用圖案進行著色、形狀操作以及圖形變換之類的重要操作的支援則完全沒有。 

Java 2D 滿足了跨平臺實現中對這些功能以及其它功能的需求。 



三、Java 2D API: 



它是JFC (Java Fundation Classes)的一員,加強了傳統AWT( Abstract Windowing Toolkit )的描繪功能。在 JDK1.2中已經支援 Java 2D的使用。透過Java 2D API ,程式設計師可以輕鬆地描繪出任意的幾何圖形、運用不同的填色效果、對圖形做旋轉( rotate)、縮放( scale)、扭曲( shear)等。如圖所示,程式設計師透過2D API所提供的功能,簡單地利用不同型別的線或是填色效果繪出統計圖,以區分出不同的資料。 

它們是基於Graphics2D類的繪圖功能,是對AWT中的Graphics類的進一步的擴充套件和增強。主要體現在: 



1。對渲染質量的控制:消除鋸齒以平滑繪製物件的邊緣 

2.裁剪、合成和透明度:它們允許使用任意形狀來限定繪製操作的邊界。它們還提供對圖形進行分層以及控制透明度和不透明度的能力。 

3.控制和填充簡單及複雜的形狀:這種功能提供了一個 Stroke 代理和一個 Paint 代理,前者定義用來繪製形狀輪廓的筆(定義繪製的筆的寬度和樣式),後者允許用純色、漸變色和圖案來填充形狀。 

4。影象處理和變換:Java 2D 同 Java 高階影象API(Java Advanced Imaging API (JAI))協作,支援用大量圖形格式處理複雜的影象。Java2D 還為您提供了修改影象、形狀和字型字元的變換能力。 

5。特殊的填充方式,如梯度或者圖案 

6.高階字型處理和字串格式化:允許象操作任何其它圖形形狀一樣操作字型字元。除此以外,可以象文書處理程式一樣,通過為 String 中的字元應用屬性和樣式資訊來建立格式化文字。 




java.awt.geom 包中的Areas類支援聯集( union)、交集( intersection)、差集(subtraction )、Exclusive OR (XOR)等布林運算。最後, AffineTransform 類別則提供圖形物件做Scale(比例)、Shear(剪裁)、Rotate(旋轉)等座標上的轉換。 










第二節  圖形繪製的基本方法 



一、轉換Graphics2D物件 

   

繪製圖形時,可以在Graphics物件或者Graphics2D物件上進行,它們都代表了需要繪圖的區域,選擇那個取決於是否要使用所增加的Java2D的圖形功能。但要注意的是,所有的Java2D圖形操作都必須在Graphics2D物件上呼叫。Graphics2D是Graphics的子類,同樣包含在java.awt包中。 

public void paintComponent(Graphics comp) 

{     Graphics2D comp2D=(Graphics2D)comp; 



或者 

public void paint (Graphics comp) 

{     Graphics2D comp2D=(Graphics2D)comp; 







二、Graphics 類特性 



Graphics 類支援幾種確定圖形環境狀態的特性。以下列出了部分特性: 

1)Color:當前繪製顏色,它屬於 java.awt.Color 型別。所有的繪製、著色和純文字輸出都將以指定的顏色顯示。 

2)Font:當前字型,它屬於 java.awt.Font 型別。它是將用於所有純文字輸出的字型。 

3)Clip:java.awt.Shape 型別的物件,它充當用來定義幾何形狀的介面。該特性包含的形狀定義了圖形環境的區域,繪製將作用於該區域。通常情況下,這一形狀與整個圖形環境相同,但也並不一定如此。 

4)ClipBounds:java.awt.Rectangle 物件,它表示將包圍由 Clip 特性定義的 Shape 的最小矩形。它是隻讀特性。 

5)FontMetrics:java.awt.FontMetrics 型別的只讀特性。該物件含有關於圖形環境中當前起作用的 Font 的資訊。如同我們將看到的那樣,獲取此資訊的這種機制已被 LineMetrics 類所取代 

6)Paint Mode:該特性控制環境使用當前顏色的方式。如果呼叫了 setPaintMode() 方法,那麼所有繪製操作都將使用當前顏色。如果呼叫了 setXORMode() 方法(該方法獲取一個 Color 型別的引數),那麼就用指定的顏色對畫素做“XOR”操作。XOR 具有在重新繪製時恢復初始位模式的特性,因此它被用作橡皮擦除和動畫操作。 



三、繪圖的屬性和基本程式設計方法 



1)顏色Color類:沒有變化。 

2)填充方式: 



Paint(油漆桶)介面有幾個具體的實現,它們允許用純色、漸變色或圖案來填充形狀。 



1,純色填充(Color類):對 java.awt.Color 類做了一些調整以實現 Paint,並且可以用於純色填充。 

2,漸變色來填充(梯度填充GradientPaint類):java.awt.GradientPaint 類允許用線性顏色漸變色來填充形狀,線性顏色漸變色允許在兩個指定的 Color 物件之間建立過渡。可以將漸變色設定成“週期性的”,這將導致漸變色圖案重複出現。 

3,圖案填充(紋理TexturePaint類):提供了 java.awt.TexturePaint 類,它可以用由 BufferedImage描述的圖案填充形狀 

程式設計方法: 

使用Graphics2D類中的setPaint()方法並使用Paint物件作為其引數,但由於任何可以作為填充的類如GradientPaint、TexturePaint和Color都實現了Paint介面(該介面注意定義了在Graphics2D下的顏色填充方式),因此可以將它們作為引數。如: 

public void paintComponent(Graphics comp) 

{     Graphics2D comp2D=(Graphics2D)comp; 

GradientPaint pat=newGradientPaint(0f,0f,Color.white,100f,45f,Color.blue); 

comp2D.setPaint(pat); 





3)設定筆的形狀: 



Stroke 介面由 java.awt.BasicStroke 類實現。該類允許進行大量的選擇以修改線的繪製細節。可以程式設計指定 BasicStroke 寬度,也可以指定對名為柱頭和交點的路徑上端點和交點的“裝飾”。現在也可以繪製點劃線了,只須設定 BasicStroke 的破折號屬性即可。 

在Graphics類中線條是一個點寬,而在Graphics2D中可以通過BasicStoke類中的setStroke()方法來設定。其建構函式是BasicStroke(float width, int cap, int join) 

其中width指示線寬(預設時為1.0) 

cap指示線的末端(包頭,在BasicStroke類中定義出三個static 型別的常量如CAP_BUTT沒有包頭()、CAP_ROUND圓包頭()、CAP_SQUARE方包頭()的樣式 



join指示線段之間的拐角(在BasicStroke類中定義出三個static 型別的常量如JOIN_BEVEL()、JOIN_MITER()、   JOIN_ROUND()樣式。 



4)程式設計方法: 



public void paintComponent(Graphics comp) 

{     Graphics2D comp2D=(Graphics2D)comp; 



BasicStroke pen 

=new BasicStroke(2.0f, BasicStroke .CAP_BUTT, BasicStroke .JOIN_ROUND); 

comp2D.setStroke (pen); 





程式碼示例: 



       float thick =0.5f;         //設定畫刷的粗細為0.5 

BufferedImage bi = new BufferedImage(800, 600,BufferedImage.TYPE_INT_RGB); 

Graphics2D g = (Graphics2D)bi.getGraphics(); 

Stroke stroke =g.getStroke();            //得到當前的畫刷 

g.setStroke(new BasicStroke(thick, BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND)); 

g.draw(new Line2D.Float(x1, y1, x2, y2)); 畫線 

g.setStroke( stroke ); //將畫刷復原 





5)建立要繪製的形狀物件 

   

在Java2D中進行繪圖時,不是採用對應的方法來實現,而是為要實現某中形狀創建出相應的形狀物件。這可以通過使用java.awt.geom包中的類來定義所要建立的形狀。如線條Line2D.Float類、距形Rectangle2D.Float或者Rectangle2D.Double類、橢圓Ellipes2D.Float、圓弧Arc2D.Float類等。 



6)繪製物件: 



1,可以使用Graphics2D類中的方法draw()用於繪製輪廓,而fill()方法用於填充。它們都以前面所建立的圖形物件作為引數。 

2,Java2D中的字串的繪製仍然採用drawString()方法,但有drawString(String s, float x, float y)和drawString(Stringstr, int x, int y)。 

3,繪製輪廓:draw(Shape s)其中的Shape介面在Graphics2D中被定義 

新的 Java 2D Shape 類都有“2D”字尾。這些新的形狀使用浮點值(而不是整數)來描述其幾何形狀。 

Polygon類(int[] xpoints, int[] ypoints, int npoints) 

RectangularShape(抽象類,其子類有Arc2D, Ellipse2D, Rectangle2D, RoundRectangle2D), Rectangle(距形) 

QuadCurve2D(二次貝塞爾樣條曲線,貝塞爾曲線由兩個端點以及一個或兩個控制點指定。貝塞爾曲線建立了適合於大多數表示的曲線。) 

CubicCurve2D(三次貝塞爾樣條曲線) 

Area(區域) 

GeneralPath(由直線、二次樣條曲線、三次樣條曲線所構成) 

Line2D 



8)基本步驟 



繪圖的第一個步驟是產生 Graphics2D 物件。然後設定所要的狀態屬性。例如你想要對一物件做漸層式的填色,可以設定屬性 Paint為 GradientPaint。最後再呼叫Graphics2D所提供的方法fill或是draw,完成整個繪圖的程式。 


9)程式例項 



例一: 

這是一個最簡單的例子,也可以認為是繪圖的一個最簡單的框架。 



import java.awt.*; 

import java.awt.event.*; 

import javax.swing.*; 

import java.awt.geom.*; 

public class Map extends JFrame 

{   public Map() 

       {  super("Map"); 

         setSize(350,350); 

         MapPane map=newMapPane(); 

        getContentPane().add(map); 

       } 

       public static void main(String []arg) 

       {  Map frame=new Map(); 

          frame.show(); 

       } 



class MapPane extends JPanel 

{   public void paintComponent(Graphics comp) 

    {     Graphics2Dcomp2D=(Graphics2D)comp; 

      comp2D.drawString("sbcd",200,200); 

             Line2D.Float line=new Line2D.Float(1.0f,2.0f,200.0f,200.0f); 

       comp2D.draw(line); 

    } 









例二: 

下面是在Graphics2D模式下的基本繪圖框架。我們可以看到,利用: 

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 

                         RenderingHints.VALUE_ANTIALIAS_ON); 

通過該方法的設定,使圖形去除鋸齒狀,可以得到多麼細膩的圖形。 



樣例: 



import java.awt.*; 

import java.awt.event.*; 

import java.awt.geom.*; 



public class DrawDemo extends JFrame { 



  public DrawDemo(){ 

    //設定視窗的大小、標題 

    this.setSize(new Dimension(600, 400)); 

    

    //建立繪製各種形狀的容器 

    ShapesPanel shapesPanel = new ShapesPanel(); 

    //將該容器加入視窗 

    getContentPane().add(shapesPanel,BorderLayout.CENTER); 

  } 



  public static void main(String[] args) { 

    DrawDemo frame = new DrawDemo(); 

    frame.setVisible(true); 

    //當視窗關閉時清空記憶體 

    frame.addWindowListener(new WindowAdapter() { 

        public voidwindowClosing(WindowEvent e) { 

           System.exit(0); 

        } 

    }); 

  } 





//建立各種容器的類 

class ShapesPanel extends JPanel { 

    final int maxCharHeight = 15; 

    final Color bg = Color.white; //宣告背景顏色為灰色 

    final Color fg = Color.blue;     //宣告前景顏色為藍色 



    public ShapesPanel() { 

       setBackground(bg);           //設定背景顏色 

       setForeground(fg);           //設定前景顏色 

        //建立組合邊框 

       setBorder(BorderFactory.createCompoundBorder( 

               BorderFactory.createRaisedBevelBorder(), 

               BorderFactory.createLoweredBevelBorder())); 

    } 





    public void paintComponent(Graphics g1) { 

       super.paintComponent(g1);      //清空背景顏色 





         float thick =0.5f;              //設定畫刷的粗細為 0.5 

         Graphics2D g =(Graphics2D)g1; 

         Stroke stroke =g.getStroke();           //得到當前的畫刷 

         g.setStroke(newBasicStroke(thick, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND)); 

         

         //通過該方法使圖形去除鋸齒狀 

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 

                         RenderingHints.VALUE_ANTIALIAS_ON); 

        

         

         String txt= "我的文章"; 

         

         int style=2;//0普通1粗體2斜體3粗斜 

         g.setFont(new Font("宋體", 2,15)); //15為字大小 

         //設定筆刷為黑色 

         g.setPaint(Color.black); 

         

         g.drawString(txt,200,150); 

         

         g.setPaint(Color.red); 

         g.draw(newLine2D.Float(0,0,200,150)); //畫線 

         

         g.setPaint(Color.blue); 

         

         g.draw(newRectangle2D.Float(200,150,100,100)); 

         

         g.setStroke(stroke); //將畫刷復原 

         

    } 









    例三:圖形靈活的顯示 

    

在上面的例子中,是使用一個繼承於JPanel的類,覆蓋它的void paintComponent(Graphics g1)事件方法,實現繪圖的,這樣雖然方便,但顯得靈活性不高。 

實際上,通過JPanel物件直接賦值給Graphics2D物件,往往可以使程式具有很大的靈活性。程式可以這樣來寫。 



JPanel contentPane= (JPanel) this.getContentPane(); 

public Graphics2D comp2D=(Graphics2D)contentPane .getGraphics(); 



樣例: 



package myDrawDemo; 



import java.awt.*; 

import java.awt.event.*; 

import javax.swing.*; 

import java.awt.geom.*; 



public class DrawDemo1 extends JFrame 



  public JPanel contentPane; //繪圖視窗 

  public Graphics2D comp2D;    //繪圖物件 

  JPanel jPanel1 = new JPanel();//控制元件容器 

  JButton jButton1 = new JButton(); 

  JButton jButton2 = new JButton(); 





  //建構函式 

  public DrawDemo1() { 

    enableEvents(AWTEvent.WINDOW_EVENT_MASK); 

    try { 

      jbInit(); 

    } 

    catch(Exception e) { 

      e.printStackTrace(); 

    } 

  } 



  //控制元件的初始化 



  private void jbInit() throws Exception  { 

    contentPane = (JPanel) this.getContentPane(); 

    contentPane.setLayout(new BorderLayout()); 

    this.setSize(new Dimension(400, 300)); 

    this.setTitle("Frame Title"); 

    //contentPane.setSize(400,240); 

    jPanel1.setLayout(null); 

    jButton1.setBounds(new Rectangle(30, 235, 100, 31)); 

    jButton1.setText("畫線保留"); 



    jButton1.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton1_actionPerformed(e); 

      } 

    }); 



    jButton2.setBounds(new Rectangle(150, 235, 100, 30)); 

    jButton2.setText("畫線刪除"); 

   

    jButton2.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton2_actionPerformed(e); 

      } 

    }); 



     contentPane.add(jPanel1, BorderLayout.CENTER); 

    jPanel1.add(jButton1, null); 

    jPanel1.add(jButton2, null); 

  } 



   public static void main(String[] args) { 

    

    DrawDemo1 frame=new DrawDemo1(); 

    frame.show(); 

    frame.comp2D=(Graphics2D)frame.contentPane.getGraphics(); 

    frame.comp2D.setBackground(Color.white); 

    frame.comp2D.clearRect(0,0,401,221); 





  //Overridden so we can exit when window is closed 

  protected void processWindowEvent(WindowEvent e) { 

    super.processWindowEvent(e); 

    if (e.getID() == WindowEvent.WINDOW_CLOSING) { 

      System.exit(0); 

    } 

  } 



  void jButton1_actionPerformed(ActionEvent e){ 



       comp2D.setPaint(Color.red); 

       Line2D.Float line=new Line2D.Float(1.0f,2.0f,200.0f,220.0f); 

       comp2D.draw(line); 



  } 



  void jButton2_actionPerformed(ActionEvent e) { 

      

    comp2D.clearRect(0,0,401,221); 

    comp2D.setPaint(Color.blue); 

    Line2D.Float line=new Line2D.Float(1.0f,100.0f,300.0f,220.0f); 

    comp2D.draw(line); 

  } 









例四:剪裁 



圖形處理問題中,剪裁由的時候是非常難處理的,所謂剪裁是指超過繪圖取得內容不顯示,看起來這是個簡單問題,但由於所有的線條必須計算與邊界的交點,而且邊界有四個方向,這就使問題變得很複雜。java 2D很好的解決了這個問題,請看下面的例子。 



package myDrawDemo; 



import java.awt.*; 

import java.awt.event.*; 

import javax.swing.*; 

import java.awt.geom.*; 



public class DrawDemo2 extends JFrame 



  public JPanel contentPane; //繪圖視窗 

  public Graphics2D comp2D;    //繪圖物件 

  JPanel jPanel1 = new JPanel();//控制元件容器 

  JButton jButton1 = new JButton(); 

  JButton jButton2 = new JButton(); 





  //建構函式 

  public DrawDemo2() { 

    enableEvents(AWTEvent.WINDOW_EVENT_MASK); 

    try { 

      jbInit(); 

    } 

    catch(Exception e) { 

      e.printStackTrace(); 

    } 

  } 



  //控制元件初始化 



    private void jbInit() throws Exception  { 

    contentPane = (JPanel) this.getContentPane(); 

    contentPane.setLayout(new BorderLayout()); 

    this.setSize(new Dimension(400, 300)); 

    this.setTitle("Frame Title"); 

    //contentPane.setSize(400,240); 

    jPanel1.setLayout(null); 

    jButton1.setBounds(new Rectangle(30, 235, 100, 31)); 

    jButton1.setText("畫線保留"); 



    jButton1.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton1_actionPerformed(e); 

      } 

    }); 



    jButton2.setBounds(new Rectangle(150, 235, 100, 30)); 

    jButton2.setText("畫線刪除"); 

   

    jButton2.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton2_actionPerformed(e); 

      } 

    }); 

   

     contentPane.add(jPanel1, BorderLayout.CENTER); 

    jPanel1.add(jButton1, null); 

    jPanel1.add(jButton2, null); 



  } 



   public static void main(String[] args) { 

    

    DrawDemo2 frame=new DrawDemo2(); 

    frame.show(); 

    frame.comp2D=(Graphics2D)frame.contentPane.getGraphics(); 

    frame.comp2D.setBackground(Color.white); 

    frame.comp2D.clearRect(0,0,401,221); 

   } 



  //Overridden so we can exit when window is closed 

  protected void processWindowEvent(WindowEvent e) { 

    super.processWindowEvent(e); 

    if (e.getID() == WindowEvent.WINDOW_CLOSING) { 

      System.exit(0); 

    } 

  } 



  void jButton1_actionPerformed(ActionEvent e){ 



       comp2D.setPaint(Color.red); 

       Line2D.Float line=newLine2D.Float(1.0f,2.0f,200.0f,220.0f); 





        comp2D.draw(line); 

  } 



  void jButton2_actionPerformed(ActionEvent e) { 

      

    comp2D.clearRect(0,0,401,221); 

    //剪裁 

    comp2D.setClip(50,50,300,150); 

    comp2D.setPaint(Color.blue); 

    Line2D.Float line=newLine2D.Float(1.0f,100.0f,300.0f,220.0f); 

    comp2D.draw(line); 

  } 





  





第三節  曲線問題的高階應用開發 



在jdk尚未支援 2D圖形之前,只可以畫出直的、相同粗細的線條。現在可以通過2D API繪出不同粗細的線條及圓滑的曲線。在java.awt.geom包中提供了Line2D、 QuadCurve2D(二次貝塞爾曲線)及 CubicCurve2D(三次貝塞爾曲線)等相關的類,讓程式設計師能夠輕鬆地繪出想要的線條。 

其實繪圖的核心是畫線,下面通過一些例項對一些問題進行深入的討論。 



    一、直線問題深入研究 



樣例: 

我們通過一個例子,深入的研究一下繪製直線和折線需要掌握哪些內容。 



package myDrawDemo; 



import java.awt.*; 

import java.awt.event.*; 

import javax.swing.*; 

import java.awt.geom.*; 



public class DrawDemo1 extends JFrame 



  public JPanel contentPane; //繪圖視窗 

  public Graphics2D comp2D;    //繪圖物件 

  JPanel jPanel1 = new JPanel();//控制元件容器 

  JButton jButton1 = new JButton(); 

  JButton jButton2 = new JButton(); 

  JButton jButton3 = new JButton(); 



  //建構函式 

  public DrawDemo1() { 

    enableEvents(AWTEvent.WINDOW_EVENT_MASK); 

    try { 

      jbInit(); 

    } 

    catch(Exception e) { 

      e.printStackTrace(); 

    } 

  } 



  //控制元件初始化 

  private void jbInit() throws Exception  { 

    contentPane = (JPanel) this.getContentPane(); 

    contentPane.setLayout(new BorderLayout()); 

    this.setSize(new Dimension(400, 300)); 

    this.setTitle("Frame Title"); 

    //contentPane.setSize(400,240); 

    jPanel1.setLayout(null); 

    jButton1.setBounds(new Rectangle(30, 235, 100, 31)); 

    jButton1.setText("園頭"); 



    jButton1.addActionListener(new java.awt.event.ActionListener(){ 

      public void actionPerformed(ActionEvent e){ 

        jButton1_actionPerformed(e); 

      } 

    }); 



    jButton2.setBounds(new Rectangle(150, 235, 100, 30)); 

    jButton2.setText("方頭"); 

   

    jButton2.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton2_actionPerformed(e); 

      } 

    }); 



   jButton3.setBounds(new Rectangle(270, 235, 100, 30)); 

    jButton3.setText("封閉"); 

   

    jButton3.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton3_actionPerformed(e); 

      } 

    }); 



     contentPane.add(jPanel1, BorderLayout.CENTER); 

    jPanel1.add(jButton1, null); 

    jPanel1.add(jButton2, null); 

    jPanel1.add(jButton3, null); 

  } 



   public static void main(String[] args) { 

    

    DrawDemo1 frame=new DrawDemo1(); 

    frame.show(); 

    frame.comp2D=(Graphics2D)frame.contentPane .getGraphics(); 

    frame.comp2D.setBackground(Color.white); 

    frame.comp2D.clearRect(0,0,401,221); 

   } 



  //Overridden so we can exit when window is closed 

  protected void processWindowEvent(WindowEvent e) { 

    super.processWindowEvent(e); 

    if (e.getID() == WindowEvent.WINDOW_CLOSING) { 

      System.exit(0); 

    } 

  } 



  int Xs1[]={10,60,120,200,260,340}; 

  int Ys1[]={10,200,120,180,60,130}; 



  void jButton1_actionPerformed(ActionEvent e){ 



      comp2D.clearRect(0,0,401,221); 

       //筆寬度      

      float thick = 10f; 

      //設定筆刷 

      //園頭園連線 

comp2D.setStroke(new BasicStroke(thick, 

BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 

      comp2D.setPaint(Color.red); 

      

       //通過該方法使圖形去除鋸齒狀 

      comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 

                         RenderingHints.VALUE_ANTIALIAS_ON); 

         comp2D.drawPolyline(Xs1,Ys1,Xs1.length);   

  } 



  void jButton2_actionPerformed(ActionEvent e) { 

      

      comp2D.clearRect(0,0,401,221); 

       //筆寬度      

      float thick = 10f; 

      

      //設定筆刷 

      //方頭方連線 

comp2D.setStroke(new BasicStroke(thick, 

BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE)); 

      comp2D.setPaint(Color.blue); 

      

       //通過該方法使圖形去除鋸齒狀 

     //comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 

       //                 RenderingHints.VALUE_ANTIALIAS_ON); 

      comp2D.drawPolyline(Xs1,Ys1,Xs1.length);   

  } 



void jButton3_actionPerformed(ActionEvent e) { 

      

      comp2D.clearRect(0,0,401,221); 

       //筆寬度      

      float thick = 1f; 

      

      //設定筆刷 

      //方頭方連線 

comp2D.setStroke(new BasicStroke(thick, 

BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE)); 

      

      comp2D.setPaint(Color.blue); 

      

       //通過該方法使圖形去除鋸齒狀 

     //comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 

       //                 RenderingHints.VALUE_ANTIALIAS_ON); 

    

      //畫封閉線 

     comp2D.drawPolygon(Xs1,Ys1,Xs1.length);   

  } 









二、貝塞爾(Bezier)曲線 



java 2D提供的QuadCurve2D(二次貝塞爾曲線)及 CubicCurve2D(三次貝塞爾曲線)等相關的類,可以很容易的畫出貝賽爾曲線。 

QuadCurve2D為三個資料,中間一個為控制點。 

CubicCurve2D為四個資料,中間兩個為控制點。 



樣例: 



package myDrawDemo; 



import java.awt.*; 

import java.awt.event.*; 

import javax.swing.*; 

import java.awt.geom.*; 



public class DrawDemo1 extends JFrame 



  public JPanel contentPane; //繪圖視窗 

  public Graphics2D comp2D;    //繪圖物件 

  JPanel jPanel1 = new JPanel();//控制元件容器 

  JButton jButton1 = new JButton(); 

  JButton jButton2 = new JButton(); 



  //建構函式 

  public DrawDemo1() { 

    enableEvents(AWTEvent.WINDOW_EVENT_MASK); 

    try { 

      jbInit(); 

    } 

    catch(Exception e) { 

      e.printStackTrace(); 

    } 

  } 



  //控制元件初始化 

  private void jbInit() throws Exception  { 

    contentPane = (JPanel) this.getContentPane(); 

    contentPane.setLayout(new BorderLayout()); 

    this.setSize(new Dimension(400, 300)); 

    this.setTitle("Frame Title"); 

    //contentPane.setSize(400,240); 

    jPanel1.setLayout(null); 

    jButton1.setBounds(new Rectangle(30, 235, 150, 31)); 

    jButton1.setText("二階貝塞爾"); 



    jButton1.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton1_actionPerformed(e); 

      } 

    }); 



    jButton2.setBounds(new Rectangle(200, 235, 150, 30)); 

    jButton2.setText("三階貝塞爾"); 

   

    jButton2.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton2_actionPerformed(e); 

      } 

    }); 



     contentPane.add(jPanel1, BorderLayout.CENTER); 

    jPanel1.add(jButton1, null); 

    jPanel1.add(jButton2, null); 

   

  } 



   public static void main(String[] args) { 

    

    DrawDemo1 frame=new DrawDemo1(); 

    frame.show(); 

    frame.comp2D=(Graphics2D)frame.contentPane.getGraphics(); 

    frame.comp2D.setBackground(Color.white); 

    frame.comp2D.clearRect(0,0,401,221); 

   } 



  //Overridden so we can exit when window is closed 

  protected void processWindowEvent(WindowEvent e) { 

    super.processWindowEvent(e); 

    if (e.getID() == WindowEvent.WINDOW_CLOSING) { 

      System.exit(0); 

    } 

  } 



  

  void jButton1_actionPerformed(ActionEvent e){ 



     double[] x1={50,180,300}; 

     double[] y1={100,190,100}; 



      comp2D.clearRect(0,0,401,221); 

       //筆寬度      

      float thick = 1f; 

      

      comp2D.setPaint(Color.red); 

      

      QuadCurve2D.Double qc=new QuadCurve2D.Double(); 

     qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2]); 

       

      comp2D.draw(qc); 

      

     comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]); 

     comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5); 

      

      comp2D.setPaint(Color.blue); 

      

      x1[1]=180; 

      y1[1]=30; 

      

     qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2]); 

       

      comp2D.draw(qc); 

      

      comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]); 

     comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5); 

      

  } 



  void jButton2_actionPerformed(ActionEvent e) { 

      

     double[] x1={50,80,200,300}; 

     double[] y1={100,70,190,100}; 

      

      comp2D.clearRect(0,0,401,221); 

       //筆寬度      

      float thick = 1f; 

      

      comp2D.setPaint(Color.red); 

      

      CubicCurve2D.Double qc=newCubicCurve2D.Double(); 

     qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2],x1[3],y1[3]); 

       

      comp2D.draw(qc); 

      

     comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]); 

     comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5); 

      

      comp2D.drawLine((int)x1[2]-5,(int)y1[2],(int)x1[2]+5,(int)y1[2]); 

     comp2D.drawLine((int)x1[2],(int)y1[2]-5,(int)x1[2],(int)y1[2]+5); 

      

      float dash1[] = {10.0f}; 

      

      //畫虛線 

      BasicStroke dashed = new BasicStroke(1.0f, 

                                        BasicStroke.CAP_BUTT, 

                                        BasicStroke.JOIN_MITER, 

                                        10.0f, dash1, 0.0f); 



      comp2D.setStroke(dashed); 

      comp2D.setPaint(Color.darkGray); 

      comp2D.drawLine((int)x1[1],(int)y1[1],(int)x1[2],(int)y1[2]); 

     

     //畫實線 

      BasicStroke stroke = newBasicStroke(1.0f); 

      comp2D.setStroke(stroke); 

      comp2D.setPaint(Color.blue); 

      

      x1[1]=180; 

      y1[1]=70; 

      x1[2]=80; 

      y1[2]=190; 

      

     qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2],x1[3],y1[3]); 

       

      comp2D.draw(qc); 

      

     comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]); 

      comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5); 

      

     comp2D.drawLine((int)x1[2]-5,(int)y1[2],(int)x1[2]+5,(int)y1[2]); 

     comp2D.drawLine((int)x1[2],(int)y1[2]-5,(int)x1[2],(int)y1[2]+5); 

      

      comp2D.setStroke(dashed); 

      comp2D.setPaint(Color.darkGray); 

     comp2D.drawLine((int)x1[1],(int)y1[1],(int)x1[2],(int)y1[2]); 

      comp2D.setStroke(stroke); 

  } 















    

    三、自定義樣條曲線程式設計 

    

當我們需要平滑多個數據樣本點的時候,貝塞爾曲線就不能滿足要求了,為此,可以採用最早由美國“波音”飛機制造公司提出來的樣條曲線來完成,這種曲線所以稱之為樣條,是因為它模擬了造船業中的放樣原理。 

樣條曲線的數學原理請參考計算機圖形學,這裡給出的是由java編寫的三次樣條曲線的例子。曲線平滑的原則是,必須通過所有的樣本點,另外,不論有多少樣本點,曲線的階次最大為三次,所以是穩定的。 

這裡我們可以看出來,程式設計的生命是什麼呢?數學!這是程式設計著的生命所在。語言只是一種規範或者是一個工具,要真正寫出好的程式,沒有深厚的數學功底,是萬萬不可能的。 



樣例: 



package myDrawDemo; 



import java.awt.*; 

import java.awt.event.*; 

import javax.swing.*; 

import java.awt.geom.*; 



public class DrawCurve extends JFrame 



  public JPanel contentPane; //繪圖視窗 



  JPanel jPanel1 = new JPanel();//控制元件容器 

  JButton jButton1 = new JButton(); 

  JButton jButton2 = new JButton(); 

  JButton jButton3 = new JButton(); 



  

  GraphicsCurve gracu; 





  //建構函式 

  public DrawCurve() { 

    enableEvents(AWTEvent.WINDOW_EVENT_MASK); 

    try { 

      jbInit(); 

    } 

    catch(Exception e) { 

      e.printStackTrace(); 

    } 

  } 



    //控制元件初始化 



    private void jbInit() throws Exception  { 

    contentPane = (JPanel) this.getContentPane(); 

    contentPane.setLayout(new BorderLayout()); 

    this.setSize(new Dimension(500,400)); 

    this.setTitle("Frame Title"); 

    //contentPane.setSize(400,240); 

    jPanel1.setLayout(null); 

    jButton1.setBounds(new Rectangle(30, 310, 100, 31)); 

    jButton1.setText("直線"); 





    jButton1.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton1_actionPerformed(e); 

      } 

    }); 





    jButton2.setBounds(new Rectangle(150, 310, 100, 30)); 

    jButton2.setText("樣條曲線"); 

   

    jButton2.addActionListener(new java.awt.event.ActionListener(){ 

      public void actionPerformed(ActionEvent e){ 

        jButton2_actionPerformed(e); 

      } 

    }); 

    

    jButton3.setBounds(new Rectangle(270, 310, 100, 30)); 

    jButton3.setText("粗線條"); 

   

    jButton3.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton3_actionPerformed(e); 

      } 

    }); 

   

     contentPane.add(jPanel1, BorderLayout.CENTER); 

    jPanel1.add(jButton1, null); 

    jPanel1.add(jButton2, null); 

    jPanel1.add(jButton3, null); 

    

    gracu=new GraphicsCurve(); 

  } 



   public static void main(String[] args) { 

    

    DrawCurve frame=new DrawCurve(); 

    frame.show(); 

    frame.gracu.myGraphics=(Graphics2D)frame.contentPane.getGraphics(); 

    frame.gracu.myGraphics.setBackground(Color.white); 

    frame.gracu.myGraphics.clearRect(0,0,500,300); 

   } 



  //Overridden so we can exit when window is closed 

  protected void processWindowEvent(WindowEvent e) { 

    super.processWindowEvent(e); 

    if (e.getID() == WindowEvent.WINDOW_CLOSING) { 

      System.exit(0); 

    } 

  } 

    int Xs1[]={10,60,120,200,260,340}; 

    int Ys1[]={10,200,120,180,60,130}; 



  //畫折線 

  void jButton1_actionPerformed(ActionEvent e){ 

          

      gracu.myGraphics.setPaint(Color.blue); 

     gracu.myGraphics.drawPolyline(Xs1,Ys1,Xs1.length);     

  } 

  

  //畫樣條  

  void jButton2_actionPerformed(ActionEvent e) { 

      

      gracu.myGraphics.setPaint(Color.red); 

      gracu.DrawCurves(Xs1,Ys1); 

  } 



  //畫粗線 

  void jButton3_actionPerformed(ActionEvent e) { 

      //筆寬度      

      float thick = 10f; 

      //設定筆刷 

      //方頭園連線 

      //gracu.myGraphics.setStroke(newBasicStroke(thick, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND)); 

      //園頭園連線 

      gracu.myGraphics.setStroke(newBasicStroke(thick, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 

      gracu.myGraphics.setPaint(Color.blue); 

       //通過該方法使圖形去除鋸齒狀 

      gracu.myGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 

                         RenderingHints.VALUE_ANTIALIAS_ON); 

     gracu.myGraphics.drawPolyline(Xs1,Ys1,Xs1.length);     

         } 

  } 



class GraphicsCurve 



     //繪圖物件 

       public Graphics2D myGraphics; 

       

       public GraphicsCurve() 

      {        

        

       } 

       

       public GraphicsCurve(Graphics2Dgraphics) 

      {        

        this.myGraphics=graphics; 

       } 

       //引數表 

       //x陣列,y陣列,筆刷       

       public void DrawCurves(int[] xa,int[]ya) 

       { 

              

             int[] x, y; 

             double[] a, b, c; 

             double[] px, py, qx, qy, tt; 

             double[] dx, dy; 

             int px1,py1,px2,py2; 

           x=xa; 

             y=ya; 

             px1=x[0]; 

             py1=y[0]; 

             int n=x.length; 

                    a=new double[n]; 

                    b=new double[n]; 

                    c=new double[n]; 

                    px=new double[n]; 

                    py=new double[n]; 

                    qx=new double[n]; 

                    qy=new double[n]; 

                    tt=new double[n]; 

                    dx=new double[n]; 

                    dy=new double[n]; 

                    int i, t, es; 

                    double bx3, bx4, by3, by4, cx, cy; 

                    bx4 = 0; 

                    by3 = 0; 

                    es = 3; 

                    px[0] = 1; 

                    py[0] = 1; 

                    px[n-1] = 1; 

                    py[n-1] = 1; 

                    if (n>1) 

                    { 

                           for (i = 1;i<n;i++) 

                                  tt[i] = Math.sqrt((x[i] - x[i - 1]) * (x[i] - x[i - 1]) + (y[i] - y[i - 1]) *(y[i] - y[i - 1])); 

                           switch(n)       

                           {    

                                  case 2: 

                                         break; 

                                  case 3: 

                                         for (i = 1;i<n - 1;i++) 

                                         { 

                                                a[i] = 2 * (tt[i] + tt[i + 1]); 

                                                b[i] = tt[i + 1]; 

                                                c[i] = tt[i]; 

                                                dx[i] = 3 * (tt[i] * (x[i + 1] - x[i]) / tt[i + 1] + tt[i + 1] * (x[i] - x[i -1]) / tt[i]); 

                                                dy[i] = 3 * (tt[i] * (y[i + 1] - y[i]) / tt[i + 1] + tt[i + 1] * (y[i] - y[i -1]) / tt[i]); 

                                         } 



                                         dx[1] = dx[1] - tt[2] * px[0]; 

                                         dx[n - 2] = dx[n - 2] - tt[n - 2] * px[n-1]; 

                                         dy[1] = dy[1] - tt[2] * py[0]; 

                                         dy[n - 2] = dy[n - 2] - tt[n - 2] * py[n-1]; 



                                         //注意,這是n=3的情況專有計算 

                                         px[1] = dx[1] / a[1]; 

                                         py[1] = dy[1] / a[1]; 

                                          

                                         break; 

                                  default: 

                                         for (i = 1;i<n - 1;i++) 

                                         { 

                                                a[i] = 2 * (tt[i] + tt[i + 1]); 

                                                b[i] = tt[i + 1]; 

                                                c[i] = tt[i]; 

                                                dx[i] = 3 * (tt[i] * (x[i + 1] - x[i]) / tt[i + 1] + tt[i + 1] * (x[i] - x[i -1]) / tt[i]); 

                                                dy[i] = 3 * (tt[i] * (y[i + 1] - y[i]) / tt[i + 1] + tt[i + 1] * (y[i] - y[i -1]) / tt[i]); 

                                         } 

                                         dx[1] = dx[1] - tt[2] * px[0]; 

                                         dx[n - 2] = dx[n - 2] - tt[n - 2] * px[n-1]; 

                                         dy[1] = dy[1] - tt[2] * py[0]; 

                                         dy[n - 2] = dy[n - 2] - tt[n - 2] * py[n-1]; 

                                         c[1] = c[1]/ a[1]; 

                                         for (i = 2 ;i< n - 1;i++) 

                                         { 

                                                a[i] = a[i] - b[i] * c[i - 1]; 

                                                c[i] = c[i] / a[i]; 

                                         } 

                                         qx[1] = dx[1] / a[1]; 

                                         qy[1] = dy[1] / a[1]; 

                                         for (i = 2 ;i< n - 1;i++) 

                                         { 

                                                qx[i] = (dx[i] - b[i] * qx[i - 1]) / a[i]; 

                                                qy[i] = (dy[i] - b[i] * qy[i - 1]) / a[i]; 

                                         } 

                                         px[n - 2] = qx[n - 2]; 

                                         py[n - 2] = qy[n - 2]; 

                                         for (i = n - 3;i>=1;i--) 

                                         { 

                                                px[i] = qx[i] - c[i] * px[i + 1]; 

                                                py[i] = qy[i] - c[i] * py[i + 1]; 

                                         } 

                                         break; 

                           } 

                           for (i = 0 ;i< n - 1;i++) 

                           { 

                                  bx3 = (3 * (x[i + 1] - x[i]) / tt[i + 1] - 2 * px[i] - px[i + 1]) / tt[i +1]; 

                                  bx4 = ((2 * (x[i] - x[i + 1]) / tt[i + 1] + px[i] + px[i + 1]) / tt[i + 1]) /tt[i + 1]; 

                                  by3 = (3 * (y[i + 1] - y[i]) / tt[i + 1] - 2 * py[i] - py[i + 1]) / tt[i +1]; 

                                  by4 = ((2 * (y[i] - y[i + 1]) / tt[i + 1] + py[i] + py[i + 1]) / tt[i + 1]) /tt[i + 1]; 

                                  t = 0; 

                                  while (t < tt[i + 1]) 

                                  { 

                                         t = t + es; 

                                         cx = x[i] + (px[i] + (bx3 + bx4 * t) * t) * t; 

                                         cy = y[i] + (py[i] + (by3 + by4 * t) * t) * t; 

                                         px2 = (int)cx; 

                                         py2 = (int)cy; 

                                         myGraphics.drawLine(px1,py1,px2,py2); 

                                         px1 = px2; 

                                         py1 = py2; 

                                  } 

                           } 

                    }                          

       } 













    四、使用者資料的曲線顯示 



當需要用曲線表達資料的時候,我們雖然可以使用由廠家提供的“圖表”元件,但更多的還是需要自己編寫的,請仔細研究下面的程式,當對圖表設計有更深入的理解。 

下面的例子,我們構造一個專門處理使用者資料的類,在這個類裡,實現了使用者座標和螢幕座標的轉換,同時給出了一個自動繪製座標的方法。我們也直接使用了上面我們討論過的樣條曲線的類實現資料平滑。例子中的資料可以來自於資料庫或其它任何地方,仔細的研究這個例子,可以看出只要我們開動腦筋,把java強大的功能和我們對問題的理解結合在一起,就可以寫出多麼靈活多變的程式來呀! 



樣例: 



package myDrawDemo; 



import java.awt.*; 

import java.awt.event.*; 

import javax.swing.*; 

import javax.swing.event.*; 

import java.awt.geom.*; 



public class DataDrawDemo extends JFrame 



  public JPanel contentPane; //控制元件容器 

  

  JPanel jPanel1 = new JPanel();//繪圖控制元件 

  

  JButton jButton1 = new JButton(); 

  JButton jButton2 = new JButton(); 

  JButton jButton3 = new JButton(); 

  JButton jButton4 = new JButton(); 

  JButton jButton5 = new JButton(); 



  JButton jButton6 = new JButton(); 

  JButton jButton7 = new JButton(); 

  JButton jButton8 = new JButton(); 

  JButton jButton9 = new JButton(); 



  JButton jButton10 = new JButton(); 

  

  JTextField jText1=new JTextField(); 



  JTextField jText2=new JTextField(); 



  boolean kcu=true; 

  

  //使用者座標轉換物件 

  myGraphicsData mp=new myGraphicsData(); 

  

  //曲線轉換物件 

  GraphicsCurve gracu=new GraphicsCurve(); 

  

  

    //視窗範圍 

    double wx1,wx2,wy1,wy2; 



  //建構函式 

  public DataDrawDemo() { 

    enableEvents(AWTEvent.WINDOW_EVENT_MASK); 

    try { 

      jbInit(); 

    } 

    catch(Exception e) { 

      e.printStackTrace(); 

    } 

  } 



    //初始化程式碼 

    private void jbInit() throws Exception  { 



    

    contentPane = (JPanel) this.getContentPane(); 

    contentPane.setLayout(null); 

   

    this.setSize(new Dimension(650, 500)); 

    this.setTitle("Frame Title"); 

    //contentPane.setSize(400,240); 

    //jPanel1.setLayout(null); 



    jPanel1.setBounds(0,90,650,420); 

    jButton1.setBounds(new Rectangle(30, 20, 80, 25)); 

    jButton1.setText("開始"); 



    jButton1.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton1_actionPerformed(e); 

      } 

    }); 



    jButton2.setBounds(new Rectangle(120, 20, 80, 25)); 

    jButton2.setText("左移"); 

   

    jButton2.addActionListener(new java.awt.event.ActionListener(){ 

      public void actionPerformed(ActionEvent e){ 

        jButton2_actionPerformed(e); 

      } 

    }); 



    jButton3.setBounds(new Rectangle(210, 20, 80, 25)); 

    jButton3.setText("右移"); 

   

    jButton3.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton3_actionPerformed(e); 

      } 

    }); 



   jButton4.setBounds(new Rectangle(300, 20, 80, 25)); 

    jButton4.setText("上移"); 

   

    jButton4.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton4_actionPerformed(e); 

      } 

    }); 



  jButton5.setBounds(new Rectangle(390, 20, 80, 25)); 

    jButton5.setText("下移"); 

   

    jButton5.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton5_actionPerformed(e); 

      } 

    }); 

    

    jButton6.setBounds(new Rectangle(120, 50, 80, 25)); 

    jButton6.setText("X擴"); 

   

    jButton6.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton6_actionPerformed(e); 

      } 

    }); 



    jButton7.setBounds(new Rectangle(210, 50, 80, 25)); 

    jButton7.setText("X縮"); 

   

    jButton7.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton7_actionPerformed(e); 

      } 

    }); 



   jButton8.setBounds(new Rectangle(300, 50, 80, 25)); 

    jButton8.setText("Y擴"); 

   

    jButton8.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton8_actionPerformed(e); 

      } 

    }); 



    jButton9.setBounds(new Rectangle(390, 50, 80, 25)); 

    jButton9.setText("Y縮"); 

   

    jButton9.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton9_actionPerformed(e); 

      } 

    }); 

    

    //樣條控制    

    jButton10.setBounds(new Rectangle(30, 50, 80, 25)); 

    jButton10.setText("樣條"); 



    jButton10.addActionListener(newjava.awt.event.ActionListener() { 

      public void actionPerformed(ActionEvent e){ 

        jButton10_actionPerformed(e); 

      } 

    }); 



    jText1.setBounds(new Rectangle(490, 20, 120, 20)); 

    jText1.setText(""); 

  

    jText2.setBounds(new Rectangle(490, 50, 120, 20)); 

    jText2.setText(""); 

  

  

    //滑鼠按下偵聽器 

    jPanel1.addMouseListener(newjava.awt.event.MouseAdapter(){ 

       public void mousePressed(MouseEvent e){ 

       JPanel_mousePressed(e); 

   

     } 

        

   }); 

   

    //滑鼠拖動偵聽器 

    jPanel1.addMouseMotionListener(newjava.awt.event.MouseMotionAdapter(){ 

       public void mouseDragged(MouseEvente){ 

       JPanel_mouseDragged(e); 

     } 

    }); 

    

    

    //滑鼠釋放偵聽器 

    jPanel1.addMouseListener(new