2014-01-07 82 views
2

我想使用Timer對象動態調整窗口大小,但沒有成功......我在構造函數中設置了面板的首選大小,它很好地設置了窗口的大小,儘管只有一次。程序初始化後,首選大小會發生變化,但窗口大小保持不變。爲什麼?由於構造函數僅初始化一次,因此不受大小更改的影響?如果是這樣,我怎麼能解決這個實時調整窗口?如何使用Timer動態調整框架大小?

我知道這不會解決在開始評論給出的行使問題,所以請忽略:-)

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

} 

回答

5

您需要重新收拾你的JFrame調整其大小。比如在你的ActionListener結束:

Window win = SwingUtilities.getWindowAncestor(panel); 
win.pack(); 

一個問題要問你,雖然:在天堂的名字爲什麼你的類擴展JApplet的,而不是JPanel的?或者如果它需要成爲一個小程序,爲什麼你把它填充到JFrame中?


編輯
關於你的評論:

豈不通常可以不延長JFrame的JPanel的?我將它填充到JFrame中,以允許它作爲應用程序以及applet運行。 'Java編程入門'告訴我如何去做:p在actionPerformed方法的末尾添加代碼對我沒有任何幫助;

大部分的GUI代碼都應該朝向創建JPanel,而不是JFrame或JApplet。然後,您可以毫無困難地將您的JPanel放在需要和想要的地方。你的書有嚴重的問題,如果它告訴你這些,就不應該信任它。


編輯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(); 
     } 
     }); 
    } 
} 
+0

難道它通常被延長JFrame的JPanel的不是?我將它填充到JFrame中,以允許它作爲應用程序以及applet運行。這就是'Java編程入門'告訴我如何去做:p 在actionPerformed方法的末尾添加你的代碼對我沒有任何幫助; – hatakeK

+0

到目前爲止(第18章)所有的GUI類都有擴展的JFrame 。也就是說,我只做過非常小的GUI程序。感謝您的洞察! – hatakeK

+0

@hatakeK:請參閱編輯回答。 –