一个 Java 入门 GUI 小程序,就是不太明白为什么我会多一个假 button 块

2018-03-25 21:34:48 +08:00
 Newyorkcity

上面的那个 button 按钮是假的,第一鼠标移动上去不变样子,第二点也点不了
点下面那个真的我代码安排好的,很正常.并且点了一次之后上面那个假的也会消失,程序正常运行,色块变色
程序代码如下:

package SimpleGui3;
import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;

public class SimpleGui3 {    
    public static void main(String[] args) {
        MyFrame gui = new MyFrame();
    }
}

class MyFrame extends JFrame implements ActionListener {
    JButton button;
    MyDrawPanel draw_panel;
    
    public MyFrame() {    
        this.setVisible(true);
        this.setSize(300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        
        button = new JButton("click to change colors");
        button.addActionListener(this);
        this.getContentPane().add(BorderLayout.SOUTH,button);
        
        draw_panel = new MyDrawPanel();
        this.getContentPane().add(BorderLayout.CENTER,draw_panel);
        
    }
    
    public void actionPerformed(ActionEvent event) {
        this.repaint();
    }
}
//无关紧要的部分↓
class MyDrawPanel extends JPanel {
    public void paintComponent(Graphics g) {
        int[] color_array = new int[3];
        for(int i=0;i<color_array.length;i++) {
            color_array[i] = (int)(Math.random() * 255);
        }
        Color c = new Color(color_array[0],color_array[1],color_array[2]);
        g.setColor(c);
        g.fillRect(20, 50, 100, 100);
    }
}

到底是咋回事儿啊,求大佬解答,谢谢..

2017 次点击
所在节点    问与答
14 条回复
kaneg
2018-03-25 21:47:46 +08:00
我的 mac 上运行没有你描述的问题,Java 为 jdk1.8.0_162。你的运行环境是什么? OS 和 Java
Newyorkcity
2018-03-25 22:30:16 +08:00
@kaneg 谢谢 win10+eclipse

->java -version

java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
justinwu
2018-03-26 01:36:48 +08:00
@Newyorkcity 那个无关紧要的代码确定木有问题?

override paintComponent 后,是不是也要 call super.paintComponent,猜的,试试看。
night98
2018-03-26 02:22:22 +08:00
这个代码在手机上看可以说是非常难受了
736531683
2018-03-26 08:06:09 +08:00
爪机无力,现在还写 java 的 gui 吗?…之前 java 课被迫写了几个感觉没什么用
play78
2018-03-26 08:43:36 +08:00
好像我也会耶
Newyorkcity
2018-03-26 09:02:40 +08:00
@justinwu 在把我认为无关紧要的那块代码改为注释之后,确实没有再出现问题诶!
但覆盖 paintComponent 后我并没有在新 paintComponent 里要求 super().paintComponent()呀,为何会发生这种情况?
vve2ex
2018-03-26 10:29:18 +08:00
win7 1.8 eclipse 测试没有出现多余按钮
Newyorkcity
2018-03-26 11:00:57 +08:00
@vve2ex 编译运行两三次试试?我重启之后第一次编译运行也无问题。。
justinwu
2018-03-26 11:22:03 +08:00
@Newyorkcity 自绘控件,需保证其可视区域都被绘制或刷新,除非有意为之。你的 paintComponent 只画了一小片区域,其他没画的部分,图形缓冲区的内容是不可预料的,不画的就会是残留的内容或不可预料内容。JPanel 或其父类会绘制控件背景,你覆盖了此行为,就该自己画控件背景或是委托父类绘制背景。

class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
...
}
}

有些系统或平台或不同 Java 版本并不一定会出现问题。这涉及多个方面因素。说来话长,有兴趣可自行研究 GUI 框架代码。
vve2ex
2018-03-26 11:52:42 +08:00
@Newyorkcity 运行多次也没有出现你这种现象
看了 justinwu 的答案觉得比较合理
kaneg
2018-03-26 20:15:04 +08:00
根据楼主的补充的 java 版本的信息,推测是 Java 9 的 swing paint 跟 Java 8 不一样。目前手头没有 Java 9,暂时无法验证。要么是 Java9 的 bug,要么是其行为变化了
Newyorkcity
2018-03-26 23:53:18 +08:00
@justinwu
@kaneg
@vve2ex
在 sementfault 上一位大佬说把构造器中放在开头的 this.setVisible(true);放到构造器的尾巴上(就构造器最后)
居然真的解决了这个问题诶!!!
这背后的运行机制到底是怎么回事啊?
vve2ex
2018-03-27 09:17:49 +08:00
@Newyorkcity 把 segmentfault 的链接贴上看一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/441301

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX