Проблема с получением графического объекта для печати на панель - PullRequest
1 голос
/ 03 мая 2020

У меня проблемы с приведенной ниже программой, над которой я работал. Предполагается, что программа принимает пользовательские данные через GUI, а затем использует их для создания и рисования объекта. После некоторого тестирования я знаю, что объект (овальный или прямоугольный angular) создается. Проблема, с которой я сталкиваюсь, заключается в том, что объект не рисуется на панели. Что я здесь делаю неправильно и как я могу получить метод draw для вызова. Я очень плохо знаком с графическими методами и, возможно, совершаю простую ошибку.


import java.awt.*;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 *
 * Purpose: This GUI will take a users input to print a shape
 */
public class Test {

 //Shape class that extends the base rectangle class   
 public abstract static class Shape extends Rectangle {

   private static final long serialVersionUID = 1L;

   // instance variables for shape class
   private String color;
   private Boolean solid;
   private int count;

   // Constructor for shape class
   public Shape(Rectangle rectangle, String color, Boolean solid) 
{
       super(rectangle);
       this.color = color;
       this.solid = solid;
       count++;

   }

      // Method that will give the number of shapes printed
   public  int  getNoOfShapes() {
       return count;
   }
   // method that will take the users color select and set the color

   public void setColor(Graphics g) {
       if(color.equalsIgnoreCase("black"))
           g.setColor(Color.BLACK);
       else if(color.equalsIgnoreCase("red"))
           g.setColor(Color.RED);
       else if(color.equalsIgnoreCase("orange"))
           g.setColor(Color.ORANGE);
       else if(color.equalsIgnoreCase("yellow"))
           g.setColor(Color.YELLOW);
       else if(color.equalsIgnoreCase("green"))
           g.setColor(Color.GREEN);
       else if(color.equalsIgnoreCase("blue"))
           g.setColor(Color.BLUE);
       else if(color.equalsIgnoreCase("magenta"))
           g.setColor(Color.MAGENTA);
   }
   // return shape type is solid or hollow
   public Boolean getSolid() {
       return solid;
   }

   // draw method
   public abstract void draw(Graphics g);
}

 //Oval subclass
  public static class Oval extends Shape {

   private static final long serialVersionUID = 1L;

   // Constructor for the oval class
   public Oval(Rectangle rectangle, String color, Boolean solid) {
       super(rectangle, color, solid);

   }

   //Draw method for the oval 
   @Override
   public void draw(Graphics g) {
       // Draw a hollow oval shape
       if(super.getSolid() == false)
           g.drawOval((int)getX(), (int)getY(), (int)getWidth(), (int)getHeight());
       //Draw a solid oaval shape
       else if(super.getSolid() == true)
           g.fillOval((int)getX(),(int) getY(), (int)getWidth(), (int)getHeight());
   }

}

  //Rectangular subclass
  public static class Rectangular extends Shape {

   private static final long serialVersionUID = 1L;

   // Constructor for Rectangular class
   public Rectangular(Rectangle rectangle, String color, Boolean solid) {
       super(rectangle, color, solid);
   }

   //Method to draw a rectangle
   @Override
   public void draw(Graphics g) {
       // Will draw a hollow rectangle
       if(super.getSolid() == false)
           g.drawRect((int)getX(), (int)getY(), (int)getWidth(), (int)getHeight());
       //Will draw a solid rectangle
       else if(super.getSolid() == true)
           g.fillRect((int)getX(), (int)getY(), (int)getWidth(), (int)getHeight());
   }

}



//Drawing class with GUI inside
public static class Drawing extends JPanel {

   private static final long serialVersionUID = 1L;
   // create Shape 
   private Shape shape1=null;

   public void drawShape(Shape shape) throws OutsideBounds{
   try { 
           if(shape.intersects(270,20,200,200))
               throw new OutsideBounds("This shape will not fit into the drawing box");
       }catch(OutsideBounds o) {
           JOptionPane.showMessageDialog(null, o.getMessage());
       }catch(Exception e) {
               JOptionPane.showMessageDialog(null, "Please only enter integers ");
       }
   }

