2014-01-07 3 views
2

Я пытаюсь динамически изменять размер окна с помощью объекта 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, чтобы он запускался как приложение, так и апплет. Вот как «Введение в Java Programming» говорит мне, как это сделать: р Добавление кода в конце метода actionPerformed ничего не делает для меня, о

Большинство кода GUI должны быть направлены на создание JPanels, а не JFrames или JApplets. Затем вы можете без труда разместить свои JPanels там, где это необходимо и желательно. У вашей книги серьезные проблемы, и ей не следует доверять, если она вам это говорит.


Edit 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, чтобы он запускался как приложение, так и апплет. Вот как «Введение в программирование на Java» говорит мне, как это сделать: p Добавление вашего кода в конце метода actionPerformed для меня ничего не делало o – hatakeK

+0

До сих пор (глава 18) все классы GUI расширили JFrame , Тем не менее, я делал очень маленькие программы с графическим интерфейсом. Спасибо за понимание! – hatakeK

+0

@hatakeK: см. Правки, чтобы ответить пожалуйста. –

Смежные вопросы