gpt4 book ai didi

java - 在 JTabbedPane 上触发 stateChanged 事件

转载 作者:行者123 更新时间:2023-12-04 04:47:19 26 4
gpt4 key购买 nike

我有带有淡入淡出动画的 JTabbedPane,当用户单击选项卡时执行。为了处理动画,我覆盖了 stateChanged方法。

public class AnimatedJTabbedPane extends JTabbedPane implements ChangeListener, TimingTarget{

/**
*
*/
private static final long serialVersionUID = 1L;
protected BufferedImage previousTabImage;
protected BufferedImage bufferImage;
protected BufferedImage nextTabImage;
protected boolean animationStarted = false;
protected boolean paintPreviousImage = false;
protected boolean leftToRightIndex = false;
protected float fraction = 0.0f;
protected Animator animator;
protected int previousTabIndex = -1;

public AnimatedJTabbedPane(int tabPlacement) {
super(tabPlacement);

this.animator = new Animator(300, this);
this.animator.setAcceleration(0.1f);
this.animator.setDeceleration(0.8f);
this.addChangeListener(this);
}

public void stateChanged(ChangeEvent e) {

if(this.previousTabIndex != this.getSelectedIndex()){
if(this.previousTabIndex == -1){
this.previousTabIndex = this.getSelectedIndex();
}
else{
this.paintPreviousImage = true;
boolean interrupted = false;
if(this.animator.isRunning()){
this.animator.stop();
interrupted= true;
}

Component previousComponent = this.getComponentAt(this.previousTabIndex);

this.previousTabImage = this.getGraphicsConfiguration().createCompatibleImage(
previousComponent.getWidth(), previousComponent.getHeight(), Transparency.TRANSLUCENT);

previousComponent.paint(this.previousTabImage.getGraphics());

Component nextComponent = this.getComponentAt(this.getSelectedIndex());
this.nextTabImage = this.getGraphicsConfiguration().createCompatibleImage(
previousComponent.getWidth(), previousComponent.getHeight(), Transparency.TRANSLUCENT);

nextComponent.paint(this.nextTabImage.getGraphics());

if(this.previousTabIndex < this.getSelectedIndex()){
this.leftToRightIndex = true;
}
else{
this.leftToRightIndex = false;
}

this.previousTabIndex = this.getSelectedIndex();
if(interrupted){
this.animator.setStartFraction(1-this.fraction);
}
else{
this.animator.setStartFraction(0);
}
this.animationStarted = true;
this.animator.start();
}
}
}


@Override
public void paintChildren(Graphics g){
if(this.getComponentCount() != 0){
Rectangle childrenPosition = this.getComponentAt(0).getBounds();

if(this.bufferImage == null ||
this.bufferImage.getWidth() != this.getWidth() ||
this.bufferImage.getHeight() != this.getHeight()){
this.bufferImage = new BufferedImage(
this.getWidth(),
this.getHeight(),
BufferedImage.TYPE_INT_ARGB);
}

if(this.animationStarted){
if(this.paintPreviousImage){
g.drawImage(this.bufferImage, 0, 0, null);
this.paintPreviousImage = false;
}
else{
Graphics2D g2d = (Graphics2D)this.bufferImage.createGraphics();
int x = (int)childrenPosition.getX();
int y = (int)childrenPosition.getY();

this.performFadeAnimation(g2d, x, y);

g.drawImage(this.bufferImage, 0, 0, null);
g2d.dispose();
}
g.dispose();
}
else{
Graphics2D g2d = (Graphics2D)this.bufferImage.createGraphics();

super.paintChildren(g2d);
g.drawImage(this.bufferImage, 0, 0, null);
g2d.dispose();
g.dispose();
}
}
else{
super.paintChildren(g);
}
}


protected void performFadeAnimation(Graphics2D g2d, final double x, final double y){
g2d.drawImage(this.previousTabImage, (int)x, (int)y, null);

AlphaComposite composite =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, this.fraction);
g2d.setComposite(composite);

g2d.drawImage(this.nextTabImage, (int)x, (int)y, null);
}

@Override
public void begin() {
// TODO Auto-generated method stub
}

@Override
public void end() {
this.animationStarted = false;
this.repaint();
this.nextTabImage.flush();
this.nextTabImage = null;
this.previousTabImage.flush();
this.previousTabImage = null;
}

@Override
public void repeat() {
// TODO Auto-generated method stub
}

@Override
public void timingEvent(float fraction) {
this.fraction = fraction;
this.repaint();
}

}

当用户手动单击选项卡时,这很有效。 stateChanged事件被调用并且选项卡随着动画而变化。

我需要从代码中更改选定的选项卡,所以我使用 setSelectedIndex(int)方法。
public void setSelectedTab(int tab){
animatedTabbedPane.setSelectedIndex(tab);
}

但是现在标签在 setSelectedIndex 之后立即更改结束 - 没有动画,然后 stateChanged方法被调用,因此选项卡切换回以前选择的选项卡并执行(正确)我的动画。

所以选项卡改变了两次,第一次在 setSelectedIndex 之后没有动画之后的第二次 stateChangedAnimatedJTabbedPane .

我需要类似的东西:
 animatedTabbedPane.firePropertyChange("stateChanged", old, new);

我只想用 stateChanged 更改标签方法,所以我可以不用默认 setSelectedIndex方法。我该怎么做?

编辑
我的问题的一个小图表:

enter image description here

红线代表可见性。因此,当用户仅更改选项卡时 stateChanged被调用时,选项卡 0 平滑地更改为选项卡 1。当我使用 setSelectedIndex 时选项卡 0 立即被选项卡 1 替换,只有这样我才能从 stateChanged 看到我想要的动画,让用户看到一闪。

最佳答案

我找到了问题的真正原因。

这是线程问题,而不是动画本身。我在打电话 setSelectedIndex外面 EDT 所以我的 JTabbedPane 立即更新,然后动画来自 EDT 进行了。

答案是:

public void setSelectedTab(final int tab) throws InterruptedException, InvocationTargetException{
if(!SwingUtilities.isEventDispatchThread()){
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
animatedTabbedPane.setSelectedIndex(tab);
}
});
}
else
animatedTabbedPane.setSelectedIndex(tab);
}

更改内部标签 EDT 不再需要不必要的闪光。

关于java - 在 JTabbedPane 上触发 stateChanged 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17992512/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com