   // Method to paint shape
   @Override
      public void paintComponent(Graphics g) {

       try {
           // print count of shapes
           super.paintComponents(g);
           shape1.setColor(g);
           shape1.draw(g);
           repaint();

       }catch(Exception e) {}
   }

}

public static class GUI{
   // Instance variables for the GUI
  // private JFrame window;
   private JLabel shape;
   private JLabel fillType;
   private JLabel color;
   private JLabel width;
   private JLabel height;
   private JLabel xCoordinate;
   private JLabel yCoordinate;
   private JLabel printCount;
   private JComboBox<String> cshape;
   private JComboBox<String> cfillType;
   private JComboBox<String> ccolor;
   private JTextField widthField;
   private JTextField heightField;
   private JTextField  xField;
   private JTextField yField;
   private JButton draw;
   private JButton clear;
   private JButton exit;
   private JPanel panel;



   // Constructor that will initiate GUI variables
   public  GUI() {
       JFrame window = new JFrame();
       window.setSize(500,350); // set size fo frame
       window.setDefaultCloseOperation(EXIT_ON_CLOSE);
       window.setLayout(null); // set no layout
       window.setLocationRelativeTo(null); // centered frame
       window.setTitle("Geometric Drawing"); // title
       shape=new JLabel("Shape Type");
       fillType=new JLabel("Fill Type");
       color=new JLabel("Color");
       width=new JLabel("Width");
       height=new JLabel("Height");
       xCoordinate=new JLabel("x coordinate");
       yCoordinate=new JLabel("y coordinate");
       printCount=new JLabel("1");
       cshape=new JComboBox<>(new String[] {"Oval","Rectangle"});
       cfillType=new JComboBox<>(new String[] {"Solid","Hollow"});
       ccolor=new JComboBox<>(new String[] {"Black","Red","Orange","Yellow","Green","Blue","Magenta"});
       widthField=new JTextField();
       heightField=new JTextField();
       xField=new JTextField();
       yField=new JTextField();
       draw=new JButton("Draw");
       clear = new JButton("clear");
       exit = new JButton("exit");
       panel=new JPanel();
       // set border with title to panel
       panel.setBorder(BorderFactory.createTitledBorder("Shape Drawing"));

       // adding all parts to the window 
       window.add(shape);
       window.add(fillType);
       window.add(color);
       window.add(width);
       window.add(height);
       window.add(xCoordinate);
       window.add(yCoordinate);
       window.add(printCount);
       window.add(cshape);
       window.add(cfillType);
       window.add(ccolor);
       window.add(widthField);
       window.add(heightField);
       window.add( xField);
       window.add(yField);
       window.add(draw);
       window.add(clear);
       window.add(exit);
       window.add(panel);

       // set positions within the window
       shape.setBounds(20, 20, 100, 30);
       fillType.setBounds(20, 55, 100, 30);
       color.setBounds(20, 90, 100, 30);
       width.setBounds(20, 125, 100, 30);
       height.setBounds(20, 160, 100, 30);
       xCoordinate.setBounds(20, 195, 100, 30);
       yCoordinate.setBounds(20, 230, 100, 30);
       printCount.setBounds(285, 40, 20, 30);
       cshape.setBounds(140, 20, 100, 30);
       cfillType.setBounds(140, 55, 100, 30);
       ccolor.setBounds(140, 90, 100, 30);
       widthField.setBounds(140, 125, 100, 30);
       heightField.setBounds(140, 160, 100, 30);
        xField.setBounds(140, 195, 100, 30);
       yField.setBounds(140, 230, 100, 30);
       draw.setBounds(230, 280, 80, 30);
       clear.setBounds(120, 280,80,30);
       exit.setBounds(330, 280,80,30);
       panel.setBounds(270, 20, 200, 200);
       // adding action listener to draw button
      // draw.addActionListener((ActionListener) this);
       window.setVisible(true); // make frame visible

       draw.addActionListener(
    new java.awt.event.ActionListener(){
        public void actionPerformed(java.awt.event.ActionEvent evt){
               try {

           Drawing d1 = new Drawing();       
           Shape shape;
           String color;
           int xCoord = 0, yCoord = 0, width = 0, height = 0; 

           //Point accounting for the needed shift

           xCoord = Integer.parseInt(xField.getText() + 270);
           yCoord = Integer.parseInt(yField.getText() + 50);
           width = Integer.parseInt(widthField.getText());
           height = Integer.parseInt(heightField.getText());

           Rectangle r1 = new Rectangle (xCoord, yCoord, width, height);

          // Point p = new Point(shapeX+270, shapeY+50);
           //setting dimensions based off user input 
           //Dimension d = new Dimension(shapeWidth, shapeHeight);
           if(((String) cshape.getSelectedItem()).equalsIgnoreCase("oval")){
               shape = new Oval(r1, (String)ccolor.getSelectedItem(), true);
               System.out.print("creating oval");
                 }
               else{
               shape = new Rectangular(r1,(String)ccolor.getSelectedItem(), true);}
            d1.drawShape(shape);

           window.repaint(); // call paint() method

       }catch(NumberFormatException e) {
       JOptionPane.showMessageDialog(null, "Please only enter integers ");
       }    catch (OutsideBounds ex) {    
                Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
            }    

    }
    });

    //Action Listener for clear button
       clear.addActionListener(new ActionListener(){
           public void actionPerformed(ActionEvent e){
            //Clearing all text fields   
            widthField.setText("");
            heightField.setText("");
            xField.setText("");
            yField.setText("");
                                }
       });

        //Action Liistener for exit button
       exit.addActionListener(new ActionListener(){
           public void actionPerformed(ActionEvent e){
            //message to the user   
            JOptionPane.showMessageDialog(null,"Program is ending");
            window.dispose();}
       });        
   }
}


