Я хочу сделать анимацию для изменения цвета 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);
});
}
Если речь об изменении цвета объектов 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();
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Даны две точки и середина между нимиПочему результат сравнения неверный? Изначально я использовал тип double, оказалось, что он не очень подходит...
Есть база данных, куда приходят данные о местоположение пользователя
Создаю файл таким вот кодомНо, как ни стараюсь, не получается создать файл, хотя выполняется код без ошибок