繁体   English   中英

窗口大小调整事件

[英]Window Resize event

我有一个程序可以将图像缩放到屏幕大小。 我目前有一个组件侦听器侦听 componentResized 事件,但这不是我想要的。 我希望该方法仅被称为用户从鼠标上抬起手指的方法,而不是在他们调整大小时调用。 这样,我的图像就不会根据用户的规格不断调整大小。

谢谢!

一种解决方案是提供一个 Swing Timer ,每次调用componentResized都会重置它。 这会在最后一次调整大小事件和您应该执行调整大小操作的时间之间注入一个小的延迟。

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();
}

这基本上是设置它,以便在尝试调整图像大小之前,调整大小事件之间需要 250 毫秒。 您可以使用该值来满足您自己的需求。

更新了可运行的示例

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();
            }
        }
    }

}

注意:本示例中使用的缩放不是我的首选方法,仅用于演示目的。 有关详细信息,请参阅Image.getScaledInstance() 的危险将 ImageIcon 自动缩放到标签大小以获取替代方法...

如果你把Toolkit.getDefaultToolkit().setDynamicLayout(false); 就在 main 内部,当您增加/减少它的大小时,它将禁止框架动态更新。 用户界面只有在您停止调整大小后才会更新。

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