有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

最小化窗口时的java自动重新绘制

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

共 (3) 个答案

  1. # 1 楼答案

    基本上,只是为了补充卡萨布兰卡所说的,现在发生的事情是,由于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) {}
    }
    
  2. # 2 楼答案

    I think it is not normal for the program to auto paint when i minimized it and then maximized it.

    这是很正常的。只要系统需要重新绘制窗口的一部分,就可以在的任何时间调用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()

  3. # 3 楼答案

    您可以向jframe添加一个窗口侦听器,在触发resize/maximize/Anything事件时调用panels paint方法