0

i have the following problem. i want to paint something on a custom jpanel and then set custom buttons on a absolute positions. these buttons should listen on clicking and then provide their position. but everything i tried is not working. the buttons are not displaying when i use add();

    public class IslePanel extends JPanel {

    private static final long serialVersionUID = 1L;

    private Color backgroundColor = new Color(90, 74, 66);
    private Color strokeColor = new Color(254, 254, 254);
    private Color lightGrayColor = new Color(220, 220, 220);

    /**
     * Constructor of the GameView
     * 
     * @param game
     * @param controller
     */
    public IslePanel() {
        setBackground(backgroundColor);
        SiteButton sb = new SiteButton();
        sb.setXPos(100);
        sb.setYPos(100);
        sb.setSiteRadius(20);
        add(sb);
        //example: i plan to draw a circle formed button on absolute Position (100,100) radius 20
    }


    /**
     * paintComponent-method for ALL drawing functions
     * 
     * @param Graphics
     *            g
     * 
     **/
    public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            try {
                drawTile(g, tile);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

sitebutton superclass:

public abstract class CustomButton extends JPanel implements MouseListener {

    private Vector listeners = null;

    boolean hit = false;

    public CustomButton(String title) {
        super();
        this.title = title;
        listeners = new Vector();
        addMouseListener(this);
    }

//  public Dimension getPreferredSize() {
//      return new Dimension(120, 80);
//  }


    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mouseClicked(MouseEvent e) {
        fireEvent(new ActionEvent(this, 0, title));
        System.out.println("bauen");        
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void addActionListener(ActionListener listener) {
        listeners.addElement(listener);
    }

    public void removeActionListener(ActionListener listener) {
        listeners.removeElement(listener);
    }

    private void fireEvent(ActionEvent event) {
        for (int i = 0; i < listeners.size(); i++) {
            ActionListener listener = (ActionListener) listeners.elementAt(i);
            listener.actionPerformed(event);
        }
        ;
    }
}

the button class:

public class SiteButton extends CustomButton {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private double xpos,ypos;

    private Site site;

    private int siteRadius;

    @Override
    public void paintComponent(Graphics g) {
//      super.paintComponent(g);
        Graphics2D g2D = (Graphics2D) g;

        g2D.setColor(Color.BLACK);
        g2D.fillOval((int)xpos-siteRadius/2, (int)ypos-siteRadius/2, siteRadius, siteRadius);       
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println(""+xpos + ypos);     
    }
PMatt
  • 25
  • 4
  • 1
    I don't see anywhere where your creating a frame and adding a panel with buttons I don't see you adding buttons anywhere in your code? – brso05 Dec 16 '14 at 19:04
  • What exactly have you tried doing? – Xynariz Dec 16 '14 at 19:04
  • You're missing CustomButton and a demonstration of where the button is been used... – MadProgrammer Dec 16 '14 at 20:02
  • For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson Dec 16 '14 at 23:25
  • updated. sorry wrote this post after a looooong workperiod ;D hope its now clear what i want to do. PS: i didnt want to spam a tone of code. i think its clear how i add the panel then or is there anything to consider? – PMatt Dec 17 '14 at 16:09
  • @PMatt check my answer, it should fix your problem. – Nicholas Eason Dec 17 '14 at 17:32
  • @Nicholas Eason i tried to revalidate where i think its necessary(right after i add it to the panel in the constructor) but now my button is displayed at the middle(default layout of the panel) as a square not as a black circle with my coordinates – PMatt Dec 18 '14 at 16:47
  • @PMatt that's because you painted a black circle on to the button. You didn't actually make the button a circle. The reason it's in the middle is because the default layout manager is `BorderLayout` and you didn't specify where it belongs in the layout. It defaults to `BorderLayout.CENTER` because of that. Try calling repaint(); after you add the button and the circle might redraw. – Nicholas Eason Dec 18 '14 at 17:29
  • is there a reference how to can make a "real" circle button that can be placed at absolute coordinates on a jpanel with custom paintComponent method? – PMatt Dec 18 '14 at 19:08
  • Upon further googling I have found a potential answer, but it isnt my job to google things for you ;) [here](http://stackoverflow.com/questions/778222/make-a-button-round) – Nicholas Eason Dec 19 '14 at 02:23
  • thanks ;) if i would have found solution i wouldnt post here. anyhow i managed to add my buttons. but it looks like the paintComponent method is called a lot and my round buttons are having a rectangle background. i think it would be better to post my hole project as a zip. – PMatt Dec 19 '14 at 10:51

1 Answers1

1

You might be better off using an ActionListener than a MouseListener. Not only would it save you a few lines, but it always seems to work for me. mouseClicked is only invoked when the user clicks their LMB over the button (obviously resulting in the button being pressed, but it isn't as direct). actionPerformed is invoked whenever the user performs an ActionEvent on the button (i.e. directly clicking the button).

Not to mention, buttons, by default, fire ActionEvents

The MouseListener is intended to determine if you're holding down the mouse button, if you've released the mouse button, or if you've just "clicked" (or double clicked) the mouse button - regardless of where the mouse is in the listening component.

Also, if you were to click your LMB over the button, but then drag your mouse before you were to release the LMB, the button would still execute.

As to your problem, have you tried using revalidate();?

revalidate() invalidates every component, then validates them.

The problem, is that when you call JPanel.add(button); you immediately invalidate the Container, or in your case, the JPanel. To fix this, you can either call revalidate(); or JPanel.validate();. The difference is that revalidate(), like I said previously, enacts on every component versus validate() which enacts on just one component.

Nicholas Eason
  • 290
  • 4
  • 13