-2

I have written a program that paints 5 pictures onto a canvas in jframe. I have now added a jtextfield so that the user can input a number using an actionlistener.

Ideally, the number that the user enters should then produce that amount of pictures on a new canvas.

problem is, i cant remove the canvas object and add a new canvas with the new amount of pictures on it.

please help

public class TaxiFrame extends JFrame implements ActionListener {


      private JLabel L1 = new JLabel("Number of Taxis:");
      private JLabel L2 = new JLabel("Type an integer and press enter");
      private JTextField t1 = new JTextField ("            ");


    public TaxiFrame() {
        super("This is the Frame");
        setSize(600, 400);
        getContentPane().setBackground(Color.CYAN);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout(10, 10));

        Random rx = new Random();
        Random ry = new Random();

        for(int i = 0; i < 5; i ++)

        {
            TaxiCanvas tax = new TaxiCanvas();
            tax.setBounds(rx.nextInt(600 - 100), ry.nextInt(400 - 100), 100, 100);
            add(tax);

        }


        JPanel p = new JPanel();     


         p.setOpaque(false);
         p.add(L1);
         getContentPane().
         add("South", p);

          p.setOpaque(false);
          p.add(t1);
          getContentPane().
          add("South", p);

          p.setOpaque(false);
          p.add(L2);
          getContentPane().
          add("South", p);

        setVisible(true);

        t1.addActionListener(this);



    }

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


   public void actionPerformed(ActionEvent e)
    {

        if (e.getSource() == t1)
        {
            if(Integer.parseInt(t1.getText()) > 0)
            {
                    getContentPane().removeAll();
                  TaxiCanvas tax = new TaxiCanvas();           
               add(tax);
            }
        }

    }

}

thanks alot

taxi canvas code is

import java.awt.*;
import javax.swing.*;
public class TaxiCanvas extends JComponent
{
  private Taxi taxi = new Taxi();
  public void paint(Graphics g)
  {
    taxi.paint(g);

  }
}

taxi code

import java.awt.*;
public class Taxi
{
  public void paint(Graphics g)
  {


// drawing the car body
     g.setColor(Color.yellow);
     g.fillRect(0,10, 60, 15);

// drawing the wheels
     g.setColor(Color.black);
     g.fillOval(10, 20, 12, 12);     // left wheel
     g.fillOval(40, 20, 12, 12);     // right wheel

     int x[] = {10, 20, 40, 50};   // coordinate arrays for the 
     int y[] = {10, 0, 0, 10};   //   car cabin


     g.setColor(Color.yellow);
     g.fillPolygon(x, y, 4);           // drawing the cabin in yellow


     g.setColor(Color.black);
     g.drawString("20", 25, 22);
     g.drawLine(0, 25, 60, 25);

  }
  }

BenMorel
  • 34,448
  • 50
  • 182
  • 322
  • 1
    Please paste your code here (in your question) instead of linking to another site. – Múna Mar 11 '14 at 19:18
  • sorry about that, its now changed, please help me – please delete me Mar 11 '14 at 19:25
  • Could you add the code for TaxiCanvas? – blueygh2 Mar 11 '14 at 19:26
  • thanks for reply taxicanvas code is now added – please delete me Mar 11 '14 at 19:35
  • To test this, I would need the Taxi code as well.... – blueygh2 Mar 11 '14 at 19:37
  • What is the problem here specifically? – Radiodef Mar 11 '14 at 19:39
  • thanks alot, taxi code is there now – please delete me Mar 11 '14 at 19:41
  • the problem is that when that i need the frame to be cleared of the taxi pictures and then filled with the new amount of taxis that a user entered – please delete me Mar 11 '14 at 19:43
  • @webbeginner A problem would be if the code did not do that and instead did something else. Right now it just sounds like you are wanting us to write this functionality for you. In general, we don't do that, we help fix problems. – Radiodef Mar 11 '14 at 19:48
  • @Radiodef i thought i had tried to do that with this getContentPane().removeAll(); TaxiCanvas tax = new TaxiCanvas(); add(tax); unfortunatley im very new to this and dont know where to go next – please delete me Mar 11 '14 at 19:51
  • Right and what you may have observed is that calling `removeAll` removes the panel with the labels and text field. That would be a problem and is what you should include in the question. – Radiodef Mar 11 '14 at 19:53
  • but calling removeAll isnt actually removing anything when an amount is written and entered nothing happens at all – please delete me Mar 11 '14 at 19:59
  • If you call `revalidate` and `repaint` like @peeskillet has suggested you'll see that something happens. – Radiodef Mar 11 '14 at 20:00
  • Blanking the code doesn't help here. We don't care if your code has mistakes and it is still viewable in the revision history anyway. The problem with your question is not that your code was bad, but rather that you didn't adequately describe to us what you needed help with. – Radiodef Mar 11 '14 at 21:21
  • Welcome to Stack Overflow. Please don't remove your code on block without a very good reason. The question becomes unclear without it and future readers can't understand the correlation between question and answer. – Angelo Fuchs Mar 11 '14 at 22:11

2 Answers2

