-1

I am developing the game GUI now.

But I have a small problem during programming.

I make a button to start and centered the button.

And I override mouseEntered and mouseExited.

When I run the program, Image is positioned center but cursor reacted from a distance.

I don't know why image and cursor are not matched...

This is my Main code.

    package PoET;

    public class Main {

        public static final int SCREEN_WIDTH=600;
        public static final int SCREEN_HEIGHT=800;

        public static void main(String[] args) {
            // TODO Auto-generated method stub
            new Display();
        }

    }

And this is my Display code.

package PoET;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame; 
import javax.swing.JLabel;

public class Display extends JFrame {

private Image screenImage;
private Graphics screenGraphic;

private Image explainImage = new ImageIcon(Main.class.getResource("../images/explainSample.jpg")).getImage();
private Image introBackground = new ImageIcon(Main.class.getResource("../images/background.jpg")).getImage();
private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));

private ImageIcon quitButtonBasicImage = new ImageIcon(Main.class.getResource("../images/quitButtonBasic.png"));
private ImageIcon quitButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/quitButtonPressed.png"));

private ImageIcon startButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
private ImageIcon startButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
private ImageIcon developerButtonBasicImage = new ImageIcon(Main.class.getResource("../images/developerButtonBasic.png"));
private ImageIcon developerButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/developerButtonEntered.png"));

private ImageIcon goButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
private ImageIcon goButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));

private JButton quitButton = new JButton(
        quitButtonBasicImage);
private JButton startButton = new JButton(
        startButtonBasicImage);
private JButton developerButton = new JButton(
        developerButtonBasicImage);
private JButton goButton = new JButton(
        new ImageIcon(Main.class.getResource("../images/startButtonEntered.png")));


private int mouseX, mouseY;
private boolean isExplainScreen=false;

    public Display() {
    setUndecorated(true);
    setTitle("RogueLike PoET");
    setSize(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
    setResizable(false); 
    setLocationRelativeTo(null); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    setBackground(new Color(0, 0, 0, 0));
    setLayout(null);

    //quitButton.setBounds(560, 30, 30, 30);
    quitButton.setBounds(400, 200, 30, 30);
    quitButton.setBorderPainted(false);
    quitButton.setContentAreaFilled(false);
    quitButton.setFocusPainted(false);
    quitButton.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent e) {
            quitButton.setIcon(quitButtonEnteredImage);
            quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        }

        @Override
        public void mouseExited(MouseEvent e) {
            quitButton.setIcon(quitButtonBasicImage);
            quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));

        }
        @Override
        public void mousePressed(MouseEvent e) {
            System.exit(0);
        }
    });
    add(quitButton);

    menuBar.setBounds(0, 0, 600, 30);
    menuBar.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            mouseX=e.getX();
            mouseY=e.getY();
        }
    });
    menuBar.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            int x=e.getXOnScreen();
            int y=e.getYOnScreen();
            setLocation(x-mouseX,y-mouseY);
        }
    });
    add(menuBar);


    startButton.setBounds(150, 540, 300, 60);
    startButton.setBorderPainted(false);
    startButton.setContentAreaFilled(false);
    startButton.setFocusPainted(false);
    startButton.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent e) {
            startButton.setIcon(startButtonEnteredImage);
            startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        }

        @Override
        public void mouseExited(MouseEvent e) {
            startButton.setIcon(startButtonBasicImage);
            startButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

        }

        @Override
        public void mousePressed(MouseEvent e) {
            startButton.setVisible(false);
            goButton.setVisible(true);
            introBackground=new ImageIcon(Main.class.getResource("../images/background2.jpg")).getImage();
            isExplainScreen=true;
        }
    });
    add(startButton);

    developerButton.setBounds(150, 610, 300, 60);
    developerButton.setBorderPainted(false);
    developerButton.setContentAreaFilled(false);
    developerButton.setFocusPainted(false);
    developerButton.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent e) {
            developerButton.setIcon(developerButtonEnteredImage);
            developerButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        }

        @Override
        public void mouseExited(MouseEvent e) {
            developerButton.setIcon(developerButtonBasicImage);
            developerButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

        }

        @Override
        public void mousePressed(MouseEvent e) {
            developerButton.setVisible(false);
            goButton.setVisible(true);
            introBackground=new ImageIcon(Main.class.getResource("../images/background2.jpg")).getImage();
            isExplainScreen=false;
        }
    });
    add(developerButton);

    goButton.setVisible(false);
    goButton.setBounds(150, 720, 300, 60);
    goButton.setBorderPainted(false);
    goButton.setContentAreaFilled(false);
    goButton.setFocusPainted(false);
    goButton.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent e) {
            goButton.setIcon(goButtonEnteredImage);
            goButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        }

        @Override
        public void mouseExited(MouseEvent e) {
            goButton.setIcon(goButtonBasicImage);
            goButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

        }

        @Override
        public void mousePressed(MouseEvent e) {
            goButton.setVisible(false);
            introBackground=new ImageIcon(Main.class.getResource("../images/background2.jpg")).getImage();
            isExplainScreen=true;
        }
    });
    add(goButton);

    Music introMusic = new Music("introMusic.mp3", true);
    introMusic.start();
}

