I am creating a program that has multiple classes. The program draws various shapes on a gui and the program needs to be modified to incorperate a highlighting function if a shape is clicked on. I have done the coding but it is not drawing the circle and I am not sure why. The highlight method is supposed to draw the highlighting circle. The highlight method is called when a match is found from the search method.

public class ShapeFactory extends JPanel {
    public enum ShapeType {
        Shape, Triangle, Circle, Rectangle, Mix
    };

    /**
     * The instance member field of an array of Shape references
     */
    private Shape[] shapes;

    Shape sh = new Shape();

    /**
     * An instance member field of random number generator
     */
    private Random rand;

    private Shape selectedshape = null;
    /**
     * Maximum size of each shape
     */
    private int maxSize;
    /**
     * Number of shapes to splash
     */
    private int nShapes;
    private ShapeType shapeType;

    private int x,y;
    /**
     * Constructor
     */
    public ShapeFactory() {
        // Put it as a null reference for now. Let the user determine the shape
        // array.
        shapes = null;
        // Instantiate the random generator
        rand = new Random();
        // Initialize maximum shape size,
        maxSize = 5;
        nShapes = 10;
        shapeType = ShapeType.Shape;
        // Set the panel dimensions for visualization
        this.setPreferredSize(new Dimension(800, 600));
        // this.setBorder(BorderFactory.createLineBorder(Color.GRAY, 2));
    }

    /**
     * Overrides this method from the JPanel parent to draw the shapes
     */
    public void paintComponent(Graphics g) {
        // do whatever that has been defined in the parent class
        super.paintComponent(g);
        if (shapes == null)
            this.buildShapes();

        // draw all the shapes
        for (int i = 0; i < shapes.length; ++i)
            shapes[i].paint(g);

        //if statement to paint the circle around the shape selected
        if (selectedshape != null)
            highlight(sh.x(), sh.y());  

    }

    //highlight method to create the circle to highlight the selected shape
    public void highlight(int x, int y){

        Graphics g = this.getGraphics();
        g.drawOval(x, y, 40, 40);
        g.fillOval(x,y, 40, 40);
        g.setColor(Color.gray);
        paint(g);
    }

    public int getMaxSize() {
        return maxSize;
    }

    public int getShapeCount() {
        return nShapes;
    }

    public void setMaxSize(int val) {
        this.maxSize = val;
        this.buildShapes();
    }

    public void setShapeCount(int val) {
        this.nShapes = val;
        this.buildShapes();
    }

    public void setShapeType(ShapeType type) {
        shapeType = type;
        this.buildShapes();
    }

    /**
     * A shapes mutator method This method will append more shapes to the
     * current member field of shapes
     * 
     * @param n
     *            How many shape objects to append
     * @param shapeType
     *            The concrete shape type
     */
    private void buildShapes() {
        // / instantiate the array object
        shapes = new Shape[this.nShapes];
        int nTypes = ShapeType.values().length - 1;
        // / instantiate the shape objects
        for (int i = 0; i < shapes.length; ++i) {
            shapes[i] = getShape(this.shapeType);
        }
        randomize(shapes);
    }

    private Shape getShape(ShapeType type) {
        switch (type) {
        case Shape:
            return new Shape();
        case Triangle:
            return new Triangle();
        case Circle:
            return new Circle();
        case Rectangle:
            return new Rectangle();
        default:
            ShapeType randomType = ShapeType.values()[rand.nextInt(4)];
            return getShape(randomType);
        }
    }

    private void randomize(Shape[] shapes) {
        // / reset each shape object's property to splash
        Dimension s = this.getSize();

        for (int i = 0; i < shapes.length; ++i) {
            shapes[i].setSize(rand.nextInt(maxSize) + 1);
            shapes[i].setPosition(rand.nextInt(this.getWidth()),
                    rand.nextInt(this.getHeight()));
            shapes[i].setRotation(rand.nextInt(360));
            shapes[i].setColor(getRandomColor());
        }
    }

