2016-07-28 10 views
4

非常に珍しい状況が続きます。私は、メソッド "getSelectedScreenSize"を持つクラス "ScreenSizeSelector"を持っています。メソッドの作業はUIを作成し、ユーザーはUIをドラッグしてウィンドウのサイズを返します。ボタンをクリックすると新しいJFrameが無効になっています。

今、私は次の方法でクラスのメソッドを呼び出しています:

  1. 単純なクラス(非GUI)のJFrame
  2. 最初のケースで

からボタンクリックで

  • 、それは完璧に動作しています(つまり、サイズセレクタウィンドウが開き、ユーザがドラッグしてサイズを変更し、ウィンドウ座標を戻しています)が、2番目のケースではウィンドウが開きますが、無効モードでは、ウィンドウを閉じることさえできません。すべてのヘルプは高く評価され

    package screenrecorder; 
    
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    
    import javax.swing.JButton; 
    import javax.swing.JFrame; 
    
    public class Test2 extends JFrame{ 
    
        public Test2(){ 
    
         JButton btn = new JButton("Click ME"); 
         btn.addActionListener(new ActionListener() { 
    
          @Override 
          public void actionPerformed(ActionEvent e) { 
           System.out.println(new ScreenSizeSelector().getSelectedScreenSize()); 
    
          } 
         }); 
    
         getContentPane().add(btn); 
         setSize(100,100); 
         setVisible(true); 
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    
        } 
    
        public static void main(String[] args){ 
         new Test2(); 
        } 
    
    } 
    

    package screenrecorder; 
    
    import java.awt.BorderLayout; 
    import java.awt.Color; 
    import java.awt.Dimension; 
    import java.awt.FlowLayout; 
    import java.awt.Rectangle; 
    import java.awt.Toolkit; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.awt.event.WindowEvent; 
    import java.awt.event.WindowListener; 
    
    import javax.swing.BorderFactory; 
    import javax.swing.ImageIcon; 
    import javax.swing.JButton; 
    import javax.swing.JFrame; 
    import javax.swing.JPanel; 
    import javax.swing.border.Border; 
    
    
    class ScreenSizeSelector { 
    
        private JFrame sizeSelectorWindow; 
        private JButton btnOk; 
        private Border emptyBorder; 
        private Rectangle screenArea = null; 
        private static Object lock = new Object(); 
    
    
    
        public Rectangle getSelectedScreenSize(){ 
    
         screenSizeSelectorUI(); 
    
         Thread t = new Thread() { 
          public void run() { 
           synchronized(lock) { 
            while (sizeSelectorWindow.isVisible()) 
             try { 
              lock.wait(); 
             } catch (InterruptedException e) { 
              e.printStackTrace(); 
             } 
           } 
          } 
         }; 
    
         t.start(); 
         try { 
          t.join(); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
    
         return screenArea; 
        } 
    
    
        public void screenSizeSelectorUI() { 
         emptyBorder = BorderFactory.createEmptyBorder(); 
    
         sizeSelectorWindow = new JFrame("Select screen area"); 
    
         btnOk = new JButton("Start"); 
         sizeSelectorWindow.setUndecorated(true); 
         sizeSelectorWindow.getRootPane().setWindowDecorationStyle(3); 
         sizeSelectorWindow.setBackground(new Color(0, 0, 0, 0)); 
         sizeSelectorWindow.setSize(400,400); 
    
         sizeSelectorWindow.addWindowListener(new WindowEventHandler()); 
         sizeSelectorWindow.setAlwaysOnTop(true); 
         sizeSelectorWindow.setLocationRelativeTo(null); 
    
    
         btnOk.setToolTipText("Click this button after deciding the screen area"); 
         btnOk.addActionListener(new ButtonEventHandler()); 
    
    
         JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 
         buttonPanel.setBackground(new Color(0,0,0,0)); 
         buttonPanel.add(btnOk); 
         sizeSelectorWindow.add(buttonPanel,BorderLayout.SOUTH); 
    
         sizeSelectorWindow.setVisible(true); 
         sizeSelectorWindow.setEnabled(true); 
    
        } 
    
    class ButtonEventHandler implements ActionListener { 
    
    @Override 
    public void actionPerformed(ActionEvent e) { 
    
        int x = (int)(sizeSelectorWindow.getBounds().getX()); 
        int y = (int) (sizeSelectorWindow.getBounds().getY()); 
        int width = sizeSelectorWindow.getWidth(); 
        int height = sizeSelectorWindow.getHeight(); 
    
        screenArea = new Rectangle(x,y,width,height); 
        sizeSelectorWindow.dispatchEvent(new WindowEvent(sizeSelectorWindow, WindowEvent.WINDOW_CLOSING)); 
    } 
    
    
    } 
    
    class WindowEventHandler implements WindowListener{ 
    
        @Override 
        public void windowOpened(WindowEvent e) { 
        } 
    
        @Override 
        public void windowClosing(WindowEvent e) { 
    
         synchronized (lock) { 
          sizeSelectorWindow.setVisible(false); 
          lock.notify(); 
         } 
        } 
    
        @Override 
        public void windowClosed(WindowEvent e) { 
        } 
    
        @Override 
        public void windowIconified(WindowEvent e) { 
         sizeSelectorWindow.setState(JFrame.NORMAL); 
         Toolkit.getDefaultToolkit().beep(); 
        } 
    
        @Override 
        public void windowDeiconified(WindowEvent e) {} 
    
        @Override 
        public void windowActivated(WindowEvent e) {} 
    
        @Override 
        public void windowDeactivated(WindowEvent e) {} 
    
    
        } 
    
    } 
    

    のTest1クラス:

    package screenrecorder; 
    
    import java.awt.Rectangle; 
    
    public class Test1{ 
    
        public static void main(String[] args){ 
         System.out.println(new ScreenSizeSelector().getSelectedScreenSize()); 
        } 
    } 
    

    にTest2クラスここ

    は私が

    ScreenSizeSelectorクラスを使用していたコードです。

  • +0

    コードをデバッグすると、例外が表示されますか? –

    +0

    デバッグ中に例外は発生しません。 –

    +0

    EDT(EventDispatchThreadに関するOracleのチュートリアルの詳細)、Thread t = new Thread()の代わりにSwing Timerを使用する{ – mKorbel

    答えて

    0

    ボタンをクリックすると、アクションリスナーはgetSelectedScreenSize()関数が戻るのを待ちます。 getSelectedScreenSize()関数は、screenSelectorUI()によって作成された2番目のウィンドウが非表示になるのを待機しています。 screenSelectorUI()は、第二のウィンドウを作成しますが、このような色設定:あなたは色のコンストラクタのjavadocを見れば

    sizeSelectorWindow.setBackground(new Color(0, 0, 0, 0)); 
    

    public Color(int r, 
           int g, 
           int b, 
           int a) 
    

    が指定された赤、緑を使ってsRGBカラーを生成します、青、アルファ値の範囲(0〜255)です。
    パラメータ:

    • R - 赤色成分
    • グラム - 緑成分
    • B - 青色成分
    • - アルファ成分

    アルファ値を0に設定すると、完全に非表示になります。 (アルファ値は透明です)また、この2番目のウィンドウは装飾されておらず、閉じても終了しないので、それはまったく存在しないことさえありません。

    私が得意でないことは、test1がどのように動作したかです。 サイドノート:私が試してみると、それはボタンを表示するだけで、私ができるのはクリックだけです。ボタンは消えますが、アプリケーションはまだ実行されています。

    これは基本的には完全に推測ですが、多くのスイングコンポーネントはコマンドではなくオペレーティングシステムに要求します。私は400、400にリサイズしてもらえますか? OSは技術的にあなたが言うことをする必要はありません。私はHow does Java handle multithreading?を読んでいました。マルチスレッドは実際にはOSに依存していると言われています。 screenSelectorUI()が単独で呼び出されたときに、どこかでうんざりする気がしますが、何らかのボタンのスレッド内にあるときに何らかの形でそれを正しく取得します。

    +0

    こんにちは、UIが表示されます(Test1とI窓でも同じように走った)。背景は透明ですが、フレームの枠が表示されます。ボタンとフレームの境界線が表示されます。 –

    関連する問題