最小化窗口时自动重绘
我有一个JFrame,有两个面板,在一个面板中我画了一条线,当我工作时,我最小化了我正在做的java程序的窗口,当我最大化它时,我画的线是不同的,它重新绘制了它一个不同的地方!
有谁知道如何锁定这幅画,这样当我最小化它时就不会搞砸这幅画了?
谢谢你!
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
class JFramePaint1 extends JFrame implements ActionListener /*implements ActionListener*/{
public static int activa = 0;
public static JButton drawing = new JButton("drawing");
public static JButton erase = new JButton("erase");
public static int x1=0, y1=0,x2=0,y2=0;
public JFramePaint1(){
//row column
JPanel container = new JPanel(); //new JPanel(new GridLayout(2,1));
JPanel header = new JPanel();
// header.setLayout(new GridLayout(50, 2));
// header.setLayout(new FlowLayout());
header.setLayout(new BoxLayout(header, BoxLayout.LINE_AXIS));
container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS)); //lo quite ahorita
// container.setLayout(new FlowLayout());
ContentComponent c = new ContentComponent();
drawing.addActionListener(this);
erase.addActionListener(this);
//header.setSize(30,30);
//drawing.setAlignmentY(Component.BOTTOM_ALIGNMENT);
container.add(Box.createRigidArea(new Dimension(100, 0)));
header.add(drawing); //lo quite ahorita
header.add(erase);
container.add(header);
//container.add(Box.createRigidArea(new Dimension(5,0)));
//header.add(drawing);
// container.add(header);
container.add(c); //lo quite ahorita
add(container);
// add(c);
//add(c);
}
public static void main(String[] a) {
JFramePaint1 VentanaDiverti = new JFramePaint1();
VentanaDiverti.setSize(800, 700);
VentanaDiverti.setLocation(200, 0);
VentanaDiverti.setTitle("Diverti");
VentanaDiverti.setResizable ( false );
VentanaDiverti.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
VentanaDiverti.setVisible(true);
/* JFrame f = new JFrame();
// JFramePaint1 f = new JFramePaint1();
f.setTitle("Drawing Graphics in Frames");
f.setSize(800, 650);
f.setLocation(200,50);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane( new ContentComponent());
f.getContentPane().add(b);
//f.addWindowListener(this);
//b.addActionListener(this);
f.setVisible(true);*/
}
static class ContentComponent extends JPanel {
public void paint(Graphics g) {
BufferedImage image;
/*reset the variables, this makes the repaint look the same! it's as comments so that you can see what happens
x1=0;
y1=0;
x2=0;
y2=0;
*/
try {
image = ImageIO.read(new File("image name and path"));
} catch (IOException ex) {
// handle exception...
}
g.setColor (Color.RED);
// void fillRect(int x, int y, int width, int height)
// Fills the specified rectangle.
g.fillRect(0, 0, 800, 600);
if( activa == 1){
g.setColor(Color.BLACK);
// g.drawRect(40, 40, 150, 80);
int x = 40;
int y= 40;
for(int i = 0; i< 4; i++){
//g.drawRect(x+10, y+10, 150, 80);
x = x+10;
y = y+10;
}
//drawLine(int x1, int y1, int x2, int y2)
//Draws a line, between the points (x1, y1) and (x2, y2) in this graphics context's coordinate system.
x1+=20;
x2+=20;
y2+=50;
g.drawLine(x1,y1,x2,y2);
x2+=30;
y1=y2;
g.drawLine(x1,y1,x2,y2);
// g.drawLine(20,0,20,50);
}
// activa = 0;
}//del paint
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()== drawing)
{ System.out.println("entro");
if(activa==0){
activa = 1;
repaint();}
}
if(e.getSource()==erase){
activa = 0;
x1=0;
y1=0;
x2=0;
y2=0;
repaint();
}
}
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void windowOpened(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
出现这种情况是很正常的。只要系统需要重绘窗口的一部分,
paint
方法就可以在任何时间调用(请参阅在 AWT 中绘画 了解具体细节)。当您最小化窗口时,之前绘制的任何内容都不会保存在任何地方,因此当您最大化窗口时,所有内容都需要重新绘制,因此paint
会自动调用。因此,您不应在
paint
中对数据执行任何更新。您应该在单独的方法中执行这些操作,将结果存储在变量中,并且仅使用这些现有结果来绘制内容。由于以下部分不会更改:
将它们移动到单独的方法中,例如
updatePoints
。然后在actionPerformed
方法中,首先调用updatePoints()
,然后调用repaint()
。It is very normal for this to happen. The
paint
method can be called at any time, whenever the system needs to redraw a portion of your window (see Painting in AWT for specific details). When you minimize the window, whatever you drew into it before is not saved anywhere, so when you maximize the window, all of the contents need to be drawn again, sopaint
will be called automatically.For this reason, you should not perform any updates to your data in
paint
. You should do these in a separate method, store the results in your variables and only use these existing results to draw the content.Since the following parts do not change:
move them into a separate method, say
updatePoints
. Then in youractionPerformed
method, first callupdatePoints()
and thenrepaint()
.您可以向 jframe 添加一个窗口侦听器,该侦听器在触发调整大小/最大化/任何事件时调用面板绘制方法。
You could add a window listener to your jframe that calls the panels paint method when a resize/maximize/whatever event is triggered.
基本上,只是补充一下 casablanca 所说的,发生的情况是,由于您的 x1、x2、y1、y2 变量是静态的,因此每次执行绘制时它们都会更新,然后保持该值直到下一次重新绘制,那时它们会再次更新,等等...
我的建议实际上是将您的数据与显示代码分开。因此,不要将 x1、x2、y1 和 y2 声明为静态全局变量,而是将它们作为内部类的一部分(您称之为 ContentComponent,并且将起始 x1、x2、y1、y2 值作为全局变量,例如这:
Basically, just to add to what casablanca said, what is happening is that since your x1, x2, y1, y2 variables are static, they are getting updated every time you perform a paint, and then staying at that value until the next repaint, at which time they are updated again, etc...
My recommendation would actually be to separate your data from your display code. So, instead of having x1, x2, y1, and y2 declared as static global variables, have them part of the inner class (what you call ContentComponent, and have a starting x1, x2, y1, y2 values as your global variables, like this: