Search code examples
javaswingjpanelpaintcomponent

Can't paint out a triangle on my picture


I'm creating a map program, that should be able to add places like subway, schools and so on..

I can open a picture that is a map, and my window should resize to fit the image. Now I wan't to be able to add like pins to the map (my triangle). The thing is I can't get it to work.. I've a MouseAdapter the should collect my X and Y and place my triangle on the map. It wont work, and I can't figure out why.. I've have even hard coded a triangle when I create the MapPanel, that triangle shows up but it alway ends up in the top center of the map.. Even when I change the value of x and y when I create it..

Here is my main program

package inlupp2_prog2;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.*;



public class MapProgram extends JFrame {

JComboBox place;
MapPanel mp = null;
JTextField searchField;
JButton searchButton, hideButton, deletePlaceButton, whatIsHere, hideCat, newCat, delCat;
JFileChooser jfc = new JFileChooser(".");
boolean changed = false;




MapProgram(){
    super("inlupp2 av Filip Blom (fibl7163)");

    //FILEMENU  TOPP
    JMenuBar fileBar = new JMenuBar();
    setJMenuBar(fileBar);

    JMenu archive = new JMenu("File");
    fileBar.add(archive);

    JMenuItem open = new JMenuItem("Open");
    archive.add(open);
    open.addActionListener(new OpenLis());

    JMenuItem save = new JMenuItem("Save");
    archive.add(save);
    //ACTIONLISTENER

    JMenuItem close = new JMenuItem("Close");
    archive.add(close);
    close.addActionListener(new CloseLis());


    //valmeny   TOPP
    JPanel north = new JPanel();
    add(north, BorderLayout.NORTH);
    north.add(new JLabel("New"));

    String[] places = { "NamedPlace", "DescribedPlace" };
    place = new JComboBox(places);
    north.add(place);
    //ACTIONLISTENER

    searchField = new JTextField("search", 10);
    north.add(searchField);
    //ACTIONLISTERNER

    searchButton = new JButton("Search");
    north.add(searchButton);
    //ACTIONLISTENER

    hideButton = new JButton("Hide places");
    north.add(hideButton);
    //ACTIONLISTER

    deletePlaceButton = new JButton("Delete places");
    north.add(deletePlaceButton);
    //ACTIONLISTERN

    whatIsHere = new JButton("What is here?");
    north.add(whatIsHere);
    //ACTIONLISTER


    //kategorier ÖST

    JPanel east = new JPanel();
    add(east, BorderLayout.EAST);

    east.add(new JLabel("Categories"));
    //SCROLLPANE

    hideCat = new JButton("Hide category");
    east.add(hideCat);
    //ACTIONLISTER

    newCat = new JButton("New category");
    east.add(newCat);
    //ACTIONLISTERN

    delCat = new JButton("Delete category");
    east.add(delCat);
    //ACTIONLISTER

    BoxLayout eastLayout = new BoxLayout(east, BoxLayout.Y_AXIS);
    east.setLayout(eastLayout);



    addWindowListener(new CloseLis());


    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); 
    setSize(800,300);
    setVisible(true);
    setLocationRelativeTo(null);
    setResizable(false);
}

class MouseLis extends MouseAdapter{
    public void MouseClicked(MouseEvent mev){
        int x = mev.getX();
        int y = mev.getY();
        Place p = new Place(x,y);
        mp.add(p);
        mp.repaint();
        mp.validate();
    }
}

class OpenLis implements ActionListener{
    public void actionPerformed(ActionEvent ave){
        int answer = jfc.showOpenDialog(MapProgram.this);
        if(answer != JFileChooser.APPROVE_OPTION){
            return;
        }

        File file = jfc.getSelectedFile();
        String filename = file.getAbsolutePath();
        if(mp != null){
            remove(mp);
        }

        mp = new MapPanel(filename);
        add(mp, BorderLayout.CENTER);
//          mp.add(new Place(500,500));
        pack();
        validate();
        repaint();
        mp.addMouseListener(new MouseLis());
    }
}

class CloseLis extends WindowAdapter implements ActionListener{

    public void closeSave(){
        if(changed){
        int answer = JOptionPane.showConfirmDialog(null,"You have unsaved changes...\nYou Still want to close this program?", "WARNING", JOptionPane.YES_NO_OPTION);
//          int answer = JOptionPane.showConfirmDialog(MapProgram.this, "You have unsaved changes...\nYou Still want to close this program?");
        if(answer==0){
            System.exit(0);
        } 
        }

        System.exit(0);
    }

    public void windowClosing(WindowEvent wev){
        closeSave();
    }


    public void actionPerformed(ActionEvent ave){
        closeSave();
    }

}

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

}

Here is my class that creates the triangle

package inlupp2_prog2;

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

public class Place extends JComponent {

public Place(int x, int y){
    setBounds(x,y,50,50);
    Dimension d = new Dimension(50, 50);
    setPreferredSize(d);
    setMaximumSize(d);
    setMinimumSize(d);
}

protected void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    int[] xes = {0,25,50};
    int[] yes = {0,50,0};
    g.fillPolygon(xes, yes, 3);
}

}

Here is my MapPanel

package inlupp2_prog2;

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

public class MapPanel extends JPanel{
private ImageIcon map;

public MapPanel(String filename){
    map = new ImageIcon(filename);
    int w = map.getIconWidth();
    int h = map.getIconHeight();
    Dimension d = new Dimension(w,h);
    setPreferredSize(d);
    setMaximumSize(d);
    setMinimumSize(d);
}

protected void paintComponent(Graphics g){
    super.paintComponent(g);
    g.drawImage(map.getImage(), 0, 0, getWidth(), getHeight(), this);
}


}

Solution

  • class MouseLis extends MouseAdapter{
        public void MouseClicked(MouseEvent mev){
            int x = mev.getX();
            int y = mev.getY();
            Place p = new Place(x,y);
            mp.add(p);
            mp.repaint();
            mp.validate();
        }
    }
    

    Note that mouseClicked != MouseClicked. Lesson: ALWAYS use @Override when overriding methods as this would show you your error:

    class MouseLis extends MouseAdapter{
        @Override
        public void MouseClicked(MouseEvent mev){
            int x = mev.getX();
            int y = mev.getY();
            Place p = new Place(x,y);
            mp.add(p);
            mp.repaint();
            mp.validate();
        }
    }
    

    Note: how did I find your error? By playing with your code and sprinkling println's within it including:

      public void MouseClicked(MouseEvent mev) {
         System.out.println("" + mev.getPoint());
         int x = mev.getX();
         int y = mev.getY();
         Place p = new Place(x, y); //!!
         p.setBorder(BorderFactory.createLineBorder(Color.red)); //!!
         mp.add(p);
         mp.repaint();
         mp.validate();
      }
    

    This guy never printed out, and so it keyed me into looking for why it wasn't working. Also, in the future, please consider creating and posting a Minimal, Complete, and Verifiable Example Program. We don't want to see your whole program, but rather you should condense your code into the smallest bit that still compiles, has no extra code that's not relevant to your problem, but still demonstrates your problem. You might very well solve the problem yourself by simply trying to isolate and expose the bug.