1

それが言う場所: usePanel.setLocation(800,usePanel.getY()); 途中で開始する場所を設定するのではなく、クールなアニメーションの位置を徐々に変更する for ループ内では、正常に動作します。

それを開始するための最初に設定された場所が機能しない理由は何ですか? これはところでFlowLayoutの下にあるので、何か関係があるかもしれないと思いますが、よくわかりません。

        usePanel.setLocation(800,usePanel.getY());
        for(int x=0;x<3500;x+=6){
            usePanel.setLocation(usePanel.getX()-5,usePanel.getY());
            Thread.sleep(500);
        }

現在のコードで更新

private Timer nextloc;
private JPanel usePanel;
private static ClosePanel cp = new ClosePanel("null");

public void run(){
    Timer andgo = new Timer(10,new TimerListener());
    while(!cp.getCloseDone()){
        andgo.start();
        andgo.restart();
    }
    if(panel.equals("topiccreator")){
        usePanel=topiccreator;
    }else{
        System.out.println("NULL PANEL TO MOVE!");
        usePanel=mainmenu;
    }

            //This is what is not working
    usePanel.setLocation(usePanel.getX()+800,usePanel.getY());
    usePanel.setVisible(true);

    nextloc = new Timer(50,new TimerListener());
    for(int r=0;r<3500;r+=6){
        nextloc.start();
        nextloc.restart();
    }
}

private class TimerListener implements ActionListener{
    public void actionPerformed(ActionEvent e){
        if(e.getSource()==nextloc){
            usePanel.setLocation(usePanel.getX()-5,usePanel.getY());
        }
    }
}
4

2 に答える 2

2

を呼び出すThread.sleepことで、ペイント要求の処理などを担当するイベント ディスパッチ スレッドをブロックする可能性があります。これは、ループが実際に終了するまで、EDT がパネルの更新された場所を処理できないことを意味します。

代わりに、javax.swing.Timer...

詳細については、Swing の同時実行を確認してください。

更新しました

これはところでFlowLayoutの下にあるので、何か関係があるかもしれないと思いますが、よくわかりません

revalidateレイアウト マネージャーと戦っている場合、使用しているコンテナーusePanelが配置されると、レイアウト マネージャーがコンポーネントを配置したい場所に再配置されることがわかります。

より良い解決策については、Sliding-Layoutをご覧ください。

基本的な例で更新

アニメーションは、時間の経過に伴う変化の錯覚です。Swing では、UI の更新に関して、開発者にかなり厳しい要件を課しています。

レイアウト マネージャーなどとは別に、Swing では、UI に対するすべての対話と変更を、イベント ディスパッチ スレッドのコンテキスト内で行う必要があります。また、長時間実行またはブロック プロセスは、EDT 以外の別のスレッドで実行する必要があります。

これにより、キャッチ 22 に置かれます。バックグラウンドで実行する必要があるため、EDT によるペイント リクエストの処理を (とりわけ) 停止することはありませんが、EDT のコンテキスト内からコンポーネントを更新する必要があります...

幸いなことに、利用可能なソリューションは多数あります。あなたの問題に対する最も簡単な方法は、javax.swing.Timer

ここに画像の説明を入力

この例では、ルート ペインのグラス ペイン機能を使用して、上にスライド アウトを提供します。詳細については、ルート ペインの使用方法を参照してください。

また、可変タイミング アニメーションを使用します。つまり、パネルの位置は、一定のデルタではなく、アニメーションの時間の進行に基づいています。

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class SlidingPane {

    private SlidePane slidePane = new SlidePane();

    public static void main(String[] args) {
        new SlidingPane();
    }

    public SlidingPane() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JButton slideButton = new JButton("Slide");
                slideButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        slidePane.slide();
                    }
                });

                JFrame frame = new JFrame("Testing");

                JPanel glassPane = new JPanel(null);
                glassPane.setOpaque(false);
                glassPane.add(slidePane);
                frame.setGlassPane(glassPane);
                glassPane.setVisible(true);

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                frame.add(new JLabel("Look ma, no hands!"), gbc);
                frame.add(slideButton, gbc);
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class SlidePane extends JPanel {

        private long startTime = -1;
        private int runTime = 1000;
        private int startX;
        private int targetX;
        private boolean slideIn = false;
        private Timer slideTimer;

        public SlidePane() {
            setBackground(Color.DARK_GRAY);
            setBorder(new LineBorder(Color.BLACK));
            setLocation(-getPreferredSize().width, 0);
            setLayout(new GridBagLayout());
            JLabel label = new JLabel("I'm your overload");
            label.setForeground(Color.WHITE);
            add(label);
            slideTimer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    long diff = System.currentTimeMillis() - startTime;
                    double progress = (double)diff / (double)runTime;
                    if (progress >= 1d) {
                        progress = 1d;
                        slideTimer.stop();
                        startTime = -1;
                    }

                    Container parent = getParent();
                    int height = parent.getHeight();
                    setSize(getPreferredSize().width, height);

                    int x = calculateProgress(startX, targetX, progress);
                    setLocation(x, 0);
                    revalidate();
                    repaint();
                }
            });
        }

        protected int calculateProgress(int startValue, int endValue, double fraction) {

            int value = 0;
            int distance = endValue - startValue;
            value = (int) Math.round((double) distance * fraction);
            value += startValue;

            return value;

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 400);
        }

        public void slide() {

            slideTimer.stop();
            startTime = System.currentTimeMillis();

            slideIn = !slideIn;
            startX = getX();
            targetX = 0;
            if (!slideIn) {
                targetX = -getPreferredSize().width;
            }

            slideTimer.start();

        }
    }
}
于 2013-09-29T21:33:02.067 に答える
0

なぜ機能していないと思いますか?おそらくあなたはそれに気づくことはできません。最初setPosition()に次のコードを追加した後:

Thread.sleep(3000);

すると、気づくでしょう。

于 2013-09-29T21:28:54.340 に答える