2015-09-23 4 views
3

Я пытаюсь создать программу, которая использует JComboBox, содержащий определенные фигуры (круг, квадрат, овал, прямоугольник). После того, как пользователь нажмет на указанную фигуру, панель отобразит 20 этой фигуры в случайных размерах и местоположениях.Создание конкретных фигур со случайными размерами с помощью JComboBox для выбора фигур

У меня возникли проблемы с тем, как сделать фигуры случайными размерами и местоположениями. Вот мой код до сих пор. Любые советы или источники, на которые следует обратить внимание, будут оценены.

спасибо.

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

public class HW1b extends JFrame 
{ 


public HW1b() 
{ 

    super("Shapes"); 

    final ComboPanel comboPanel = new ComboPanel(); 
    String[] shapeItems = {"Circle", "Square", "Oval", "Rectangle"}; 

    JComboBox shapeBox = new JComboBox<String>(shapeItems); 
    shapeBox.addItemListener(new ItemListener() 
    { 

     public void itemStateChanged(ItemEvent ie) 
     { 

      if (ie.getStateChange() == ItemEvent.SELECTED) 
      { 
       String item = (String)ie.getItem(); 

       if(shapeBox.getSelectedItem().equals("Circle")) 
        comboPanel.makeCircles(); 

       if(shapeBox.getSelectedItem().equals("Square")) 
        comboPanel.makeSquares(); 

       if(shapeBox.getSelectedItem().equals("Oval")) 
        comboPanel.makeOvals(); 

       if(shapeBox.getSelectedItem().equals("Rectangle")) 
        comboPanel.makeRectangles(); 
      } 

     } 

    }); 


    JPanel southPanel = new JPanel(); 
    southPanel.add(shapeBox); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 

    getContentPane().add(comboPanel, "Center"); 
    getContentPane().add(southPanel, "South"); 

    setSize(400, 400); 
     setLocation(200, 200); 
     setVisible(true); 

} 


private class ComboPanel extends JPanel 
{ 
    int w, h; 
    Random rand; 

    static final int OVAL = 0; 
    static final int RECTANGLE = 1; 
    int shapeType = -1; 

    public ComboPanel() 
    { 
     rand = new Random(); 
     setBackground(Color.white); 

    } 

    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 

     int width = getWidth(); 
     int height = getHeight(); 
     int x, y; 

     Shape s = null; 


     for (int i = 0; i < 20; i++) 
     { 
      x = rand.nextInt(width - w); 
      y = rand.nextInt(width - h); 

      switch(shapeType) 
      { 

       case OVAL: s = new Ellipse2D.Double(x,y,w,h); 
        break; 

       case RECTANGLE: s = new Rectangle2D.Double(x,y,w,h); 
        break; 
      } 

      if (shapeType > -1) 
       g2d.draw(s); 
     } 

    } 

    public void makeCircles() 
    { 
     shapeType = OVAL; 
     w = 75; 
     h = 75; 
     repaint(); 
    } 

    public void makeSquares() 
    { 
     shapeType = RECTANGLE; 
     w = 50; 
     h = 50; 
     repaint(); 
    } 

    public void makeOvals() 
    { 
     shapeType = OVAL; 
     w = 80; 
     h = 60; 
     repaint(); 
    } 

    public void makeRectangles() 
    { 
     shapeType = RECTANGLE; 
     w = 80; 
     h = 40; 
     repaint(); 
    } 

} 


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

    } 

} 
+0

Да, у меня было трудно закодированы, пока я не мог понять, что делать дальше. Спасибо за ваш ответ и объяснение. –

ответ

4

Вы закодировав w и h в вашем коде, и поэтому нет никакого способа для этого, чтобы меняться в зависимости от ваших форм. Вместо этого используйте переменную Random, rand, чтобы выбрать случайные значения w и h, которые находятся в пределах определенного диапазона. Сам я не создавал свои фигуры в методе paintComponent, так как живопись не полностью под моим контролем и может произойти, когда я этого не хочу. Например, в вашем коде ваши фигуры будут сильно различаться при изменении размера графического интерфейса. Вместо этого я создавал бы коллекцию, такую ​​как ArrayList<Shape>, и при необходимости заполнял ее созданными объектами Shape (т. Е. Ellipse2D для моих кругов), а затем перебирал эту коллекцию в вашем методе paintComponent, рисуя ваши фигуры.

, например ...

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.event.ItemEvent; 
import java.awt.event.ItemListener; 
import java.awt.geom.Ellipse2D; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import javax.swing.*; 

public class SomeShapes extends JPanel { 
    private ShapePanel shapePanel = new ShapePanel(); 
    private JComboBox<MyShape> myShapeCombo = new JComboBox<>(MyShape.values()); 

    public SomeShapes() { 
     myShapeCombo.setSelectedIndex(-1); 
     myShapeCombo.addItemListener(new ComboListener()); 

     JPanel bottomPanel = new JPanel(); 
     bottomPanel.add(myShapeCombo); 

     setLayout(new BorderLayout()); 
     add(shapePanel, BorderLayout.CENTER); 
     add(bottomPanel, BorderLayout.PAGE_END); 
    } 

    private class ComboListener implements ItemListener { 
     @Override 
     public void itemStateChanged(ItemEvent e) { 
      MyShape myShape = (MyShape) e.getItem(); 
      shapePanel.drawShapes(myShape); 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("SomeShapes"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new SomeShapes()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

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

enum MyShape { 
    OVAL("Oval"), RECTANGLE("Rectangle"), SQUARE("Square"), CIRCLE("Circle"); 
    private String name; 

    private MyShape(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

    @Override 
    public String toString() { 
     return getName(); 
    } 

} 

class ShapePanel extends JPanel { 
    private static final int PREF_W = 600; 
    private static final int PREF_H = PREF_W; 
    private static final Color SHAPE_COLOR = Color.BLUE; 
    private static final int SHAPE_COUNT = 20; 
    private static int MIN = 5; 
    private static int MAX = 200; 
    private List<Shape> shapeList = new ArrayList<>(); 
    private Random random = new Random(); 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    public void drawShapes(MyShape myShape) { 
     shapeList.clear(); // empty the shapeList 
     switch (myShape) { 
     case OVAL: 
      drawOval(); 
      break; 
     case RECTANGLE: 
      drawRectangle(); 
      break; 
      // etc... 

     default: 
      break; 
     } 
     repaint(); 
    } 

    private void drawOval() { 
     // for loop to do this times SHAPE_COUNT(20) times. 
     for (int i = 0; i < SHAPE_COUNT; i++) { 
      // first create random width and height 
      int w = random.nextInt(MAX - MIN) + MIN; 
      int h = random.nextInt(MAX - MIN) + MIN; 

      // then random location, but taking care so that it 
      // fully fits into our JPanel 
      int x = random.nextInt(getWidth() - w); 
      int y = random.nextInt(getHeight() - h); 

      // then create new Shape and place in our shapeList. 
      shapeList.add(new Ellipse2D.Double(x, y, w, h)); 
     } 
    } 

    private void drawRectangle() { 
     // .... etc 
    } 

    //.. .. etc 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D)g; 

     // set rendering hints for smooth ovals 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     g2d.setColor(SHAPE_COLOR); 
     // iterate through the shapeList ArrayList 
     for (Shape shape : shapeList) { 
      g2d.draw(shape); // and draw each Shape it holds 
     }    
    } 
}