简体   繁体   English

窗口大小调整事件

[英]Window Resize event

I have a program that scales an image to the size of the screen.我有一个程序可以将图像缩放到屏幕大小。 I currently have a component listener listening for a componentResized event, but this is not what I want.我目前有一个组件侦听器侦听 componentResized 事件,但这不是我想要的。 I would like the method to only be called one the user lift's there finger off their mouse, not as they are doing the resizing.我希望该方法仅被称为用户从鼠标上抬起手指的方法,而不是在他们调整大小时调用。 This way, my image will not constantly be resizing to the user's specifications.这样,我的图像就不会根据用户的规格不断调整大小。

Thanks!谢谢!

A solution is to supply a Swing Timer which is reset each time componentResized is called.一种解决方案是提供一个 Swing Timer ,每次调用componentResized都会重置它。 This injects a small delay between the last resize event and the time you should perform the resize action.这会在最后一次调整大小事件和您应该执行调整大小操作的时间之间注入一个小的延迟。

import javax.swing.Timer;
//...
// Declare an instance variable...
private Timer resizeTimer;
//...
// Probably in you classes constructor
resizeTimer = new Timer(250, new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        // Actually perform the resizing of the image...
        resizeBackgroundImage();
    }
});
// Don't want a repeating event...
resizeTimer.setRepeats(false);

//...
public void componentResized(ComponentEvent evt) {
    resizeTimre.restart();
}

This basically, sets it up so that it will require 250 milliseconds between resize events before an attempt is made to resize the image.这基本上是设置它,以便在尝试调整图像大小之前,调整大小事件之间需要 250 毫秒。 You can play around with the value to suit your own needs.您可以使用该值来满足您自己的需求。

Updated with runnable example更新了可运行的示例

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class RescaleTest {

    public static void main(String[] args) {
        new RescaleTest();
    }

    public RescaleTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage master;
        private Image scaled;

        private Timer resizeTimer;

        public TestPane() {
            try {
                master = ImageIO.read(new File("/path/to/your/image"));
                scaled = master;
            } catch (IOException exp) {
                exp.printStackTrace();
            }

            resizeTimer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    resizeBackground();
                }
            });
            resizeTimer.setRepeats(false);

            addComponentListener(new ComponentAdapter() {

                @Override
                public void componentResized(ComponentEvent e) {
                    resizeTimer.restart();
                }

            });
        }

        protected void resizeBackground() {
            // This is not my preferred scaling process, I prefer to use
            // a divide and conqure approach and do so in the background
            // where possible, but this is beyond the scope of the question...
            if (getWidth() < getHeight()) {
                scaled = master.getScaledInstance(getWidth(), -1, Image.SCALE_SMOOTH);
            } else {
                scaled = master.getScaledInstance(-1, getHeight(), Image.SCALE_SMOOTH);
            }
            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            return master != null ? new Dimension(master.getWidth(), master.getHeight()) : new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (scaled != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - scaled.getWidth(this)) / 2;
                int y = (getHeight() - scaled.getHeight(this)) / 2;
                g2d.drawImage(scaled, x, y, this);
                g2d.dispose();
            }
        }
    }

}

nb: The scaling used in this example is not my preferred method and was done for demonstration purposes only.注意:本示例中使用的缩放不是我的首选方法,仅用于演示目的。 See The Perils of Image.getScaledInstance() for details and Scale the ImageIcon automatically to label size for an alterantive approach...有关详细信息,请参阅Image.getScaledInstance() 的危险将 ImageIcon 自动缩放到标签大小以获取替代方法...

If you put Toolkit.getDefaultToolkit().setDynamicLayout(false);如果你把Toolkit.getDefaultToolkit().setDynamicLayout(false); right inside of main it will disable the frame from updating dynamically as you increase/decrease it's size.就在 main 内部,当您增加/减少它的大小时,它将禁止框架动态更新。 The ui will only be updated after you stop resizing.用户界面只有在您停止调整大小后才会更新。

import MainMenu.GameManager;

import java.awt.*;
import java.io.IOException;

public class Main {

    Main(){

    }
        public static void main(String[] args) throws IOException {
            GameManager manager = new GameManager();
            Toolkit.getDefaultToolkit().setDynamicLayout(false);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM