我有一个程序,将图像缩放到屏幕大小。我目前有一个组件侦听器侦听componentResized事件,但这不是我想要的。我希望这种方法只能被称为用户抬起手指而不是他们正在调整大小的方式。这样,我的图像将不会不断调整到用户的规格。窗口大小事件
谢谢!
我有一个程序,将图像缩放到屏幕大小。我目前有一个组件侦听器侦听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();
}
}
}
}
注:在本例中使用的比例是不是我的首选方法,仅用于演示目的已完成。详情请参阅The Perils of Image.getScaledInstance(); Scale the ImageIcon automatically to label size更改方法...
我明白你来自哪里,你能举个例子吗? –
也许这可以帮到你? http://stackoverflow.com/questions/10229292/get-notified-when-the-user-finishes-resizing-a-jframe – anonymous
@ chris13524我更新了一个例子的轮廓... – MadProgrammer
您是否试过MouseListener(或MouseAdapter)并实现mouseReleased(MouseEvent e)方法?然后,获取新尺寸并重新绘制新尺寸的图像? – anonymous
我正在考虑这一点,但随后每次点击时都会尝试调整大小。 –