2
  1. When removing and adding components you need to revalidate() and repaint()

  2. Instead of adding and removing containers consider using a CardLayout that will "layer" your containers and let you navigate through them. See How to use CardLayout

  3. Don't override the paint method of JComponent. instead override paintComponent and make sure to call super.paintComponent as not to break the paint chain and probably leaving you with paint artifacts.

  4. Dont use this deprecated add("South", p); method. Instead use add(p, BorderLayout.SOUTH)

  5. Trying to tax.setBounds will do nothing, as far as placement, as your layout is set (not null)

  6. You are trying to add to "South" a bunch of times. Each position can only hold one component

  7. When adding to BorderLayout, if you don't specify a position when adding, it will automatically get added to the CENTER. So if you try to add multiple components without specify a position, only the last component you add will be shown.

  8. Swing apps should be run on the Event Dispatch Thread (EDT). You can do so by wrapping your code in your main in a SwingUtilities.invokeLater.... See more at Initial Threads

  9. Honestly I have no idea what your code is attempting to do, but look at RadioDef's comment below, see if it means anything to you.

  10. If you want to add multiple Taxi objects to your TaxiCanvas, see this answer where you can use a List of Taxi objects and iterate through them in the paintComponent method.

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Something else you might also address is the OP's use of `removeAll` which will of course remove all components, including the panel with the labels and text field (and is I assume the actual reason they have come here asking a question). – Radiodef Mar 11 '14 at 19:51
  • @Radiodef I don't know what the OP is attempting _at all_ with their code. So I just pointed out your comment :) – Paul Samsotha Mar 11 '14 at 19:54
  • 1
    Lol, I kind of inferred what they are wanting to do is remove all the existing TaxiCanvases and add a certain number of new ones. But they really need to offer more of an explanation. : / I gave you an up vote because these are all helpful tips to set them on their way to writing a Swing app that works. – Radiodef Mar 11 '14 at 19:59
  • thanks for trying but revalidate and repaint arent working either unfortunatley – please delete me Mar 11 '14 at 20:05
  • @webbeginner Make sure to erase all the spaces in the text field. – Radiodef Mar 11 '14 at 20:22
0

I implemented many of the suggestions by @peeskillet as well as cleaned up the code a little and here is the result.

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

public class TaxiFrame
extends JFrame
implements ActionListener {

    private JLabel label1 = new JLabel("Number of Taxis:");
    private JLabel label2 = new JLabel("Type an integer and press enter");
    private JTextField inputField = new JTextField(10);
    private JPanel taxiPanel = new JPanel();

    private Dimension tpSize = new Dimension(600, 400);
    private Random rand = new Random();

    public TaxiFrame() {
        super("This is the Frame");
        getContentPane().setBackground(Color.CYAN);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout(10, 10));

        taxiPanel.setLayout(null);
        taxiPanel.setOpaque(false);
        taxiPanel.setPreferredSize(tpSize);
        add(taxiPanel, BorderLayout.CENTER);

        JPanel p = new JPanel();

        p.setOpaque(false);
        p.add(label1);
        p.add(inputField);
        p.add(label2);
        add(p, BorderLayout.SOUTH);

        inputField.addActionListener(this);

        inputField.setText("5");
        addNewTaxis(5);

        pack();
        setResizable(false);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void addNewTaxis(int numTaxis) {
        for(int i = 0; i < numTaxis; i++) {
            addNewTaxi();
        }
    }

    private void addNewTaxi() {
        TaxiCanvas tc = new TaxiCanvas();
        tc.setBounds(
            rand.nextInt(tpSize.width - 100),
            rand.nextInt(tpSize.height - 100),
            100, 100
        );
        taxiPanel.add(tc);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == inputField) {
            int numTaxis = Integer.parseInt(inputField.getText());

            if(numTaxis > 0) {
                taxiPanel.removeAll();
                addNewTaxis(numTaxis);

                taxiPanel.revalidate();
                repaint();
            }
        }
    }

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

    public static class TaxiCanvas
    extends JComponent {
        private Taxi taxi = new Taxi();

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            taxi.paint(g);
        }
    }

    public static class Taxi {
        public void paint(Graphics g) {
            // drawing the car body
            g.setColor(Color.yellow);
            g.fillRect(0,10, 60, 15);

            // drawing the wheels
            g.setColor(Color.black);
            g.fillOval(10, 20, 12, 12); // left wheel
            g.fillOval(40, 20, 12, 12); // right wheel

            int x[] = {10, 20, 40, 50}; // coordinate arrays for the 
            int y[] = {10, 0, 0, 10};   //   car cabin

            g.setColor(Color.yellow);
            g.fillPolygon(x, y, 4);     // drawing the cabin in yellow

            g.setColor(Color.black);
            g.drawString("20", 25, 22);
            g.drawLine(0, 25, 60, 25);
        }
    }
}

looks working

Please don't accept this answer, I just wanted to show they were good suggestions and show the working code. There were many small Swing-related bugs but otherwise the code works.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Radiodef
  • 37,180
  • 14
  • 90
  • 125