 // Out of bounds class
public static class OutsideBounds extends Exception {

   private static final long serialVersionUID = 1L;
   // parameterized constructor
   public OutsideBounds(String errorMessage) {
       // call super class parameterized constructor
       super(errorMessage);   
   }
}


public static void main(String[] args) {
       GUI G1 = new GUI();  // Creating GUI

   }

}```

1 Ответ

1 голос
/ 03 мая 2020

Есть несколько небольших проблем, которые объединяются, чтобы создать большую проблему.

  1. null макеты - просто плохая идея. Потратьте время, чтобы узнать, как использовать и смешивать соответствующие макеты
  2. Не используйте String в качестве носителя информации, если вы можете избежать этого. Это слишком легко облажаться. В вашем случае вы узнаете, как использовать ListCellRenderer для настройки JComoboBox, чтобы он мог нести Color в качестве базового значения
  3. Должен быть один экземпляр Drawing, который должен отображать ВСЕ формы. Затем вы добавляете каждую новую форму к нему. Вместо того, чтобы пытаться создавать новые экземпляры для каждой отдельной фигуры.
  4. Для того, чтобы что-то было нарисовано, оно должно быть добавлено к чему-то, что можно нарисовать. Это означает, что в определенный момент необходимо добавить панель Drawing в ваш фрейм (или содержимое, которое прямо или косвенно содержится в вашем фрейме).

Это очень базовый c переработать ваш код. Он будет генерировать овал или прямоугольник в случайном месте со случайным цветом. Я оставлю вас, чтобы заполнить остальные ваши требования вокруг него

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;

public class Test {

    //Shape class that extends the base rectangle class   
    public abstract static class Shape extends Rectangle {

        private static final long serialVersionUID = 1L;

        // instance variables for shape class
        private String color;
        private Boolean solid;
        private int count;

        // Constructor for shape class
        public Shape(Rectangle rectangle, String color, Boolean solid) {
            super(rectangle);
            this.color = color;
            this.solid = solid;
            count++;

        }

        // Method that will give the number of shapes printed
        public int getNoOfShapes() {
            return count;
        }
        // method that will take the users color select and set the color

        public void setColor(Graphics g) {
            if (color.equalsIgnoreCase("black")) {
                g.setColor(Color.BLACK);
            } else if (color.equalsIgnoreCase("red")) {
                g.setColor(Color.RED);
            } else if (color.equalsIgnoreCase("orange")) {
                g.setColor(Color.ORANGE);
            } else if (color.equalsIgnoreCase("yellow")) {
                g.setColor(Color.YELLOW);
            } else if (color.equalsIgnoreCase("green")) {
                g.setColor(Color.GREEN);
            } else if (color.equalsIgnoreCase("blue")) {
                g.setColor(Color.BLUE);
            } else if (color.equalsIgnoreCase("magenta")) {
                g.setColor(Color.MAGENTA);
            }
        }
        // return shape type is solid or hollow

        public Boolean getSolid() {
            return solid;
        }

        // draw method
        public abstract void draw(Graphics g);
    }

    //Oval subclass
    public static class Oval extends Shape {

        private static final long serialVersionUID = 1L;

        // Constructor for the oval class
        public Oval(Rectangle rectangle, String color, Boolean solid) {
            super(rectangle, color, solid);

        }

        //Draw method for the oval 
        @Override
        public void draw(Graphics g) {
            // Draw a hollow oval shape
            if (super.getSolid() == false) {
                g.drawOval((int) getX(), (int) getY(), (int) getWidth(), (int) getHeight());
            } //Draw a solid oaval shape
            else if (super.getSolid() == true) {
                g.fillOval((int) getX(), (int) getY(), (int) getWidth(), (int) getHeight());
            }
        }

    }

    //Rectangular subclass
    public static class Rectangular extends Shape {

        private static final long serialVersionUID = 1L;

        // Constructor for Rectangular class
        public Rectangular(Rectangle rectangle, String color, Boolean solid) {
            super(rectangle, color, solid);
        }

        //Method to draw a rectangle
        @Override
        public void draw(Graphics g) {
            // Will draw a hollow rectangle
            if (super.getSolid() == false) {
                g.drawRect((int) getX(), (int) getY(), (int) getWidth(), (int) getHeight());
            } //Will draw a solid rectangle
            else if (super.getSolid() == true) {
                g.fillRect((int) getX(), (int) getY(), (int) getWidth(), (int) getHeight());
            }
        }

    }

//Drawing class with GUI inside
    public static class Drawing extends JPanel {

        private List<Shape> shapes;
        private List<String> colors; 

        private final Random rnd = new Random();

        public Drawing() {
            shapes = new ArrayList<>(25);
            colors = new ArrayList<>();
            colors.add("black");
            colors.add("red");
            colors.add("orange");
            colors.add("yellow");
            colors.add("green");
            colors.add("blue");
            colors.add("magenta");
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected Rectangle randomBounds() {
            int minSize = 10;
            int avaliableWidth = getWidth() - minSize;
            int avaliableHeight = getHeight() - minSize;

            int width = Math.max(minSize, rnd.nextInt(avaliableWidth / 4));
            int height = Math.max(minSize, rnd.nextInt(avaliableHeight / 4));
            int x = rnd.nextInt(avaliableWidth - width);
            int y = rnd.nextInt(avaliableHeight - height);

            Rectangle bounds = new Rectangle(x, y, width, height);
            return bounds;
        }

        protected String randomColor() {
            Collections.shuffle(colors);
            String color = colors.get(0);
            return color;
        }

        public void addCircle() {
            shapes.add(new Oval(randomBounds(), randomColor(), rnd.nextBoolean()));
            repaint();
        }

        public void addRectangle() {
            shapes.add(new Rectangular(randomBounds(), randomColor(), rnd.nextBoolean()));
            repaint();
        }

        // Method to paint shape
        @Override
        public void paintComponent(Graphics g) {
            // print count of shapes
            super.paintComponents(g);
            for (Shape shape : shapes) {
                Graphics2D g2d = (Graphics2D) g.create();
                shape.setColor(g2d);
                shape.draw(g2d);
                g2d.dispose();
            }
        }

    }

    public static class GUI {

        private Drawing drawing;

        // Constructor that will initiate GUI variables
        public GUI() {
            JFrame window = new JFrame();
            window.setDefaultCloseOperation(EXIT_ON_CLOSE);
            window.setTitle("Geometric Drawing"); // title

            JPanel controls = new JPanel(new GridLayout(0, 1));
            controls.add(makeButton("Circle"));
            controls.add(makeButton("Rectangle"));

            drawing = new Drawing();

            window.add(controls, BorderLayout.WEST);
            window.add(drawing);

            window.pack();
            window.setLocationRelativeTo(null);
            window.setVisible(true); // make frame visible
        }

        protected JButton makeButton(String name) {
           JButton btn = new JButton(name);
           btn.addActionListener(new ActionListener() {
               @Override
               public void actionPerformed(ActionEvent e) {
                   if ("Circle".equals(e.getActionCommand())) {
                      drawing.addCircle(); 
                   } else if ("Rectangle".equals(e.getActionCommand())) {
                      drawing.addRectangle(); 
                   }
               }
           });
           return btn;
        }

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    GUI G1 = new GUI();  // Creating GUI
                }
            });

        }
    }

}

Взгляните на:

для получения более подробной информации

...