如何使用 Timer 动态调整帧大小?
我正在尝试使用 Timer 对象动态调整窗口大小,但没有成功...我在构造函数中设置了面板的首选大小,它很好地设置了窗口的大小,尽管只有一次.程序初始化后首选大小会发生变化,但窗口大小保持不变.为什么?因为构造函数只初始化一次,因此不受大小变化的影响?如果是这样,我该如何解决这个问题以实时调整窗口大小?
I'm trying to resize a window dynamically using a Timer object, but not succeeding... I set the preferred size of the panel in the constructor, which sets the size of the window nicely, though only once. The preferred size changes after the program is initialized, but the window size stays the same. Why? Because the constructor is initialized only once and therefore isn't affected by the size change? If so, how could I get around this to resize the window in real-time?
我知道这不会解决开头评论中给出的练习中的问题,所以请忽略它:-)
I know this won't solve the problem in the exercise given in the beginning comments, so please ignore that :-)
/*
* Exercise 18.15
*
* "(Enlarge and shrink an image) Write an applet that will display a sequence of
* image files in different sizes. Initially, the viewing area for this image has
* a width of 300 and a height of 300. Your program should continuously shrink the
* viewing area by 1 in width and 1 in height until it reaches a width of 50 and
* a height of 50. At that point, the viewing area should continuously enlarge by
* 1 in width and 1 in height until it reaches a width of 300 and a height of 300.
* The viewing area should shrink and enlarge (alternately) to create animation
* for the single image."
*
* Created: 2014.01.07
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Ex_18_15 extends JApplet {
// Main method
public static void main(String[] args) {
JFrame frame = new JFrame();
Ex_18_15 applet = new Ex_18_15();
applet.isStandalone = true;
frame.add(applet);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
// Data fields
private boolean isStandalone = false;
private Image image = new ImageIcon("greenguy.png").getImage();
private int xCoordinate = 360;
private int yCoordinate = 300;
private Timer timer = new Timer(20, new TimerListener());
private DrawPanel panel = new DrawPanel();
// Constructor
public Ex_18_15() {
panel.setPreferredSize(new Dimension(xCoordinate, yCoordinate));
add(panel);
timer.start();
}
class DrawPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
}
class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if(yCoordinate <= 50) {
yCoordinate++;
xCoordinate++;
}
else if(yCoordinate >= 300) {
yCoordinate--;
xCoordinate--;
}
panel.setPreferredSize(new Dimension(xCoordinate, yCoordinate));
repaint();
}
}
}
推荐答案
你需要重新打包你的 JFrame 来调整它的大小.例如在 ActionListener 的末尾:
You need to re-pack your JFrame to resize it. For instance at the end of your ActionListener:
Window win = SwingUtilities.getWindowAncestor(panel);
win.pack();
给你一个问题:为什么你的类是扩展 JApplet 而不是 JPanel?或者如果它需要是一个小程序,你为什么要把它塞进一个 JFrame 中?
A question for you though: Why in heaven's name is your class extending JApplet and not JPanel? Or if it needs to be an applet, why are you stuffing it into a JFrame?
编辑
关于您的评论:
Edit
Regarding your comment:
它通常不是扩展 JFrame 而不是 JPanel 吗?我将它填充到 JFrame 中以允许它作为应用程序和小程序运行.这就是Java 编程简介"告诉我如何做到这一点的方式:p 在 actionPerformed 方法的末尾添加代码对我没有任何作用;o
Wouldn't it usually be extending JFrame not JPanel? I'm stuffing it into a JFrame to allow it to run as an application as well as an applet. That's how 'Introduction to Java Programming' tells me how to do it :p Adding your code at the end of the actionPerformed method didn't do anything for me ;o
您的大部分 GUI 代码都应该用于创建 JPanel,而不是 JFrame 或 JApplets.然后,您可以毫无困难地将您的 JPanel 放置在需要和需要的地方.您的书存在严重问题,如果它告诉您这一点,则不应被信任.
Most of your GUI code should be geared towards creating JPanels, not JFrames or JApplets. You can then place your JPanels where needed and desired without difficulty. Your book has serious issues and should not be trusted if it is telling you this.
编辑 2
为我工作:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class ShrinkingGui extends JPanel {
private static final int INIT_W = 400;
private static final int INIT_H = INIT_W;
private static final int TIMER_DELAY = 20;
private int prefW = INIT_W;
private int prefH = INIT_H;
public ShrinkingGui() {
new Timer(TIMER_DELAY, new TimerListener()).start();;
}
public Dimension getPreferredSize() {
return new Dimension(prefW, prefH);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (prefW > 0 && prefH > 0) {
prefW--;
prefH--;
Window win = SwingUtilities.getWindowAncestor(ShrinkingGui.this);
win.pack();
} else {
((Timer)e.getSource()).stop();
}
}
}
private static void createAndShowGUI() {
ShrinkingGui paintEg = new ShrinkingGui();
JFrame frame = new JFrame("Shrinking Gui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(paintEg);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
相关文章