java – 打印出自定义按钮并使MouseListener工作的问题
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 打印出自定义按钮并使MouseListener工作的问题,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5986字,纯文字阅读大概需要9分钟。
内容图文
![java – 打印出自定义按钮并使MouseListener工作的问题](/upload/InfoBanner/zyjiaocheng/788/ea1271e2897445868fd9996a39cdda03.jpg)
我想制作一个自定义按钮,它包含一个大小方块,分别有这些颜色:#2980b9#3498db.
小方块将位于大方块的内部,当光标位于上方或单击时,它将增加其大小,同时颜色将更改为更清晰的(#4AA3DF).
问题是只打印出较小的一个,甚至打印得不好;因为它出现在窗口的左上角.
此外,根本没有使用MouseListener函数.
这是Button类:
public class Button extends JComponent implements MouseListener {
private static final long serialVersionUID = 1L;
JFrame frame = new JFrame();
public Button(JFrame frame) {
enableInputMethods(true);
addMouseListener(this);
this.frame = frame;
}
// Mouse activity //DELETED
MouseEvent mouseEvent; //DELETED
// Window's width and height.
int width = (int) frame.getWidth();
int height = (int) frame.getHeight();
// Squares's sizes.
int bigSquareXSize = 200;
int bigSquareYSize = 200;
int smallSquareXSize = 180;
int smallSquareYSize = 180;
// smallSquare color.
volatile String color = "#3498db";
//I think that I should do something with the update method,
//but i'm not sure about what (sorry, I know this is stupid).
public void update() {
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// Squares's X and Y positions.
int bigSquareXPosition = width / 2 - bigSquareXSize / 2;
int bigSquareYPosition = height / 2 - bigSquareYSize / 2;
int smallSquareXPosition = width / 2 - smallSquareXSize / 2;
int smallSquareYPosition = height / 2 - smallSquareYSize / 2;
g.setColor(Color.decode("#2980b9"));
g2.setColor(Color.decode(color));
g.fillRect(bigSquareXPosition, bigSquareYPosition, bigSquareXSize, bigSquareYSize);
g2.fillRect(smallSquareXPosition, smallSquareYPosition, smallSquareXSize, smallSquareYSize);
}
// Returns a true value if the cursor is placed over the smallSquare.
public boolean insideArea(MouseEvent e) {
boolean value = false;
int smallSquareXPosition = width / 2 - smallSquareXSize / 2;
int smallSquareYPosition = height / 2 - smallSquareYSize / 2;
if (e.getX() > smallSquareXPosition && e.getX() < smallSquareXPosition + smallSquareXSize) {
if (e.getY() > smallSquareYPosition && e.getY() < smallSquareYPosition + smallSquareYSize) {
value = true;
}
}
return value;
}
volatile boolean clicked = false;
@Override
public void mouseClicked(MouseEvent e) {
if (insideArea(e)) {
clicked = !clicked;
if (clicked) {
color = "#4AA3DF";
smallSquareXSize = 190;
smallSquareYSize = 190;
}
} else {
color = "#3498db";
smallSquareXSize = 180;
smallSquareYSize = 180;
}
this.repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
if (!clicked) {
if (insideArea(e)) {
color = "#4AA3DF";
smallSquareXSize = 190;
smallSquareYSize = 190;
}
}
this.repaint();
}
@Override
public void mouseExited(MouseEvent e) {
if (!clicked) {
if (insideArea(e)) {
color = "#3498db";
smallSquareXSize = 180;
smallSquareYSize = 180;
}
}
this.repaint();
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
这是StartingPoint类:
public class StartingPoint implements Runnable {
Thread thread = new Thread(this);
static JFrame frame = new JFrame("BUTTON!");
static Button button = new Button(frame);
public static void main(String[] args) {
//Frame creation
JFrame frame = new JFrame("BUTTON!");
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(button);
frame.add(panel);
}
@Override
public void run() {
while (true) {
button.update();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这就是控制台所说的:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Button.insideArea(Button.java:62)
at Button.mouseEntered(Button.java:92)
据我所知,问题与框架有关,但我不知道如何解决它.
我查找了java.lang.NullPointerException异常,但我理解的是,当你不调用setSize()方法或类似方法时会发生这种情况,但我做到了.
问题是什么,解决问题的最佳方法是什么?
编辑:我发现是什么导致控制台说出它所说的是mouseEvent.现在,每次我想引用光标时,我都会在方法定义的括号之间使用e.
控制台没有错误;然而,事情以相同的方式打印,MouseListener仍然无法正常工作.
编辑:我不再有例外,因为有MouseEvent mouseEvent,但其他问题仍然存在.
解决方法:
有几个问题.
这些行应该在paint方法中:
int smallSquareXPosition = width / 2 - smallSquareXSize / 2;
int smallSquareYPosition = height / 2 - smallSquareYSize / 2;
就目前而言,这些值在对象初始化时分配一次.但是你的paint方法期望它们是动态的,因为你的事件监听器改变了smallSquareXSize和smallSquareXSize.
由于这些变量只能从paint方法访问,因此在paint方法中移动所有sch变量声明:
public void paintComponent(Graphics g) {
int bigSquareXPosition = width / 2 - bigSquareXSize / 2;
int bigSquareYPosition = height / 2 - bigSquareYSize / 2;
int smallSquareXPosition = width / 2 - smallSquareXSize / 2;
int smallSquareYPosition = height / 2 - smallSquareYSize / 2;
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.decode("#2980b9"));
g2.setColor(Color.decode(color));
g.fillRect(bigSquareXPosition, bigSquareYPosition, bigSquareXSize, bigSquareYSize);
g2.fillRect(smallSquareXPosition, smallSquareYPosition, smallSquareXSize, smallSquareYSize);
}
这也遵循一种良好的通用编码实践,即声明变量使得它们具有尽可能小的范围.在这种情况下,您将把所有方法的范围缩小到仅使用它们的方法.虽然它不适用于这种情况,但是如果可能的话,你应该进一步将范围缩小到只是一个代码块(例如在循环内或块内等).
另一个问题更微妙.它是并发之一,即在多线程环境中运行.发送鼠标事件的线程是与主线程不同的线程.此外,它可能是每个鼠标事件的不同线程(我不确定).并发线程的一个含义是,在一个线程中对实例变量的更改可能不会被其他线程“看到”.具体来说,这个字段:
boolean clicked = false;
这一行:
clicked = !clicked;
这个“问题”是由于java内存模型,它简单地说每个线程可以缓存字段值的副本,这意味着如果一个线程为其分配一个新值,另一个线程可能会或可能不会看到此更改.
但不要惊慌 – 有一个简单的解决方法:
volatile boolean clicked = false;
volatile关键字告诉java永远不会缓存该值 – 始终检查由创建该对象的线程管理的内存中的值.
我不确定您使用的框架是否可以为各种类型的鼠标事件使用不同的线程,但如果确实如此,则需要使用volatile.如果不是,如果不需要,就不会有任何伤害.
内容总结
以上是互联网集市为您收集整理的java – 打印出自定义按钮并使MouseListener工作的问题全部内容,希望文章能够帮你解决java – 打印出自定义按钮并使MouseListener工作的问题所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。