【问题标题】:automatic repaint when minimizing window最小化窗口时自动重绘
【发布时间】:2010-11-18 21:01:22
【问题描述】:

我有一个 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){}  
}

【问题讨论】:

  • 好的我已经通过在paint方法中添加线条的初始坐标来解决它,所以它在我最大化窗口后在完全相同的位置绘制线条,所以它看起来像没啥事儿。但如果有人知道如何锁定它,我仍然想知道。
  • 你不是很清楚你想要什么? “锁定”是什么意思?
  • 最小化窗口时不重绘。如果我最小化窗口然后最大化它,我看不到初始绘图,线条出现在不同的位置。我像这样画线 x1+=20; x2+=20; y2+=50; g.drawLine(x1,y1,x2,y2);所有坐标的初始值都是0。这些x1等是全局变量,所以这就是为什么当我最小化它时它会在不同的地方重新绘制它......我认为当我最小化它然后程序自动绘制它是不正常的最大化它。
  • 你能给我们一个完整的例子吗?如果我对您的代码外观有更多了解,我可能会给您一个提示。我的直觉是,使用 += 修饰符,每次重绘时,实际上都是在重新计算线条的位置。只是重绘并不像你想象的那么频繁。
  • 在我发布后我提到了我提到的解决方案之后就有代码!但是必须重置变量似乎很愚蠢,因为当我最小化它时会自动重新绘制!!

标签: java graphics jframe jpanel paint


【解决方案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()

【讨论】:

    【解决方案2】:

    您可以向 jframe 添加一个窗口侦听器,当触发调整大小/最大化/任何事件时调用面板绘制方法。

    【讨论】:

      【解决方案3】:

      基本上,补充一下 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) {}
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多