简体   繁体   English

如何在Java中将鼠标悬停侦听器添加到矩形

[英]How to add a mouse hover listener to a rectangle in Java

I am trying to make a button using the Rectangle object and am also trying to make the color change on hover, and it will not change. 我正在尝试使用Rectangle对象创建按钮,还试图在悬停时改变颜色,并且颜色不会改变。 I have made my code have more generic names for variables that way it would not confuse, here it is: 我已经使代码中的变量具有更通用的名称,以至于不会混淆,这里是:

public class MouseHandler extends MouseAdapter {
    @Override
    public void mouseMoved(MouseEvent e) {
        int mx = e.getX();
        int my = e.getY();
        if(mx > button.x && mx < button.x+button.width &&
                my > button.y && my < button.y+button.height) {
                buttonHover = true;
        } else {
                buttonHover = false;

        }
    }
}

And I tried calling these lines of code also, but it wouldn't work: 而且我也尝试调用这些代码行,但这行不通:

if(buttonHover)
g.setColor(hoverColor);
g.drawRect(button.x, button.y, button.width, button.height);

I will put my full code at the bottom, with the actual variable names. 我将把完整的代码和实际的变量名放在底部。 Thanks for the help! 谢谢您的帮助!

package trivia;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class Main extends JFrame{

boolean mainMenu = true;
boolean startHover;
static Color tan = Color.decode("#F4EBC3");
static Color darkGreen = Color.decode("#668284");
static Color buttonColor = Color.decode("#A2896B");
static Color borderColor = Color.decode("#333333");
static Color buttonHover = Color.decode("#F5B66E");
Rectangle header = new Rectangle(0, 0, 500, 100);
Rectangle body = new Rectangle(0, 100, 500, 400);
Rectangle start = new Rectangle(150, 150, 200, 40);
Rectangle howToPlay = new Rectangle(150, 225, 200, 40);
Rectangle quit = new Rectangle(150, 300, 200, 40);

public Main() {
    setTitle("Trivia Game!");
    setSize(500, 500);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);

}
@Override
public void paint(Graphics g) {
    Dimension d = this.getSize();
    if(mainMenu = true){
        g.setColor(darkGreen);
        g.fillRect(header.x, header.y, header.width, header.height);
        g.setFont(new Font("Courier", Font.BOLD, 24));
        g.setColor(Color.BLACK);
        drawCenteredString("Trivia Game!", d.width, 125, g);
        g.setColor(tan);
        g.fillRect(body.x, body.y, body.width, body.height);
        g.setColor(buttonColor);
        g.fillRect(start.x, start.y, start.width, start.height);
        g.setColor(borderColor);
        g.drawRect(start.x, start.y, start.width, start.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("Start", d.width, 340, g);
        g.setColor(buttonColor);
        g.fillRect(howToPlay.x, howToPlay.y, howToPlay.width, howToPlay.height);
        g.setColor(borderColor);
        g.drawRect(howToPlay.x, howToPlay.y, howToPlay.width, howToPlay.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("How To Play", d.width, 490, g);
        g.setColor(buttonColor);
        g.fillRect(quit.x, quit.y, quit.width, quit.height);
        g.setColor(borderColor);
        g.drawRect(quit.x, quit.y, quit.width, quit.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("Quit?", d.width, 640, g);
        g.setColor(buttonColor);
        g.fillRect(start.x, start.y, start.width, start.height);
        g.setColor(borderColor);
        g.drawRect(start.x, start.y, start.width, start.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("Start", d.width, 340, g);
        if(startHover)
            g.setColor(buttonHover);
            g.drawRect(start.x, start.y, start.width, start.height);
    }
}
public void drawCenteredString(String s, int w, int h, Graphics g) {
    FontMetrics fm = g.getFontMetrics();
    int x = (w - fm.stringWidth(s)) / 2;
    int y = (fm.getAscent() + (h- (fm.getAscent() + fm.getDescent())) / 2);
    g.drawString(s, x, y);
}

public static void main(String[] args) {
    @SuppressWarnings("unused")
    Main m = new Main();
}
public class MouseHandler extends MouseAdapter {
    @Override
    public void mouseMoved(MouseEvent e) {
        int mx = e.getX();
        int my = e.getY();
        if(mx > start.x && mx < start.x+start.width &&
                my > start.y && my < start.y+start.height) {
                startHover = true;
                System.out.println("yes");
        } else {
                startHover = false;
                System.out.println("no");
        }
    }
}
}

I'll start with... 我将从...开始

1) If it truly just a rectangle you want to deal with. 1)如果确实是您要处理的矩形。 Please use https://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html , Java has been kind enough to make your life simple please don't throw it away. 请使用https://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html,Java足以使您的生活变得简单,请不要扔掉它。 (ignore this keeping here for reference) (忽略此内容以供参考)

2) You should implement MouseMotionListener... I did it for you. 2)您应该实现MouseMotionListener ...我为您做了。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class test extends JFrame  implements MouseMotionListener {

boolean mainMenu = true;
boolean startHover;
static Color tan = Color.decode("#F4EBC3");
static Color darkGreen = Color.decode("#668284");
static Color buttonColor = Color.decode("#A2896B");
static Color borderColor = Color.decode("#333333");
static Color buttonHover = Color.decode("#F5B66E");
Rectangle header = new Rectangle(0, 0, 500, 100);
Rectangle body = new Rectangle(0, 100, 500, 400);
Rectangle start = new Rectangle(150, 150, 200, 40);
Rectangle howToPlay = new Rectangle(150, 225, 200, 40);
Rectangle quit = new Rectangle(150, 300, 200, 40);

public test() {
    setTitle("Trivia Game!");
    setSize(500, 500);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    this.addMouseMotionListener(this);
}

@Override
public void paint(Graphics g) {
    Dimension d = this.getSize();
    if (mainMenu = true) {
        g.setColor(darkGreen);
        g.fillRect(header.x, header.y, header.width, header.height);
        g.setFont(new Font("Courier", Font.BOLD, 24));
        g.setColor(Color.BLACK);
        drawCenteredString("Trivia Game!", d.width, 125, g);
        g.setColor(tan);
        g.fillRect(body.x, body.y, body.width, body.height);
        g.setColor(buttonColor);
        g.fillRect(start.x, start.y, start.width, start.height);
        g.setColor(borderColor);
        g.drawRect(start.x, start.y, start.width, start.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("Start", d.width, 340, g);
        g.setColor(buttonColor);
        g.fillRect(howToPlay.x, howToPlay.y, howToPlay.width,
                howToPlay.height);
        g.setColor(borderColor);
        g.drawRect(howToPlay.x, howToPlay.y, howToPlay.width,
                howToPlay.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("How To Play", d.width, 490, g);
        g.setColor(buttonColor);
        g.fillRect(quit.x, quit.y, quit.width, quit.height);
        g.setColor(borderColor);
        g.drawRect(quit.x, quit.y, quit.width, quit.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("Quit?", d.width, 640, g);
        g.setColor(buttonColor);
        g.fillRect(start.x, start.y, start.width, start.height);
        g.setColor(borderColor);
        g.drawRect(start.x, start.y, start.width, start.height);
        g.setFont(new Font("Courier", Font.BOLD, 20));
        g.setColor(Color.black);
        drawCenteredString("Start", d.width, 340, g);
        if (startHover)
            g.setColor(buttonHover);
        g.drawRect(start.x, start.y, start.width, start.height);
    }
}

public void drawCenteredString(String s, int w, int h, Graphics g) {
    FontMetrics fm = g.getFontMetrics();
    int x = (w - fm.stringWidth(s)) / 2;
    int y = (fm.getAscent() + (h - (fm.getAscent() + fm.getDescent())) / 2);
    g.drawString(s, x, y);
}

public static void main(String[] args) {
    @SuppressWarnings("unused")
    test m = new test();
}

@Override
public void mouseDragged(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void mouseMoved(MouseEvent e) {
    System.out.println("lol");
    int mx = e.getX();
    int my = e.getY();
    if (mx > start.x && mx < start.x + start.width && my > start.y
            && my < start.y + start.height) {
        startHover = true;
        System.out.println("yes");
    } else {
        startHover = false;
        System.out.println("no");
    }
}
}

If you read below you can see there are a lot of things wrong with your code. 如果您阅读下面的内容,可以看到您的代码有很多错误。 Don't let that scare you from learning. 不要让那吓到你学习。 Do it step by step and you will be fine. 一步一步做就可以了。

You've several issues going on here: 您在这里遇到了几个问题:

  • You're doing drawing directly within a JFrame, a dangerous thing to do, since JFrames hold many components, several I'm sure that you're not familiar with, including borders, rootpane, glasspane, and contentpane, and if you mess up painting, it can mess up the drawing of these critical components. 您正在直接在JFrame中绘制图形,这很危险,因为JFrame包含许多组件,所以我确定您不熟悉其中的几个组件,包括边框,根窗格,玻璃窗格和内容窗格,如果您搞砸了,绘画,可能会弄乱这些关键组件的绘制。
  • Also by painting inside of a paint method, you loose all the advantages of Swing graphics. 同样,通过在绘制方法内部进行绘制,您将失去Swing图形的所有优点。
  • Also you appear to have most of your program design and logic within a painting method, something that you should never do since you don't have full control over when or even if that method gets called. 同样,您似乎在绘画方法中拥有大部分程序设计和逻辑,这是您永远都不应做的事情,因为您无法完全控制何时甚至调用该方法。
  • Instead, you should create your button component in its own class, separate from the JFrame 相反,您应该在与JFrame分开的类中创建按钮组件
  • Give your class ability to be placed in a JPanel 使您的班级能够放置在JPanel中
  • And give it a rollover capability. 并为其提供翻转功能。
  • For my money though, I'd just extend a JButton or better, just use a JButton, and make it look the way I want rather than trying to re-invent the wheel. 为了我的钱,我只是扩展一个JButton或更好,只使用一个JButton,并使它看起来像我想要的方式,而不是尝试重新发明轮子。

eg, 例如,

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class Main2 extends JPanel {
   private static final Color TAN = Color.decode("#F4EBC3");
   private static final Color DARK_GREEN = Color.decode("#668284");
   private static final Color BUTTON_COLOR = Color.decode("#A2896B");
   private static final Color BORDER_COLOR = Color.decode("#333333");
   private static final Color BUTTON_ROLLOVER_COLOR = Color.decode("#F5B66E");
   private static final String TITLE = "Trivia Game!";
   private static final Font TITLE_FONT = new Font("Courier", Font.BOLD, 24);
   private static final int PREF_W = 500;
   private static final int PREF_H = PREF_W - 30;
   private JButton startButton;
   private JButton howToPlayButton;
   private JButton quitButton;


   public Main2() {
      JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
      titleLabel.setFont(TITLE_FONT);
      int blGap = 15;
      titleLabel.setBorder(BorderFactory.createEmptyBorder(blGap, blGap, blGap, blGap));
      JPanel titlePanel = new JPanel(new GridBagLayout());
      titlePanel.setBackground(DARK_GREEN);
      titlePanel.add(titleLabel);

      JPanel centerInnerPanel = new JPanel(new GridLayout(0, 1, blGap, 2 * blGap));
      centerInnerPanel.setOpaque(false);
      centerInnerPanel.setBorder(BorderFactory.createEmptyBorder(blGap, blGap, blGap, blGap));
      centerInnerPanel.add(startButton = createButton("Start"));
      centerInnerPanel.add(howToPlayButton = createButton("How To Play"));
      centerInnerPanel.add(quitButton = createButton("Quit?"));

      JPanel centerOuterPanel = new JPanel(new GridBagLayout());
      centerOuterPanel.setBackground(TAN);
      centerOuterPanel.add(centerInnerPanel);


      setLayout(new BorderLayout());
      add(titlePanel, BorderLayout.PAGE_START);
      add(centerOuterPanel, BorderLayout.CENTER);
   }

   private JButton createButton(String name) {
      final JButton button = new JButton(name);
      button.setFont(TITLE_FONT.deriveFont(20F));
      button.setBackground(BUTTON_COLOR);
      Border emptyBorder = BorderFactory.createEmptyBorder(5, 25, 5, 25);
      Border lineBorder = BorderFactory.createLineBorder(BORDER_COLOR);
      Border nestedBorder = BorderFactory.createCompoundBorder(lineBorder, emptyBorder);
      button.setBorder(nestedBorder);


      button.getModel().addChangeListener(new ChangeListener() {

         @Override
         public void stateChanged(ChangeEvent e) {
            ButtonModel model = (ButtonModel)e.getSource();
            if (model.isRollover()) {
               button.setBackground(BUTTON_ROLLOVER_COLOR);
            } else {
               button.setBackground(BUTTON_COLOR);
            }
         }
      });

      return button;
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      int w = Math.max(super.getPreferredSize().width, PREF_W);
      int h = Math.max(super.getPreferredSize().height, PREF_H);

      return new Dimension(w, h);
   }

   private static void createAndShowGui() {
      Main2 mainPanel = new Main2();

      JFrame frame = new JFrame("Main2");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM