我有一个最简单的 java gui 的工作版本,带有一个按钮和一个圆圈,工作正常:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
//a gui element shares its events only with classes that implement Actionlistener interface
public class SimpleGui1 implements ActionListener {
JButton button;
JFrame frame;
ppanel mypanel;
public static void main (String[] args) {
SimpleGui1 mywindow = new SimpleGui1();
mywindow.renderWindow();
}
public void renderWindow(){
frame = new JFrame();
button = new JButton("click me");
mypanel = new ppanel();
//register my interest to catch button events
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, mypanel);
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
//button will call this method when clicked (its the callback)
public void actionPerformed(ActionEvent event)
{
frame.repaint();
button.setText("Clicked!!");
}
}
//i need this to override paintComponent
public class ppanel extends JPanel {
//draw something silly
public void paintComponent(Graphics g) {
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor, 150,150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
}
然后,只是为了好玩,我尝试将这两个类聚合为一个,如下所示:
public class SimpleGui1 extends JPanel implements ActionListener {
private JButton button;
private JFrame frame;
private JPanel mypanel;
public static void main (String[] args) {
SimpleGui1 mywindow = new SimpleGui1();
mywindow.renderWindow();
}
public void renderWindow(){
frame = new JFrame();
button = new JButton("click me");
mypanel = new JPanel();
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// register my interest to catch button events
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, mypanel);
//without this i see only the button
//frame.add(this);
}
//button will call this method when clicked (its the callback)
public void actionPerformed(ActionEvent event)
{
frame.repaint();
button.setText("Clicked!!");
}
public void paintComponent(Graphics g) {
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor, 150,150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
}
新类编译成功,但在运行时它只绘制按钮。由于某种原因,paintComponent 未被调用,正确工作的唯一方法是在 renderwindow() 中添加以下内容:
frame.add(this);
我的问题是为什么这种行为...为什么我必须显式添加 对象到我的框架以使该版本正常工作?
几乎在所有地方都尝试过 repaint() 和 validate() 。变化不大
我也知道我不应该从 EDT 中提取东西,并且带有内部类的版本也可以缓解问题
最佳答案
事实上,您必须显式地将 this 对象添加到内容 Pane 中。我编译并测试了以下内容:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
//a gui element shares its events only with classes that implement Actionlistener interface
public class SimpleGui1 extends JPanel implements ActionListener {
JButton button;
JFrame frame;
ppanel mypanel;
public void paintComponent(Graphics g)
{
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor, 150,150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
public static void main (String[] args) {
SimpleGui1 mywindow = new SimpleGui1();
mywindow.renderWindow();
}
public void renderWindow(){
frame = new JFrame();
button = new JButton("click me");
//register my interest to catch button events
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, this);
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
//button will call this method when clicked (its the callback)
public void actionPerformed(ActionEvent event)
{
frame.repaint();
button.setText("Clicked!!");
}
}
您需要显式添加组件才能进行绘制,组件是对象本身并不重要!
关于java - 但为什么 swing 不绘制我的组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32260145/