2014-06-23 9 views
8

Próbuję utworzyć rodzaj paska narzędzi w nieodnowionej ramce alwaysOnTop. Dlatego chcę, aby moja ramka znajdowała się na mojej głównej ramce, ale nie na ramkach innych programów. Próbowałem ten kod:Ramka zawsze na szczycie mojego programu tylko

public class Test { 
    private static JFrame mainFrame; 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       mainFrame = new JFrame("test"); 
       mainFrame.setSize(800,600); 
       mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       mainFrame.setVisible(true); 

       A a = new A(); 
      } 
     }); 
    } 

    public static class A extends JDialog { 

     public A() { 
      super(mainFrame); 
      setAlwaysOnTop(true); 
      setFocusable(false); 
      setSize(80,60); 
      setVisible(true); 
     } 
    } 
} 

Ale mimo stosowania JDialog i doprecyzowanie właściciela, pobyt ramki na wierzchu innych aplikacji (przynajmniej w Ubuntu Może wynik jest inny z innego systemu operacyjnego.?)

EDIT: Ok, próbowałem ten kod dla mojego okna:

public static class A extends JDialog { 

    public A(String name) { 
     super(mainFrame, name); 
     setAlwaysOnTop(true); 
     setFocusable(false); 
     setSize(80, 60); 
     setVisible(true); 

     mainFrame.addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowActivated(WindowEvent e) { 
       A.this.setAlwaysOnTop(true); 
      } 

      @Override 
      public void windowDeactivated(WindowEvent e) { 
       // A.this.setAlwaysOnTop(false); 
       A.this.toBack(); 
      } 
     }); 
    } 
} 

problem jest teraz, że gdy okno główne luźne ostrości, okno kradnie ostrość z powrotem, a ja nie rozumiem dlaczego. Na przykład uruchamiam moją aplikację, staram się przełączyć na Firefox, pojawia się Firefox i obejmuje mainFrame, ale okno dialogowe A dostaje fokus i pozostaje na ekranie. Teraz, jeśli ponownie wybiorę Firefoksa, okno dialogowe ostatecznie zniknie. Czy możesz mi wyjaśnić, dlaczego dialog się skupia?

Dzięki

+0

myślę, że trzeba uciekać się do korzystania jakieś rodzimej włamania poprzez JNI/JNA – MadProgrammer

+0

'klasa A rozszerza JFrame'? –

+0

co się stanie, jeśli usuniesz 'setAlwaysOnTop()'? Zwykle ramka powinna pozostać na wierzchu innych klatek. 'SetAlwaysOnTop()' ustawia flagę dla OS – GameDroids

Odpowiedz

4

Ok, znalazłem rozwiązanie (nie wiem czy to jest rozwiązanie, ale to działa, więc ...)

odkryłem setFocusableWindowState(), który jest idealny dla pasków narzędzi. Przy okazji, nie wiem, czy mój poprzedni setFocusable (false) miał jakikolwiek efekt.

Kolejnym problemem było to, że celem staje się bardzo dziwne zachowanie z tym kodem: Jeśli mogę przełączyć z MojaApl do Firefoksa, oto co się dzieje:

focus : MyApp -> Firefox 
execution of MyDialog.toFront() 
focus : Firefox -> MyDialog 
MyDialog not focusable ! 
focus : MyDialog -> MyApp !!! 

wynik: nic się nie zmieniło!

Więc w końcu dostałem sztuczki: tuż po MyDialog.toFront(), zwracasz fokus do poprzedniego właściciela. A jedynym sposobem znalazłem to zrobić bez błędu: mainFrame.toBack()

kod końcowa:

public class Test { 
    private static JFrame mainFrame; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       mainFrame = new JFrame("test"); 
       mainFrame.setSize(800,600); 
       mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       mainFrame.setVisible(true); 

       A a = new A(); 
      } 
     }); 
    } 

    public static class A extends JDialog { 

     public A() { 
      super(mainFrame); 
      setAlwaysOnTop(true); 
      setFocusableWindowState(false); 
      setSize(80,60); 
      setVisible(true); 

      mainFrame.addWindowListener(new WindowAdapter() { 
       @Override 
       public void windowActivated(WindowEvent e) {A.this.setAlwaysOnTop(true);} 
       @Override 
       public void windowDeactivated(WindowEvent e) { 
        A.this.toBack(); 
        mainFrame.toBack(); 
       } 
      }); 
     } 
    } 
} 
+0

Potwierdziłem to rozwiązanie w systemie Windows 10. Dzięki –

4

Należy dokonać okno zawsze na wierzchu tylko gdy okno rodzic idzie aktywnym. Coś takiego:

public class Test { 
    private static JFrame mainFrame; 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       mainFrame = new JFrame("test"); 
       mainFrame.setSize(800,600); 
       mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       mainFrame.setVisible(true); 

       final A a = new A(); 
       mainFrame.addWindowListener(new WindowAdapter() { 
        /** 
        * {@inheritDoc} 
        */ 
        @Override 
        public void windowDeactivated(WindowEvent e) { 
         a.setAlwaysOnTop(false); 
        } 

        /** 
        * {@inheritDoc} 
        */ 
        @Override 
        public void windowActivated(WindowEvent e) { 
         a.setAlwaysOnTop(true); 
        } 
       }); 
      } 
     }); 
    } 

    public static class A extends JDialog { 

     public A() { 
      super(mainFrame); 
      setAlwaysOnTop(true); 
      setFocusable(false); 
      setSize(80,60); 
      setVisible(true); 
     } 
    } 
} 
+0

. Spróbujmy tego w moim prawdziwym programie. Dam ci znać. – Sharcoux

+0

Ok. Próbowałem twojego podejścia. nie działa z setAlwaysOnTop (false), ale robi to za pomocą toBack(). Niemniej jednak nadal mam mały problem. Zobacz moją edycję. I dzięki za pomoc! – Sharcoux

+0

@ user1967800, gdy ramka jest na wierzchu, kradnie fokus. Musisz więc ustawić wartość alwaysOnTop na wartość false. –

Powiązane problemy