    /**
     * A Helper method that generate a random RBGA color
     * 
     * @return a random color
     */
    private Color getRandomColor() {
        int c = Color.HSBtoRGB(rand.nextFloat(), rand.nextFloat() / 2f + 0.5f,
                rand.nextFloat() / 2f + 0.7f);
        return new Color(c);
    }

    //Search method created to search for the selected shape
    public void search(int x2, int y2) {
        selectedshape = null;
        for (int i = 0; i < shapes.length; ++i)
            if ((sh.size() - sh.x()) == getX() && (sh.size() - sh.y()) == getY()){
                selectedshape = shapes[i];
                break;
            }

    }



}

This is the gui class

public class ShapeSplashApp extends JPanel implements ChangeListener,
        ActionListener, MouseListener {

    private ShapeFactory shapes;
    public int x, y;

    public ShapeSplashApp() {
        shapes = new ShapeFactory();

        JSpinner maxSize = new JSpinner();
        maxSize.setName("maxSize");
        maxSize.setValue(shapes.getMaxSize());
        maxSize.setPreferredSize(new Dimension(80, 30));
        maxSize.addChangeListener(this);

        JSpinner shapeCount = new JSpinner();
        shapeCount.setName("shapeCount");
        shapeCount.setValue(shapes.getShapeCount());
        shapeCount.setPreferredSize(maxSize.getPreferredSize());
        shapeCount.addChangeListener(this);

        JComboBox splashShapes = new JComboBox();
        splashShapes.setName("shape");
        ShapeFactory.ShapeType[] types = ShapeFactory.ShapeType.values();
        for (int i = 0; i < types.length; ++i)
            splashShapes.addItem(types[i]);
        splashShapes.addActionListener(this);

        JPanel control = new JPanel();
        control.add(new JLabel("Max Size"));
        control.add(maxSize);

        control.add(new JLabel("Number of Shapes"));
        control.add(shapeCount);

        control.add(new JLabel("Choices of Shapes"));
        control.add(splashShapes);

        control.addMouseListener(this);

        this.add(control);
        this.add(shapes);

        Dimension dim = new Dimension(shapes.getPreferredSize());
        dim.setSize(dim.getWidth() + 20, dim.getHeight() + 50);
        this.setPreferredSize(dim);
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        // TODO Auto-generated method stub
        JSpinner source = (JSpinner) e.getSource();
        String name = source.getName();
        int val = (Integer) source.getValue();
        if (name.equals("maxSize")) {
            shapes.setMaxSize(val);
            shapes.repaint();
        } else if (name.equals("shapeCount")) {
            shapes.setShapeCount(val);
            shapes.repaint();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JComboBox source = (JComboBox) e.getSource();
        Object val = source.getSelectedItem();
        shapes.setShapeType((ShapeFactory.ShapeType) val);
        shapes.repaint();
    }

    public static void main(String[] args) {
        JFrame win = new JFrame("Shape Splash");
        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        win.getContentPane().add(new ShapeSplashApp());
        win.pack();
        win.setVisible(true);
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();

        shapes.search(x,y);
        shapes.repaint();
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }



}

Not sure whether your code is compiled? You didn't mention any error...

Anyway in your ShapeFacotry class at line 42 in the constructor, you assigned a value Shape to your shapeType. Then you call buildShapes(). Inside the method, you create an array size of nShapes to the shapes. They all are fine until you hit line 115. The line is calling for getting a new shape using the shapeType which is the Shape. Therefore, the getShape() will always return the case 1 -- new Shape();. I don't know how you draw or implement the Shape class which is not Triangle, Circle, or Rectangle. That may be what you need to change -- random the shape value when create each shape for the shapes array?

You need to pass the paintComponent's graphics object to the highlight method and paint onto that. Because of double-buffering and other hidden Swing internals the this.getGraphics() graphics object is is no real use to you.

This article has been dead for over six months. Start a new discussion instead.