我有一个JFrame,带有两个面板,在一个面板中我绘制一条线,当我工作时我最小化了我正在做的java程序的窗口,当我最大化它的线条,我DREW是不同的,它在另一个地方重新粉刷它!
有没有人知道如何锁定这幅画,这样当我最小化它时不会搞砸图画?
谢谢!
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){}
}
答案 0 :(得分:1)
我认为当我最小化它然后最大化它时,程序自动绘制是不正常的。
这种情况发生是很正常的。只要系统需要重绘窗口的一部分,就可以随时在 调用paint
方法(有关具体细节,请参阅Painting in AWT)。当您最小化窗口时,无论您在之前绘制的是什么都未保存,所以当您最大化窗口时,需要再次绘制所有内容,因此将调用paint
自动。
因此,您不应在paint
中对数据执行任何更新。您应该在单独的方法中执行这些操作,将结果存储在变量中,仅使用这些现有结果来绘制内容。
由于以下部分不会改变:
image = ImageIO.read(new File("image name and path"));
x1+=20;
x2+=20;
y2+=50;
x2+=30;
将它们移到一个单独的方法中,比如updatePoints
。然后在actionPerformed
方法中,先致电updatePoints()
,然后致电repaint()
。
答案 1 :(得分:0)
您可以向jframe添加一个窗口侦听器,在触发resize / maximize / whatever事件时调用面板绘制方法。
答案 2 :(得分:0)
基本上,只是为了添加casablanca所说的,发生的事情是因为你的x1,x2,y1,y2变量是静态的,所以每次执行绘画时它们都会更新,然后保持该值直到下一次重画,然后再次更新等等......
我的建议实际上是将您的数据与显示代码分开。因此,不要将x1,x2,y1和y2声明为静态全局变量,而是将它们作为内部类的一部分(您称之为ContentComponent,并将起始x1,x2,y1,y2值作为全局变量,如这样:
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 final int sx1 = 0, sy1 = 0, sx2 = 0, sy2 = 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 {
static int x1, x2, y1, y2;
public void paint(Graphics g) {
x1 = sx1;
x2 = sx2;
y1 = sy1;
y2 = sy2;
// 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;
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) {}
}