2014-02-11 168 views
0

我想做一個程序,它有一個窗口,顯示一個多邊形和兩個按鈕。多邊形從3點開始(三角形),並允許用戶按下「+」和「 - 」按鈕來添加或減去多邊形的邊。這裏是我的代碼:Java多邊形調整大小

在TestPolygonBox:

package testpolygonbox 
import javax.swing.*; 
import java.awt.*; 
public class TestPolygonBox extends JFrame { 


public TestPolygonBox(){ 
    setLayout(new BorderLayout(5,5)); 
    add(new PolygonBox()); 
} 
public static void main(String[] args) { 
    TestPolygonBox frame = new TestPolygonBox(); 
    frame.setTitle("Polygon Box"); 
    frame.setSize(400,420); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 

} 
} 

接下來是控制類:

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

public class PolygonBox extends JPanel { 
private JButton jbtEnlarge = new JButton("+"); 
private JButton jbtShrink = new JButton("-"); 
private PolygonPanel polygonPanel = new PolygonPanel(); 

public PolygonBox(){ 
    JPanel panel = new JPanel(); 
    panel.add(jbtEnlarge); 
    panel.add(jbtShrink); 
    setLayout(new BorderLayout()); 
    this.add(polygonPanel,BorderLayout.CENTER); 
    this.add(panel, BorderLayout.SOUTH); 

    jbtEnlarge.addActionListener(new EnlargeListener()); 
    jbtShrink.addActionListener(new ShrinkListener()); 
} 


class EnlargeListener implements ActionListener{ 
@Override 
public void actionPerformed(ActionEvent e){ 
    polygonPanel.enlarge(); 
    } 
} 
class ShrinkListener implements ActionListener{ 
@Override 
public void actionPerformed(ActionEvent e){ 
    polygonPanel.shrink(); 
} 
} 
} 

class PolygonPanel extends JPanel{ 
private int polygonSides = 3; 

/** Add side to the polygon*/ 
public void enlarge(){ 
    polygonSides++; 
    repaint(); 
} 
public void shrink(){ 
    polygonSides--; 
    repaint(); 
} 
    @Override /** Draw requested Shape*/ 
protected void paintComponent(Graphics g){ 

    int frameWidth = getWidth()/2; 
    int frameHeight = getHeight()/2; 
    int radius = (int)(Math.min(getWidth(),getHeight())* 0.4); 
    int xCenter = getWidth()/2; 
    int yCenter = getHeight()/2; 


    g.setColor(Color.BLUE); 
    Polygon polygon = new Polygon(); 

    polygon.addPoint(xCenter + radius, yCenter); 
       polygon.addPoint((int)(xCenter + radius * Math.cos(2 * Math.PI/polygonSides)), 
         (int)(yCenter - radius * Math.sin(2 * Math.PI/polygonSides))); 
       for (int polygonPoint = 2; polygonPoint <= polygonSides; polygonPoint++){ 
        polygon.addPoint((int)(xCenter + radius * Math.cos(polygonPoint * 2 * Math.PI/polygonSides)), 
         (int)(yCenter - radius * Math.sin(polygonPoint * 2 * Math.PI/polygonSides))); 
       } 

    g.fillPolygon(polygon); 
} 


} 

當我嘗試運行這個程序,我得到的錯誤: 異常在線程「 main「java.lang.IllegalArgumentException:在java.awt.Container.checkNotAWindow(Container.java:483) (java.awt.Container.addImpl(Container.java:1084))上添加窗口到容器 at java.awt.Container.add(Container.java:998) at javax.swing.JFrame.addImpl(JFrame.java:562) at java.awt.Container.add(Container.java:410) at 。testpolygonbox.TestPolygonBox(TestPolygonBox.java:21) 在testpolygonbox.TestPolygonBox.main(TestPolygonBox.java:24) Java結果:1

如果有人能告訴我在哪裏,我加入一個窗口添加到容器嗎?林不知道我做錯了什麼。

+0

嘿,不要刪除和重新發布的問題,至少不會這麼快。 – DSquare

回答

1

PolygonBox是一個JFrame窗口,但您將其添加到另一個JFrame。改變這個類,使其擴展爲JPanel

public class PolygonBox extends JPanel { 
+0

這是關於它。也許你可以幫我解決我的下一個問題。當我添加繪圖代碼時,它使用按鈕在面板中繪製多邊形。它爲什麼這樣做? – nfoggia

+0

現在您已將'PolygonBox'更改爲'JPanel',因此您需要將其佈局設置爲'BorderLayout'(因爲'JPanel'默認爲'FlowLayout'),因此您可以使用該佈局添加組件''setLayout新的BorderLayout())' – Reimeus

+0

即使當我這樣做時,多邊形在同一個面板中仍然很小。我需要將它添加到不同的面板,我認爲?...我添加了繪圖代碼到問題 – nfoggia

0

