1

FullScreenスクリーンショットのロジックを含むクラスと、写真のクリック効果FullScreenGUIをシミュレートするロジックを含むクラスの2つを作成しました。

フォトクリック効果は、基本的に、スクリーンショットが撮影されてから50ミリ秒後に、画面を短時間、たとえば白色で点滅させることです。JFrame画面全体を不透明度1%のaで覆うことで作成されます。背景を白くした後、不透明度を1%から100%に変更し、50ミリ秒間そのままにしてから、1%に戻します。

コンストラクターは2つのFullScreenパラメーターを取ります。1つはスクリーンショットを撮る回数用で、もう1つはその間の期間用です。

FullScreenGUIを構築し、それJFrameを最大化し、背景を白に設定します。メソッドが呼び出されると、fire()効果を生み出すために必要に応じて不透明度が変更されます。

質問:

以下のコードを使用して、スクリーンショットを初めて撮ったときに効果を出すことができますが、それ以降のクリックではできません。コンストラクFullScreenターがパラメーターを使用して呼び出されたとすると(4,2)(つまり、2秒間にそれぞれ4回クリックする)、最初のクリックでは効果がうまく生成されますが、残りの3回のクリックでは効果が生成されません。JFrameのがFullScreenGUI前面に出ていないように見えるので、効果は見えません。私は試しましJFrame.setAlwaysOnTop(true)たが、彼らはトップJFrame.toFront()に持ってこないようです。JFrame

スクリーンショットを撮るのに問題はありませんが、代わりに効果があります。それを生み出すための他のアイデアはありますか?

コードは次のとおり です。FullScreen.java

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.Timer;
import javax.swing.filechooser.FileSystemView;

class FullScreen
{   
    int times, duration;
    Timer t;
    Robot r;
    BufferedImage bi;
    FullScreenGUI fg;

FullScreen(int tim, int duration) 
{
    fg = new FullScreenGUI();
    fg.setVisible(true);
    this.times = tim;
    this.duration = duration;
    try {
        r = new Robot();
    } catch (AWTException e) {
        e.printStackTrace();
    }
    System.out.println("Inside constructor");
    t = new Timer(duration*1000, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {

            System.out.println("Inside action");
            if(times>0)
            {
                System.out.println("times: "+times);

                //Get the screenshot
                bi = capture();

                //Gives the path of the home directory. For windows, it'll go to your desktop
                FileSystemView filesys = FileSystemView.getFileSystemView();
                File fl = filesys.getHomeDirectory();
                saveImage(bi, fl);

                //Produces the "clicking" effect
                fg.setAlwaysOnTop(true);
                fg.toFront();
                fg.fire();

                times--;
            }
            else
                t.stop();
        }
    });
}

public void fire()
{
    t.start();
}

public void saveImage(BufferedImage source, File destination)
{
    System.out.println("Inside saveimage");
    if(destination.isDirectory())
    {
        System.out.println("destination: "+destination.getAbsolutePath());
        String tmp = destination.getAbsolutePath() + File.separator + "Screenshot";
        String str;
        int i=1;
        for(str=tmp; (new File(str+".png").exists()); i++)
        {
            str = tmp + "_" + String.valueOf(i);
            System.out.println("trying: "+str);
        }

        try {
            ImageIO.write(source, "png", new File(str+".png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public BufferedImage capture()
{
    System.out.println("Captured");
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    return r.createScreenCapture(new Rectangle(d));
}

public static void main(String arg[])
{
    //click 4 times each at an interval of 2 seconds
    FullScreen f = new FullScreen(4,2);

    f.fire();
    while(f.t.isRunning());
}
}

FullScreenGUI.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class FullScreenGUI extends JFrame {

FullScreenGUI()
{
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setUndecorated(true);
    setResizable(false);
    setOpacity(0.01f);
    setAlwaysOnTop(true);

    setLayout(new BorderLayout());
    JLabel jl = new JLabel();
    jl.setBackground(Color.white);
    add(jl);        

    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public void fire()
{
    System.out.println("click");
    setVisible(true);

    try{

    setOpacity(1f);
    Thread.sleep(50);
    setOpacity(0.1f);

    }catch(Exception e) { e.printStackTrace(); }

    setVisible(false);
}

}
4

1 に答える 1

4

問題の原因はThread.sleep(50);です。

EDT(イベントディスパッチスレッド)をブロックしないでください-それが発生すると、GUIは「フリーズ」します。呼び出す代わりに、このタスクThread.sleep(n)のSwingを実装します。Timer詳細については、Swingでの同時実行を参照してください。

于 2012-12-24T11:35:29.537 に答える