2016-03-31 2 views
0

Hier habe ich zwei Klassen:JFrame Ausfahrten vor TextPane gesetzt

Testklasse:

public class test { 
    private static JPanel contentPane; 
    private static JFrame frame = new JFrame("Sleeping"); 
    private static JTextPane textPane; 
    private static StyledDocument doc; 
    private static Thread sleep; 
    private static HandleMouse S = new HandleMouse(); 

public static void main(String[] args) { 

    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 
    frame.setBounds(0, 0, 450, 300); 
    contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    contentPane.setLayout(new BorderLayout(0, 0)); 
    frame.setContentPane(contentPane); 
    frame.setLocationRelativeTo(null); 

    JPanel panel = new JPanel(); 
    contentPane.add(panel, BorderLayout.CENTER); 
    panel.setLayout(new BorderLayout(0, 0)); 

    textPane = new JTextPane(); 
    panel.add(textPane, BorderLayout.CENTER); 

    doc = textPane.getStyledDocument(); 
    SimpleAttributeSet center = new SimpleAttributeSet(); 
    StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); 
    doc.setParagraphAttributes(doc.getLength() + 1, 1, center, false); 

    textPane.setEditable(false); 
    sleep = new Thread(() -> { 
     try { 
      textPane.setBackground(new Color(59, 82, 217)); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "Waiting for sleep, I drift from thoughts like these;\n", null); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "And where to-day was dream-like, build my dreams.\n", null); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "Across my brain, ghost of remembered chords\n ", null); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "Which still can make such radiance in my dream.\n", null); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "And count their faces; faces; sunlit faces.\n", null); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "Falling asleep ... the herons, and the hounds....\n", null); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "September in the darkness; and the world I've known\n", null); 
      Thread.sleep(1200); 
      doc.insertString(doc.getLength(), "all fading past me into peace. ", null); 

     } catch (BadLocationException | InterruptedException e) { 

     } 
    }); 

    frame.setResizable(false); 
    frame.setVisible(true); 
    sleep.start(); 

    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    textPane.addMouseMotionListener(S); 
    frame.addMouseMotionListener(S); 

} 

} 

und eine andere innere Klasse, die in der Testklasse ist, die die Bewegung der Maus Griffe:

public static class HandleMouse implements MouseMotionListener { 

    @Override 
    public synchronized void mouseDragged(MouseEvent e) { 
     textPane.setText("Test"); 
     ifinterrupt(); 
    } 

    @Override 
    public synchronized void mouseMoved(MouseEvent e) { 
     textPane.setText("Test"); 
     ifinterrupt(); 

    } 

    private void ifinterrupt() { 
     sleep.interrupt(); 
     textPane.removeMouseMotionListener(S); 
     frame.removeMouseMotionListener(S); 
     textPane.setBackground(Color.RED); 
     try { 
      Thread.sleep(1000); 
      System.exit(0); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Wenn ich jedoch meine Maus bewege und die Methode mouseMoved auslöst, wird der JFrame beendet (System.exit(0)), bevor diese Zeile ausgeführt wird:

textPane.setText("Test"); 

aber in der Theorie sollte es um den Text zu "Test" vor dem Beenden gesetzt, wie setText vor der ifinterrupt() Linie festgelegt ist:

textPane.setText("Test"); 
ifinterrupt(); 

Meine Frage ist, warum die JFrame Ausfahrt vor dem Text gesetzt und Was verursacht es?

Jede Hilfe wird geschätzt.

+0

nicht über statische verwenden Sie erstellen; Verwenden Sie keine Null-Layouts. blockieren Sie nicht das Ereignis, das Thread sendet – MadProgrammer

+0

Das Problem ist mit Ihrem ifintergrut(); Sie rufen 'Thread.sleep()' auf, das den aktuellen Thread blockiert, bevor Sie die Benutzeroberfläche neu malen –

+1

@Joseph Das Problem ist überall im Code, das OP verletzt die Singlethread-Natur von Swing – MadProgrammer

Antwort

1

Wenn Sie 1sec warten die GUI neu gerendert, um zu sehen, nicht das EDT blockieren, sondern um einen neuen Timer statt und schließen Sie Ihren Rahmen in diesem Timer

 Thread r = new Thread() { 
      public void run() { 
       try { 
        sleep(1000); 
        System.exit(0); 
       } catch (InterruptedException e) { 
       } 
      }; 
     }; 
     r.start(); 
1

Wenn Sie etwas auf der GUI ändern möchten, sollten Sie EDT (Event Dispatch Thread) verwenden. ALLE Interaktionen mit einer UI/Swing-Komponente MÜSSEN im Kontext des EDT erfolgen

Beim Starten einer Anwendung sollten Sie sicherstellen, dass Sie innerhalb des EDT ausgeführt werden, BEVOR Sie versuchen, eine Swing-Komponente zu erstellen/interagieren.

Verwenden Sie diesen Code. Der folgende Thread wird als Ereignisbehandlungs-Thread bezeichnet. Schreiben Sie die Codes, die Änderungen in der Benutzeroberfläche innerhalb dieses Threads vornehmen, oder rufen Sie die Methode auf, die den Code aus diesem Thread enthält.

EventQueue.invokeLater(new Runnable() { 
    public void run() { 
     // Now in the event dispatching thread 
    } 
}); 

EDT wird Ihre Änderungen auf der Benutzeroberfläche in die Warteschlange stellen und entsprechend der Priorität ausführen.

+0

Außer wenn Interrupt in der EDT aufgerufen wird, Damit wird verhindert, dass das ui aktualisiert wird, bevor System.exit aufgerufen wird: P – MadProgrammer

+0

Code war bereits in EDT –