#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.
Комментариев нет:
Отправить комментарий