public void paint(Graphics g) {
    screenImage = createImage(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
    screenGraphic = screenImage.getGraphics();
    screenDraw(screenGraphic);
    g.drawImage(screenImage, 0, 0, null);
}

public void screenDraw(Graphics g) {
    g.drawImage(introBackground, 0, 0, null);
    paintComponents(g);
    if(isExplainScreen) {
        g.drawImage(explainImage, 50, 50,null);
    }
    this.repaint();
}

}

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 2
    Set the cursor once - you don’t need the mouse listener to do it, the api will change cursor automatically – MadProgrammer Jun 04 '18 at 08:39
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). Note that an MCVE / SSCCE requires only **one** button to demonstrate the effect. 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). 3) See [Detection/fix for the hanging close bracket of a code block](http://meta.stackexchange.com/q/251795/155831) for a problem I could no longer be bothered fixing. – Andrew Thompson Jun 04 '18 at 08:59
  • @MadProgrammer Thank you. I removed all mouse listeners like this : `startButton.setBounds(150, 540, 300, 60); add(startButton);` But It worked same... – 밍밍한맹물 Jun 04 '18 at 14:16

1 Answers1

0

So I stripped back your example, removed the MouseListeners and just set the cursor of the buttons and it works fine - I reset the buttons to paint their border and contents so I could see their extent, and the cursor changes when ever the mouse enters/exist the area they cover without issue

import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Display extends JFrame {

    public static final int SCREEN_WIDTH = 600;
    public static final int SCREEN_HEIGHT = 800;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Display();
    }
    private Image screenImage;
    private Graphics screenGraphic;

//  private Image explainImage = new ImageIcon(Main.class.getResource("../images/explainSample.jpg")).getImage();
//  private Image introBackground = new ImageIcon(Main.class.getResource("../images/background.jpg")).getImage();
//  private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));
//
//  private ImageIcon quitButtonBasicImage = new ImageIcon(Main.class.getResource("../images/quitButtonBasic.png"));
//  private ImageIcon quitButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/quitButtonPressed.png"));
//
//  private ImageIcon startButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
//  private ImageIcon startButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
//  private ImageIcon developerButtonBasicImage = new ImageIcon(Main.class.getResource("../images/developerButtonBasic.png"));
//  private ImageIcon developerButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/developerButtonEntered.png"));
//
//  private ImageIcon goButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
//  private ImageIcon goButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
    private JButton quitButton = new JButton(
                    "Quote");
    private JButton startButton = new JButton(
                    "Start");
    private JButton developerButton = new JButton(
                    "Developer");
    private JButton goButton = new JButton(
                    new ImageIcon("Go"));

    private int mouseX, mouseY;
    private boolean isExplainScreen = false;

    public Display() {
        setUndecorated(true);
        setTitle("RogueLike PoET");
        setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
//      setBackground(new Color(0, 0, 0, 0));
        setLayout(null);

        //quitButton.setBounds(560, 30, 30, 30);
        quitButton.setBounds(400, 200, 30, 30);
//      quitButton.setBorderPainted(false);
//      quitButton.setContentAreaFilled(false);
        quitButton.setFocusPainted(false);
        quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        add(quitButton);

        startButton.setBounds(150, 540, 300, 60);
//      startButton.setBorderPainted(false);
//      startButton.setContentAreaFilled(false);
        startButton.setFocusPainted(false);
        startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        add(startButton);

        developerButton.setBounds(150, 610, 300, 60);
//      developerButton.setBorderPainted(
//                      false);
//      developerButton.setContentAreaFilled(
//                      false);
        developerButton.setFocusPainted(
                        false);
        developerButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        add(developerButton);

        goButton.setVisible(
                        false);
        goButton.setBounds(
                        150, 720, 300, 60);
//      goButton.setBorderPainted(
//                      false);
//      goButton.setContentAreaFilled(
//                      false);
        goButton.setFocusPainted(
                        false);
        goButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        add(goButton);
    }

    public void paint(Graphics g) {
        screenImage = createImage(SCREEN_WIDTH, SCREEN_HEIGHT);
        screenGraphic = screenImage.getGraphics();
        screenDraw(screenGraphic);
        g.drawImage(screenImage, 0, 0, null);
    }

    public void screenDraw(Graphics g) {
//      g.drawImage(introBackground, 0, 0, null);
        paintComponents(g);
        if (isExplainScreen) {
//          g.drawImage(explainImage, 50, 50, null);
        }
        this.repaint();
    }
}

