面板(JPanel)的滑动效果

4

我尝试创建一个简单的类,可以像这样滑动JPanel:

+----------+    +------+---+    +----------+
|          |    |      |   |    |          |
| JPanel1  | => | JPane| JP| => | JPanel2  |
|          |    |      |   |    |          |
+----------+    +------+---+    +----------+

我创建了javax.swing.Timer,并将其添加到类中。

timer = new Timer(50, this);
timer.start();

static final int frames = 5;
int counter = 0;

actionPerformed(ActionEvent e) {
    if (counter >= frames) {
        timer.stop();
        counter = 0;
    } else {
        counter++;
        jPanel2.setBounds(800 - 800 * counter / frames, 0, 800, 600);
    }
}

这是一个工作,但速度很慢。我只有2-3 fps,而且不知道如何加速这种方法。能帮我吗?

1个回答

12

可能将计时器的间隔从50更改为一些小于50的数字。

例如,从这个值:

timer = new Timer(50, this);

变成这样:

timer = new Timer(10, this);

注意: 在这里应避免使用魔数。

实际上,像这样的东西...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SlideEg extends JPanel {
   private SlideContainer slideContainer = new SlideContainer();

   public SlideEg() {
      setLayout(new BorderLayout());
      add(slideContainer, BorderLayout.CENTER);

      JLabel helloLabel = new JLabel("Hello", SwingConstants.CENTER);
      slideContainer.add(helloLabel);

      Timer myTimer = new Timer(5000, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            JLabel goodbyeLabel = new JLabel("Goodbye", SwingConstants.CENTER);
            goodbyeLabel.setOpaque(true);
            goodbyeLabel.setBackground(Color.pink);
            slideContainer.add(goodbyeLabel);
         }
      });
      myTimer.setRepeats(false);
      myTimer.start();
   }

   private static void createAndShowGui() {
      SlideEg mainPanel = new SlideEg();

      JFrame frame = new JFrame("SlideEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class SlideContainer extends JLayeredPane {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private static final int SLIDE_DELAY = 20;
   protected static final int DELTA_X = 2;
   Component oldComponent;

   public SlideContainer() {
      setLayout(null);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   public Component add(Component comp) {
      Component[] comps = getComponents();
      if (comps.length > 0) {
         oldComponent = comps[0];
      }
      if (oldComponent == comp) {
         return super.add(comp);
      }
      if (oldComponent != null) {
         putLayer((JComponent) oldComponent, JLayeredPane.DEFAULT_LAYER);
      }
      Component returnResult = super.add(comp);
      putLayer((JComponent) comp, JLayeredPane.DRAG_LAYER);
      comp.setSize(getPreferredSize());
      comp.setVisible(true);
      comp.setLocation(getPreferredSize().width, 0);
      slideFromRight(comp, oldComponent);
      return returnResult;
   }

   private void slideFromRight(final Component comp,
         final Component oldComponent2) {
      new Timer(SLIDE_DELAY, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent aEvt) {
            int x = comp.getX();
            if (x <= 0) {
               comp.setLocation(0, 0);
               putLayer((JComponent) comp, JLayeredPane.DEFAULT_LAYER);
               if (oldComponent2 != null) {
                  remove(oldComponent2);
               }
               ((Timer) aEvt.getSource()).stop();
            } else {
               x -= DELTA_X;
               comp.setLocation(x, 0);
            }
            repaint();
         }
      }).start();
   }
}

2
不,50就是20帧每秒,不是2或3。 - 11684
我在这个问题中更改了所有变量。在实际代码中,我避免使用魔法数字。我尝试了不同的时间/帧率,但没有帮助。而且这个实验是在空 JPanel 中进行的。 - pushistic
1
@pushistic:考虑发布一个最小的代码示例,展示你的问题,即SSCCE。这将使我们能够运行您的代码并修改它,甚至可能纠正它。在回复之前,请阅读链接,因为它提供了有关SSCCE要求的许多重要细节。 - Hovercraft Full Of Eels
@hovercraft-full-of-eels 谢谢!当我尝试编写SSCCE时,我看到了你的例子并找到了我的问题。我使用的是JPanel而不是JLayeredPane作为父组件。如果我的构造中有2个或更多的JPanel,性能会出现很大问题。 - pushistic
@Hovercraft Full Of Eels 又有一个问题需要您的好主意 - mKorbel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接