#java #swing
Хочу создать анимацию во фрейме, которой можно управлять. Создаю класс AnimatedComponent: class AnimatedComponent extends JComponent { private static final long serialVersionUID = 1L; public AnimatedComponent() { Timer timer = new Timer( 30, action -> repaint() ); timer.start(); } @Override public Dimension getPreferredSize() { return new Dimension( 300, 200 ); } @Override public void paintComponent( Graphics g ) { // animation } } Во фрейм я введу экземпляр класса AnimatedComponent и другие компоненты, которые будут влиять на его отображение: class AnimatedFrame extends JFrame { private static final long serialVersionUID = 1L; private AnimatedComponent animatedComponent = new AnimatedComponent(); private JCheckBox check1 = new JCheckBox("check1"); private JCheckBox check2 = new JCheckBox("check2"); private JSlider slider1 = new JSlider( 0, 200, 50 ); private JSlider slider2 = new JSlider( 0, 200, 50 ); private JSlider slider3 = new JSlider( 0, 200, 50 ); public AnimatedFrame() { setLayout( new GridBagLayout() ); add( animatedComponent, new GBC(0,0,1,5).setFill(GBC.BOTH).setWeight(0.5, 0.5) ); add( check1, new GBC(1,0,2,1).setAnchor(GBC.CENTER) ); add( check2, new GBC(1,1,2,1).setAnchor(GBC.CENTER) ); add( new JLabel("SLider1"), new GBC(1,2).setAnchor(GBC.EAST) ); add( slider1, new GBC(2,2).setFill(GBC.BOTH).setWeight(0.1, 0.5) ); add( new JLabel("Slider2"), new GBC(1,3).setAnchor(GBC.EAST) ); add( slider2, new GBC(2,3).setFill(GBC.BOTH).setWeight(0.1, 0.5) ); add( new JLabel("Slider3:"), new GBC(1,4).setAnchor(GBC.EAST) ); add( slider3, new GBC(2,4).setFill(GBC.BOTH).setWeight(0.1, 0.5) ); } public static void main(String... args) { EventQueue.invokeLater(new Runnable(){ @Override public void run() { AnimatedFrame frame = new AnimatedFrame(); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } } Код класса GBC: class GBC extends GridBagConstraints { private static final long serialVersionUID = 1L; public GBC(int gridx, int gridy) { this.gridx = gridx; this.gridy = gridy; } public GBC(int gridx, int gridy, int gridwidth, int gridheight) { this.gridx = gridx; this.gridy = gridy; this.gridwidth = gridwidth; this.gridheight = gridheight; } public GBC setAnchor(int anchor) { this.anchor = anchor; return this; } public GBC setFill(int fill) { this.fill = fill; return this; } public GBC setWeight(double weightx, double weighty) { this.weightx = weightx; this.weighty = weighty; return this; } } Можете сами убедиться, что программа работает некорректно. Запустите код на выполнение. Не растягивайте окно по вертикали и растяните по горизонтали. Сейчас попробуйте изменить состояние JSlider-ов или JCheckBox-ов. Они начинают отображаться неправильно. Если после этого опять изменить размер фрейма, то компоненты перерисуются правильно. Если же изменить расположение компонентов, то проблема исчезнет: public AnimatedFrame() { setLayout( new GridBagLayout() ); add( animatedComponent, new GBC(2,0,1,5).setFill(GBC.BOTH).setWeight(0.5, 0.5) ); add( check1, new GBC(0,0,2,1).setAnchor(GBC.CENTER) ); add( check2, new GBC(0,1,2,1).setAnchor(GBC.CENTER) ); add( new JLabel("SLider1"), new GBC(0,2).setAnchor(GBC.EAST) ); add( slider1, new GBC(1,2).setFill(GBC.BOTH).setWeight(0.1, 0.5) ); add( new JLabel("Slider2"), new GBC(0,3).setAnchor(GBC.EAST) ); add( slider2, new GBC(1,3).setFill(GBC.BOTH).setWeight(0.1, 0.5) ); add( new JLabel("Slider3:"), new GBC(0,4).setAnchor(GBC.EAST) ); add( slider3, new GBC(1,4).setFill(GBC.BOTH).setWeight(0.1, 0.5) ); } Кажется мне, что это как-то связано с постоянной перерисовкой компонента animatedComponent. Объясните, пожалуйста, подробно, почему так происходит, и как правильно обойти эту проблему?
Ответы
Ответ 1
Добавьте в конец конструктора AnimatedFrame() код: check1.setMinimumSize( check1.getPreferredSize() ); check2.setMinimumSize( check2.getPreferredSize() ); slider1.setMinimumSize( slider1.getPreferredSize() ); slider2.setMinimumSize( slider2.getPreferredSize() ); slider3.setMinimumSize( slider3.getPreferredSize() ); Компоненты перестают схлопываться и ресайзинг происходит довольно прилично IMHO.
Комментариев нет:
Отправить комментарий