Observations

  • Don't override paint of a top level container like a JFrame. JFrame is a compound component (it has a series of child components which make up it's core functionality), overriding paint can have an adverse affect on how those components get painted. Unlike top level containers, Swing components are double buffered by default.
  • Also, the "viewable" area the "window" area are two different concepts. For more details see How to get the EXACT middle of a screen, even when re-sized
  • Also, you could be painting beneath the windows decorations (I know, it's a undecorated window, but it's still a bad habit)
  • Don't try and put ALL your logic into a single class/paint method. Instead, break down your screens into separate components and use something like CardLayout to switch between them

This...

setSize(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);

is generally a bad idea. Better to let the child components dictate their preferred sizes and simply pack the window around them

Don't call setVisible(true); before you've established the basic UI, otherwise it's possible for some components not to be painted

I'm not sure what befit you're hoping to get from setBackground(new Color(0, 0, 0, 0));, but based on your current design, it seems like a waste

Don't call this.repaint(); or perform any other operation inside the paint chain which might trigger a repaint. This will set you for a infinite loop which will eventually consume all your CPU cycles

setLayout(null); is ill advised - there is a lot going into how components get laid out, you're in for a lot of work to reproduce it

Instead, it might look something like (as a starting point)...

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Display());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Display extends JPanel {

        //  private Image explainImage = new ImageIcon(Main.class.getResource("../images/explainSample.jpg")).getImage();
        //  private Image introBackground = new ImageIcon(Main.class.getResource("../images/background.jpg")).getImage();
        //  private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));
        //
        //  private ImageIcon quitButtonBasicImage = new ImageIcon(Main.class.getResource("../images/quitButtonBasic.png"));
        //  private ImageIcon quitButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/quitButtonPressed.png"));
        //
        //  private ImageIcon startButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
        //  private ImageIcon startButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
        //  private ImageIcon developerButtonBasicImage = new ImageIcon(Main.class.getResource("../images/developerButtonBasic.png"));
        //  private ImageIcon developerButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/developerButtonEntered.png"));
        //
        //  private ImageIcon goButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
        //  private ImageIcon goButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
        private JButton quitButton = new JButton(
                        "Quote");
        private JButton startButton = new JButton(
                        "Start");
        private JButton developerButton = new JButton(
                        "Developer");
        private JButton goButton = new JButton(
                        new ImageIcon("Go"));

        private int mouseX, mouseY;
        private boolean isExplainScreen = false;

        public Display() {
            setLayout(null);

            //quitButton.setBounds(560, 30, 30, 30);
            quitButton.setBounds(400, 200, 30, 30);
            //      quitButton.setBorderPainted(false);
            //      quitButton.setContentAreaFilled(false);
            quitButton.setFocusPainted(false);
            quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
            add(quitButton);

            startButton.setBounds(150, 540, 300, 60);
            //      startButton.setBorderPainted(false);
            //      startButton.setContentAreaFilled(false);
            startButton.setFocusPainted(false);
            startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
            add(startButton);

            developerButton.setBounds(150, 610, 300, 60);
            //      developerButton.setBorderPainted(
            //                      false);
            //      developerButton.setContentAreaFilled(
            //                      false);
            developerButton.setFocusPainted(
                            false);
            developerButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
            add(developerButton);

            goButton.setVisible(
                            false);
            goButton.setBounds(
                            150, 720, 300, 60);
            //      goButton.setBorderPainted(
            //                      false);
            //      goButton.setContentAreaFilled(
            //                      false);
            goButton.setFocusPainted(
                            false);
            goButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
            add(goButton);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 800);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(introBackground, 0, 0, null);

            // This should be done else where
//              if (isExplainScreen) {
//                  //          g.drawImage(explainImage, 50, 50, null);
//              }
            //this.repaint();
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366