2014-02-11 3 views
0

다각형과 두 개의 버튼을 표시하는 창이있는 프로그램을 만들려고합니다. 다각형은 3 점 (삼각형)에서 시작하여 "+"및 "-"버튼을 눌러 다각형의면을 더하거나 뺄 수 있습니다. "스레드에서 예외 : TestPolygonBox에서자바 다각형 크기 조정

: 내가이 프로그램을 실행하려고하면

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); 
} 


} 

내가 오류를 얻을 :

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); 

} 
} 

옆에있는 컨트롤 클래스가 여기 내 코드입니다 main "java.lang.IllegalArgumentException : 컨테이너에 윈도우 추가하기 at java.awt.Container.checkNotAWindow (Container.java:483) at java.awt.Container.addImpl (Container.java:1084)addAmpl (JFrame.java:562) (JFrame.java:562) at java.awt.Container.add (Container.java:410) at의 java.awt.Container.add (Container.java:998)에서의3210 . testpolygonbox.TestPolygonBox (TestPolygonBox.java:21) testpolygonbox.TestPolygonBox.main (TestPolygonBox.java:24) 자바 결과에서 1

내가 컨테이너에 창을하시기 바랍니다 추가하고 어디 사람이 말해 줄 수 있다면? 임 무슨 잘못하고 있는지 모르겠다.

+0

어이가 너무 빨리 적어도, 삭제하고 질문을 다시 게시하지 않습니다. – DSquare

답변

1

PolygonBoxJFrame 창이지만 JFrame에 추가 할 예정입니다. 대신 JPanel을 확장하도록 클래스를 변경하십시오.

public class PolygonBox extends JPanel { 
+0

그게 전부입니다. 어쩌면 당신은 내 다음 문제로 나를 도울 수 있습니다. 그리기 코드를 추가하면 단추가있는 패널에 다각형이 그려집니다. 왜 그렇게합니까? – nfoggia

+0

'PolygonBox'를'JPanel'으로 변경 했으므로 레이아웃을'BorderLayout'으로 설정해야합니다 ('JPanel'의 기본값은'FlowLayout'이므로), 레이아웃을 사용하여 컴포넌트를 추가 할 수 있습니다 -'setLayout new BorderLayout()) ' – Reimeus

+0

그렇게해도 폴리곤은 같은 패널에 작게 유지됩니다. 내가 생각한 다른 패널에 추가해야합니까? ... 질문에 드로잉 코드를 추가했습니다. – nfoggia

0

코드에 심각한 문제가 4 개 있습니다.

  • 이벤트 발송 스레드 (EDT)에서 스윙 코드를 실행하지 않습니다. 기본은 다음과 같이한다 :

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

    이 심지어 Swing Hello World 매우 중요합니다 - 간단한 스윙 프로그램 - 그것을 않습니다. 이것이 왜 이런 식으로되어야하는지 알고 싶다면이 책을 읽어주십시오. concurrency tutorial. 간단히 말해, 프로그램이 커지고 복잡 해지면 제대로하지 않으면 스윙 클래스에서 발생하는 일관성없고 재현 할 수없는 예외 및 버그가 많이 발생하여 추적 할 수 없습니다.

  • 둘째, Reimeus에서 설명한 것처럼 다른 프레임 안에 프레임을 넣을 수 없으며 PolygonBox는 JPanel이어야합니다.

  • 세 번째로 패널을 올바르게 채우지 못합니다. 이 코드를보십시오 :

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

    이 코드는 이상하게 보입니다. 당신이 그것을 볼 때 나타나는 질문은 : "그 버튼들은 어디에 추가 되었습니까?" 물론 panel에 있지만, 여기서은 패널에 있습니까? 이는 패널이 사용하고있는 레이아웃에 따라 다릅니다. 그리고 그 패널의 레이아웃은 무엇입니까? 자 이제 JPanels에 대한 기본 레이아웃 인 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); 
    

    은 내가 그리드 × 2를, 그에서 추가 할 패널이 지금은 그리드의 각 셀에 구성 요소를 넣어 가지고 있음을 알고 있기 때문에 올바른지 말했다 때문이다.

  • 마지막으로 페인팅에 문제가있는 것을 볼 수 있습니다 : 다각형이 지워지지 않고 다른 하나 위에 칠해 지므로 패널의 버튼 이미지를 볼 수 있습니다. 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

관련 문제