0

I created a Jframe using netbeans drag-n-drop designer. After asking here , I can make the color changing works after changing the color of some item from recList and paint(g) on a new thread of my Draw class.

Now I want to add another JComponent like DrawCar that will add the car image to the Jframe. I want this new JComponent because I don't want to re-render the "car" if the squares in the background change color.

So I created the DrawCar with paint() method like below:

  public void paint(Graphics g) {
    //This to make the (0,0) at the bottom-left not top-left as default.
    Graphics2D g2 = (Graphics2D)g;
    AffineTransform at = g2.getTransform();
    at.translate(0, getHeight());
    at.scale(1, -1);
    g2.setTransform(at);


    //Below is to draw the car
    try {
            image = ImageIO.read(new File("car.png"));
        } catch (IOException ex) {
            Logger.getLogger(Car.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
    g.drawImage(image, 245, 0, null); 
}

If I put these code to render the car in the paint() method of Draw class, it works, so no problem with this code!

In the Container (the class with the GUI) class, I have a button handler. I want the car appear when I click that button, so I tried to add to the event handler with

private void starter_btnActionPerformed(java.awt.event.ActionEvent evt) {
        Thread reDraw = new Thread(new Runnable() {
        @Override
        public void run() {
            //draw1 below is the instance of "Draw" class
            //draw1.paint2(draw1.getGraphics());     //This code works with repainting the square with new color as mentioned before

            DrawCar draw2 = new DrawCar();
            repaint();
            revalidate();
            }

        });
        reDraw.start();

 }  

but it won't work, I don't know what I missed here. Maybe some ways to add the DrawCar to the current JFrame?

Thank you for your time!


EDIT: I just make a simple project to make it clear. I created a JFrame named Test and drop in it a button that will show the picture when I click on it. It's all auto-generated codes.

Now I create a new class call MyClass

public class MyClass extends JComponent{
private BufferedImage image;

MyClass(){
    try {
            image = ImageIO.read(new File("D://pic.jpg"));
        } catch (IOException ex) {
                   Logger.getLogger(this.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
}

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(image, 50, 50, null); 
    }
}

And in the Test, the event handler of the button is like this:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
    MyClass mc = new MyClass();
    add(mc);
    repaint();
    revalidate();
} 

I clicked it and nothing happens. The picture is supposed to shows up on click. How do I make it happens? Thank you


EDIT 2:

enter image description here

This is the image of what I want to achieve, it's the little green car on the bottom, it should appears only when I click "Start!"

Community
  • 1
  • 1
Tran Hoai Nam
  • 1,273
  • 2
  • 18
  • 35

1 Answers1

2

I see quite a few general problems with your code, including:

  1. Never override the paint method, but rather a JPanel or JComponent's paintComponent method.
  2. Almost always call the super's method.
  3. Never read in a file from within a painting method.
  4. Your code flagrantly violates Swing threading rules -- most all Swing calls should be made on the Swing event thread, not off of it as you're doing.
  5. Better to create and post your Minimal, Complete, and Verifiable example or sscce as this way we can run your actually functioning code.

As for your specific problem, you're creating a DrawCar component instance, but you never appear to add it to your GUI, and so it will never show since it is never part of a top-level window such as a JFrame or JApplet or JDialog.


re comments:

Just though paint() and paintComponent() are the same, just one calls another...

No they're not. The paint(...) method is the more "primitive" of the two as it's based in the old AWT code base. It does not automatically do double buffering (unlike paintComponent) and is responsible for painting the component, the component's borders, and any child components held by the component. For the latter reason, you want to avoid overriding it since if you mess it up, you risk mispainting more than just the component.

Back to my problem, I make it like this DrawCar draw2 = new DrawCar(); add(draw2); draw2.setVisible(true); revalidate(); repaint(); I don't know if I missed the "prefix" before add, the code is auto-generated so I can't find any JFrame frame = new JFrame(); to make frame.add(draw2) like others do with their code Any chance that we will find some logical problem?

You've got major structural problems as your new DrawCar class again is nowhere to be seen in the main GUI.

So I'm guessing that your main GUI already has a DrawCar component held within it, and that you're goal is to get this to draw a car on button push (you never say!). If so, then why not have the DrawCar hold a JPanel and simply set its Icon with your image. Myself, I'd read the image in at program start up, and also flip it at at that time, if that were my goal.

Again, if you're still having problems, then isolate the problem down to the smallest compilable runnable code, your mcve and let us test it.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Sorry, I just started using Swing for a day or two. Just though `paint()` and `paintComponent()` are the same, just one calls another... I'll try to fix it as I can. Thanks for the suggestion. Back to my problem, I make it like this `DrawCar draw2 = new DrawCar(); add(draw2); draw2.setVisible(true); revalidate();` repaint(); I don't know if I missed the "prefix" before `add`, the code is auto-generated so I can't find any `JFrame frame = new JFrame();` to make `frame.add(draw2)` like others do with their code Any chance that we will find some logical problem? – Tran Hoai Nam Nov 21 '15 at 13:37
  • <> With what I understand, my main GUI does not have `DrawCar` in it. that's why I call `DrawCar draw2 = new DrawCar();` <> Do you mean something like this?: `ImageIcon image = new ImageIcon("image/pic1.jpg"); JLabel label = new JLabel("", image, JLabel.CENTER); JPanel panel = new JPanel(new BorderLayout()); panel.add( label, BorderLayout.CENTER );` – Tran Hoai Nam Nov 21 '15 at 13:59
  • @TranHoaiNam: update your original question with any new code. Again, we'd much prefer your posting a [mcve] (again, please read the link). – Hovercraft Full Of Eels Nov 21 '15 at 14:30
  • @TranHoaiNam: As we say in the US, "the Devil is in the details". While your new code looks to run fine, I still can't run it or test it. Again, we're asking for you to create and post the smallest runnable program that demonstrates your problem. For example, please look at my code in [this answer](http://stackoverflow.com/a/24770805/522444) to give you an idea of what we're looking for. If you need to display an image, use one that can be obtained online such as in [this example](http://stackoverflow.com/a/10055021/522444). – Hovercraft Full Of Eels Nov 21 '15 at 14:51
  • @TranHoaiNam: also it would help if you could provide images of what you're trying to accomplish with your GUI. – Hovercraft Full Of Eels Nov 21 '15 at 15:26
  • Just uploaded the picture, hope it helps – Tran Hoai Nam Nov 21 '15 at 17:07