Страницы

Поиск по вопросам

воскресенье, 26 января 2020 г.

Проблема с обновлением компонентов

#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.

Комментариев нет:

Отправить комментарий