Java frame.repaint()不工作
这是我直接从“headfirstjava”获得的一个源代码,但无论我做什么,我似乎都无法使它工作,我不知道我可能缺少什么Java frame.repaint()不工作,java,swing,awt,actionlistener,Java,Swing,Awt,Actionlistener,这是我直接从“headfirstjava”获得的一个源代码,但无论我做什么,我似乎都无法使它工作,我不知道我可能缺少什么 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SimpleGui3C implements ActionListener { JFrame frame; public static void main(String[] args) {
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleGui3C implements ActionListener {
JFrame frame;
public static void main(String[] args) {
SimpleGui3C gui = new SimpleGui3C();
gui.go();
}
public void go() {
MyDrawPanel drawPanel = new MyDrawPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Change colors");
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, 300, 300);
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(70, 70, 100, 100);
}
}
我试图找到另一种方法,不涉及重新绘制,而是在事件发生时创建MyDrawPanel的新实例,但它仍然不起作用,因为我没有找到正确清除面板的方法,到目前为止,我发现的唯一一种方法就是这样做,但这不是我想要实现的
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleGui3C implements ActionListener {
JFrame frame;
public static void main(String[] args) {
SimpleGui3C gui = new SimpleGui3C();
gui.go();
}
public void go() {
MyDrawPanel drawPanel = new MyDrawPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Change colors");
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
go();
}
}
class MyDrawPanel extends JPanel {
int red;
int green;
int blue;
public MyDrawPanel() {
this.red = (int) (Math.random() * 255);
this.green = (int) (Math.random() * 255);
this.blue = (int) (Math.random() * 255);
}
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, 300, 300);
Color randomColor = new Color(this.red, this.green, this.blue);
g.setColor(randomColor);
g.fillOval(70, 70, 100, 100);
}
}
这会做你想做的
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleGui3C implements ActionListener {
static JFrame frame = null; // changed here...
public static void main(String[] args) {
frame = new JFrame(); // changed here....
SimpleGui3C gui = new SimpleGui3C();
gui.go();
}
public void go() {
MyDrawPanel drawPanel = new MyDrawPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Change colors");
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, 300, 300);
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(70, 70, 100, 100);
}
}
在您的go()
方法中。。。每次通过JFrame=newjframe()创建新对象时代码>因此,每次单击屏幕上都会出现一个新的帧
通过在main()
方法中创建对象,我们每次只在同一jframe
对象上调用repaint()
方法,而不是创建新对象
希望它能帮上忙……这会满足你的要求
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleGui3C implements ActionListener {
static JFrame frame = null; // changed here...
public static void main(String[] args) {
frame = new JFrame(); // changed here....
SimpleGui3C gui = new SimpleGui3C();
gui.go();
}
public void go() {
MyDrawPanel drawPanel = new MyDrawPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Change colors");
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, 300, 300);
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(70, 70, 100, 100);
}
}
在您的go()
方法中。。。每次通过JFrame=newjframe()创建新对象时代码>因此,每次单击屏幕上都会出现一个新的帧
通过在main()
方法中创建对象,我们每次只在同一jframe
对象上调用repaint()
方法,而不是创建新对象
希望它能有所帮助……在处理Swing时,应该记住一些事情。当我看到你使用的代码时,我想指出给你看,让你走在正确的轨道上
Swing
基础应用程序从各自的
线程,称为EventDispatcherThread(EDT)
,而不是直接调用
从main。有关该主题的更多信息,请访问
尽量不要在paintComponent(。。。
)
方法,改为在其他地方执行这些计算,然后
只需调用repaint()
paintComponent(…)
的访问说明符受保护
并且
notpublic
,因此在重写超类的方法时,请尝试not
要尽可能多地更改方法访问,直到
必要的
在JPanel
上绘图时,只需调用
JPanel
的实例,而不是顶级容器的
扩展任何JComponenet/JPanel
时,请始终尝试
覆盖所述的JComponent/JPanel
的getPreferredSize()
,如下所示
许多布局将返回0
,如果未指定任何布局,则不会返回任何布局
我们会画画的
请记住调用super.paintComponent(g)
,作为第一行
内部油漆组件(…)
。添加了一条注释以更清晰
不要在JFrame
上设置大小,而是尝试调用pack()
,如下所示
在所附的福利中说明。包装法
调整框架的大小,使其所有内容都位于其上
首选尺寸。包装的另一种选择是确定框架尺寸
通过调用setSize或setBounds(这也会设置
帧位置)。一般来说,使用pack比调用
设置大小,因为pack让框架布局管理器负责
框架大小和布局管理器善于根据平台进行调整
影响组件大小的依赖项和其他因素
以下是修改后的代码(刚刚在DrawPanel
中添加了一个方法,称为setValues()
,在这里进行计算并调用repaint()
),基于以上几点:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleGui implements ActionListener {
private MyDrawPanel drawPanel;
public static void main(String[] args) {
Runnable r = new Runnable () {
@Override
public void run () {
new SimpleGui ().go ();
}
};
EventQueue.invokeLater ( r );
}
public void go() {
drawPanel = new MyDrawPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
JButton button = new JButton( "Change colors" );
button.addActionListener( this );
frame.add( drawPanel, BorderLayout.CENTER );
frame.add( button, BorderLayout.PAGE_END );
frame.pack ();
frame.setLocationByPlatform ( true );
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
drawPanel.setValues ();
}
}
class MyDrawPanel extends JPanel {
private int width = 300;
private int height = 300;
private int red;
private int green;
private int blue;
private Color randomColor;
/*
* Make this one customary habbit,
* of overriding this method, when
* you extends a JPanel/JComponent,
* to define it's Preferred Size.
* Now in this case we want it to be
* as big as the Image itself.
*/
@Override
public Dimension getPreferredSize () {
return new Dimension ( width, height );
}
public void setValues () {
red = ( int ) ( Math.random() * 255 );
green = ( int) ( Math.random() * 255 );
blue = ( int ) ( Math.random() * 255 );
randomColor = new Color( red, green, blue );
repaint ();
}
/*
* This is where the actual Painting
* Code for the JPanel/JComponent goes.
* Here the first line super.paintComponent(...),
* means we want the JPanel to be drawn the usual
* Java way first (this usually depends on the opaque
* property of the said JComponent, if it's true, then
* it becomes the responsibility on the part of the
* programmer to fill the content area with a fully
* opaque color. If it is false, then the programmer
* is free to leave it untouched. So in order to
* overcome the hassle assoicated with this contract,
* super.paintComponent(g) is used, since it adheres
* to the rules, and performs the same task, depending
* upon whether the opaque property is true or false),
* then later on we will add our image to it, by
* writing the other line, g.drawImage(...).
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent ( g );
g.setColor(randomColor);
g.fillOval(70, 70, 100, 100);
}
}
在处理Swing
时,应该记住一些事情。当我看到你使用的代码时,我想指出给你看,让你走在正确的轨道上
Swing
基础应用程序从各自的
线程,称为EventDispatcherThread(EDT)
,而不是直接调用
从main。有关该主题的更多信息,请访问
尽量不要在paintComponent(。。。
)
方法,改为在其他地方执行这些计算,然后
只需调用repaint()
paintComponent(…)
的访问说明符受保护
并且
notpublic
,因此在重写超类的方法时,请尝试not
要尽可能多地更改方法访问,直到
必要的
JPanel
上绘图时,只需调用
JPanel
的实例,而不是顶级容器的JComponenet/JPanel
时,请始终尝试
覆盖所述的JComponent/JPanel
的getPreferredSize()
,如下所示
许多布局将返回0
,如果未指定任何布局,则不会返回任何布局
我们会画画的super.paintComponent(g)
,作为第一行
内部油漆组件(…)
。添加了一条注释以更清晰JFrame
上设置大小,而是尝试调用pack()
,如下所示
在所附的福利中说明。包装法
调整框架的大小,使其所有内容都位于其上
首选尺寸。包装的另一种选择是确定框架尺寸
通过调用setSize或setBounds(这也会设置
帧位置)。一般来说,使用pack比调用
设置大小,因为pack让框架布局管理器负责
框架大小和布局管理器善于根据平台进行调整
影响组件大小的依赖项和其他因素DrawPanel
中添加了一个方法,称为setValues()
,在这里进行计算并调用repaint()
),基于以上几点:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleGui implements ActionListener {
private MyDrawPanel drawPanel;
public static void main(String[] args) {
Runnable r = new Runnable () {
@Override
public void run () {
new SimpleGui ().go ();
}
};
EventQueue.invokeLater ( r );
}
public void go() {
drawPanel = new MyDrawPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
JButton button = new JButton( "Change colors" );
button.addActionListener( this );
frame.add( drawPanel, BorderLayout.CENTER );
frame.add( button, BorderLayout.PAGE_END );
frame.pack ();
frame.setLocationByPlatform ( true );
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
drawPanel.setValues ();
}
}
class MyDrawPanel extends JPanel {
private int width = 300;
private int height = 300;
private int red;
private int green;
private int blue;
private Color randomColor;
/*
* Make this one customary habbit,
* of overriding this method, when
* you extends a JPanel/JComponent,
* to define it's Preferred Size.
* Now in this case we want it to be
* as big as the Image itself.
*/
@Override
public Dimension getPreferredSize () {
return new Dimension ( width, height );
}
public void setValues () {
red = ( int ) ( Math.random() * 255 );
green = ( int) ( Math.random() * 255 );
blue = ( int ) ( Math.random() * 255 );
randomColor = new Color( red, green, blue );
repaint ();
}
/*
* This is where the actual Painting
* Code for the JPanel/JComponent goes.
* Here the first line super.paintComponent(...),
* means we want the JPanel to be drawn the usual
* Java way first (this usually depends on the opaque
* property of the said JComponent, if it's true, then
* it becomes the responsibility on the part of the
* programmer to fill the content area with a fully
* opaque color. If it is false, then the programmer
* is free to leave it untouched. So in order to
* overcome the hassle assoicated with this contract,
* super.paintComponent(g) is used, since it adheres
* to the rules, and performs the same task, depending
* upon whether the opaque property is true or false),
* then later on we will add our image to it, by
* writing the other line, g.drawImage(...).
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent ( g );
g.setColor(randomColor);
g.fillOval(70, 70, 100, 100);
}
}
它应该做什么?我该怎么办