Java多边形调整大小

时间:2014-02-11 18:04:35

标签: java jframe jpanel panel polygons

我正在尝试制作一个具有显示多边形和两个按钮的窗口的程序。多边形从3个点(三角形)开始,允许用户按“+”和“ - ”按钮来添加或减去多边形的边。这是我的代码:

在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)     在javax.swing.JFrame.addImpl(JFrame.java:562)     在java.awt.Container.add(Container.java:410)     在testpolygonbox.TestPolygonBox。(TestPolygonBox.java:21)     在testpolygonbox.TestPolygonBox.main(TestPolygonBox.java:24) Java结果:1

如果有人能告诉我在哪个窗口添加到容器中吗?我不确定我做错了什么。

2 个答案:

答案 0 :(得分:1)

PolygonBoxJFrame窗口,但您将其添加到另一个JFrame。更改类,使其扩展JPanel

public class PolygonBox extends JPanel {

答案 1 :(得分: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当然,但在面板中?这取决于面板使用的布局。那个面板的布局是什么?好吧,因为您没有明确指定它正在使用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);
    

    使用Grid布局,因为我说我想要一个网格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