Анимация для изменения цвета JComponent. / Write animation for JComponent to change colors from rectangles' color to grey slowly

159
02 июля 2018, 20:40

Я хочу сделать анимацию для изменения цвета JComponent с любого на серый в течении 5 секунд. / I want to make an animation which would change JComponent's color from any color to grey and then back, but slowly, for 5 seconds.

class PBtn extends JComponent {
private LinkedList<MyBtn> myBtns = new LinkedList<>();
LinkedList<MyBtn> getMyBtns(){
    return myBtns;
}

static class MyBtn extends Rectangle {
    String name;
    Color color;
    MyBtn(int x, int y, int width, int height, String name, Color color) {
        this.setBounds(x, y, width, height);
        this.color = color;
    }

}
void addBtn(int x, int y, int width, int height, String name, Color color) {
    MyBtn myBtn = new MyBtn(x, y, width, height, name, color);
    this.addMouseMotionListener(new MouseMotionListener() {
        @Override
        public void mouseDragged(MouseEvent e) {
        }
        @Override
        public void mouseMoved(MouseEvent e) {
            if (myBtn.contains(e.getPoint())) {
                setToolTipText(name);
            }
            ToolTipManager.sharedInstance().mouseMoved(e);
        }
    });
    myBtns.add(myBtn);
    repaint();
}
void clearBtns() {
    myBtns.clear();
    repaint();
}
@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D graphics2D = (Graphics2D) g;
    myBtns.forEach(n -> {
        graphics2D.setColor(n.color);
        graphics2D.draw(n);
        graphics2D.fill(n);
    });
}
Answer 1

Если речь об изменении цвета объектов Rectangle внутри JComponent, (а я так понял, что именно это и требуется) то можно решить так:
(см. комментарии в коде)

static class MyBtn extends Rectangle {
String name;
Color color;
Color defaultColor;
JComponent parent;
//---вспомогательные переменные---
private Timer timer;
//Пригодятся временные переменные цвета
private float R;
private float G;
private float B;
//шаг, необходимый каждому цвету для достижения серого
private float deltaR; 
private float deltaG;
private float deltaB;
MyBtn(int x, int y, int width, int height, String name, Color compColor, JComponent parent) {
    this.setBounds(x, y, width, height);
    this.color = compColor;
    defaultColor = compColor;
    this.parent = parent;
    R = compColor.getRed();
    G = compColor.getGreen();
    B = compColor.getBlue();
    /*
     * шаг вычисляется как:
     * (Начальный цвет - Серый цвет)/Время(мс)
     * p.s. Для шагов, расписаных на каждую миллисекунду, в течение 5 секунд, время было бы 5000,
     * но так как для каждого цвета создаётся новый объект, то для снижения нагрузки, 
     * было принято решение рассчитывать шаги хотя бы в 10мс интервале
     * */
    deltaR = -(compColor.getRed() - 199)/500f; 
    deltaG = -(compColor.getGreen() - 199)/500f;
    deltaB = -(compColor.getBlue() - 199)/500f;
    timer = new Timer(10, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            //(теоретически, новые объекты можно было бы организовать в пул, но я решил не усложнять алгоритм)
            //вычисление нового цвета
            R = Math.abs(R+deltaR);
            G = Math.abs(G+deltaG);
            B = Math.abs(B+deltaB);
            //плодить новые объекты - плохая мысль, но awt.Color не поддерживает настройку..
            color = new Color((int)R, (int)G, (int)B);
            //если достигнут серый цвет, дельта меняет знак, и начинается перекрашивание обратно
            if(isGray()) {
                deltaR = -deltaR;
                deltaG = -deltaG;
                deltaB = -deltaB;
            }
            //если достигнут дефолт, таймер останавливается
            if(isDefault()) {
                deltaR = -deltaR;
                deltaG = -deltaG;
                deltaB = -deltaB;
                timer.stop();
            }
            parent.repaint();
        }
    });
}
private boolean isGray() {
    //из-за особенностей хранения float в памяти, обычные проверки тут не подходят
    boolean redEqual = Math.abs(R - 199)<0.1f;
    boolean greenEqual = Math.abs(G - 199)<0.1f;
    boolean blueEqual = Math.abs(B - 199)<0.1f;
    return redEqual&&greenEqual&&blueEqual;
}
private boolean isDefault() {
    boolean redEqual = Math.abs(R - defaultColor.getRed())<0.1f;
    boolean greenEqual = Math.abs(G - defaultColor.getGreen())<0.1f;
    boolean blueEqual = Math.abs(B - defaultColor.getBlue())<0.1f;
    return redEqual&&greenEqual&&blueEqual;
} 
public void changeColor() {
    //блокировка повторных запусков, пока не истекут 5 секунд
    if(!timer.isRunning()) {
        timer.start();
    }
}

}

READ ALSO
Сравнение BigDecimal

Сравнение BigDecimal

Даны две точки и середина между нимиПочему результат сравнения неверный? Изначально я использовал тип double, оказалось, что он не очень подходит...

199
Ошибка с FirebaseListAdapter

Ошибка с FirebaseListAdapter

При компиляции кода выдает ошибку:

194
Как можно отобразить несколько точек на mapView если координаты этих точек находятся в бд firebase?

Как можно отобразить несколько точек на mapView если координаты этих точек находятся в бд firebase?

Есть база данных, куда приходят данные о местоположение пользователя

175
Не создается файл в java

Не создается файл в java

Создаю файл таким вот кодомНо, как ни стараюсь, не получается создать файл, хотя выполняется код без ошибок

171