有4個嚴重的問題與您的代碼。

  • 您沒有在事件分派線程(EDT)中執行Swing代碼。你的主要有如下所示:

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

    這是非常重要甚至是Swing Hello World - 最簡單的Swing程序 - 它。如果你想知道爲什麼要這樣,請閱讀concurrency tutorial。簡而言之,如果你的程序變得越來越龐大而且越來越複雜,你就不會這麼做,否則你會看到很多不一致的,不可重現的異常和Swing類中發生的錯誤,並且你無法追蹤。第二,如Reimeus所述,你不能在另一個框架中放置一個框架,PolygonBox必須是JPanel

  • 第三,您沒有正確填充面板。看看這個代碼:

    JPanel panel = new JPanel(); 
    panel.add(jbtEnlarge); 
    panel.add(jbtShrink); 
    

    這段代碼看起來很奇怪,它是。當你看到它時彈出的問題是:「這些按鈕添加在哪裏?」那麼當然在panel,但其中在面板?這取決於面板使用的佈局。那個面板的佈局是什麼?那麼因爲你沒有明確指定一個,所以它使用JPanel的默認佈局:BorderLayout。與邊界佈局panel.add(component);相當於panel.add(component, BorderLayout.CENTER);。然而,你不能在CENTER中放置兩個組件,你可以放置一個包含許多組件或任何其他組件的面板,但是你不能直接放置兩個組件,這就是爲什麼該代碼不起作用。那麼你如何填充面板?學會使用它,然後以適當的方式添加組件。例如,我會用GridLayout來做到這一點。

    JPanel panel = new JPanel(new GridLayout(1, 2)); 
    panel.add(_enlargeButton); 
    panel.add(_shrinkButton); 
    

    與電網布局,因爲我說我想要一個1x2的網格,這些都增加了正確的,因爲面板現在他已經把組件在網格的每個單元都知道。

  • 最後,您會看到存在繪畫問題:多邊形不會被擦除,它們會彼此重疊,並且您可能會看到面板中按鈕的圖像...這是因爲您必須在paintComponent方法中調用super.paintComponent(g)。事情是,代碼描繪了一個多邊形,是的,但是你也必須完成組件爲繪畫本身所做的所有其他工作,所以你必須做的第一件事就是調用你重寫的原始代碼,然後繪製你的組件。有關這種工作原理的詳細教程,請參閱Painting in AWT and Swing

所有這一切,改變一些變量的名稱,遵循Java約定和重新格式化代碼,以獲得更好的組織。這是您的固定節目:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import java.awt.Polygon; 
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.SwingUtilities; 

public class TestPolygonBox extends JFrame 
{ 
    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() { //Error 1: executing Swing code outside the EDT fixed 
      public void run() 
      { 
       TestPolygonBox frame = new TestPolygonBox(); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public TestPolygonBox() 
    { 
     super("Polygon Box"); //this is JFrame("title") since we are extending a frame 
     setLayout(new BorderLayout());//this line doesn't actually do nothing since the frame already usesk BorderLayout by default 

     add(buildPolygonBoxPanel()); 

     setSize(400, 420); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    } 


    private JPanel buildPolygonBoxPanel() //Error 2: PolygonBox has to be a panel, also I made it into a mthod returning the panel instead of a whole class since it was unnecessary. 
    { 
     JPanel polygonBox = new JPanel(new BorderLayout()); 

     _polygonPanel = new PolygonPanel(); 

     JPanel buttonsPanel = new JPanel(new GridLayout(1, 2)); //Error 4 adding the buttons properly to a panel. 
     _enlargeButton = new JButton("+1"); 
     _enlargeButton.addActionListener(new EnlargeListener()); 
     _shrinkButton = new JButton("-1"); 
     _shrinkButton.addActionListener(new ShrinkListener()); 
     buttonsPanel.add(_enlargeButton); 
     buttonsPanel.add(_shrinkButton); 

     polygonBox.add(_polygonPanel, BorderLayout.CENTER); 
     polygonBox.add(buttonsPanel, BorderLayout.SOUTH); 

     return polygonBox; 
    } 

    class EnlargeListener implements ActionListener 
    { 
     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      _polygonPanel.enlarge(); 
     } 
    } 

    class ShrinkListener implements ActionListener 
    { 
     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      _polygonPanel.shrink(); 
     } 
    } 

    private JButton _enlargeButton; 
    private JButton _shrinkButton; 
    private PolygonPanel _polygonPanel; 
} 

class PolygonPanel extends JPanel 
{ 
    private int _polygonSides = 3; 

    /** Add side to the polygon */ 
    public void enlarge() 
    { 
     _polygonSides++; 
     repaint(); 
    } 

    public void shrink() 
    { 
     if (_polygonSides > 3) _polygonSides--; 
     repaint(); 
    } 

    @Override 
    /** Draw requested Shape*/ 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); //Error 4 fixed, call super.paintComponent 

     int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4); 
     int xCenter = getWidth()/2; 
     int yCenter = getHeight()/2; 

     g.setColor(Color.BLUE); 
     Polygon polygon = new Polygon(); 

     polygon.addPoint(xCenter + radius, yCenter); 
     polygon.addPoint((int) (xCenter + radius * Math.cos(2 * Math.PI/_polygonSides)), (int) (yCenter - radius * Math.sin(2 * Math.PI/_polygonSides))); 
     for (int polygonPoint = 2; polygonPoint <= _polygonSides; polygonPoint++) 
     { 
      polygon.addPoint((int) (xCenter + radius * Math.cos(polygonPoint * 2 * Math.PI/_polygonSides)), (int) (yCenter - radius * Math.sin(polygonPoint * 2 * Math.PI/_polygonSides))); 
     } 

     g.fillPolygon(polygon); 
    } 
} 

只需複製並執行它,它看起來像這樣:

TestPolygonBox