2012-04-07 6 views
1

Dies ist ein seltsames Problem. Ich habe eine Lösung dafür, aber ich weiß nicht, WARUM das Problem an erster Stelle auftritt. Beachten Sie den folgenden Code:Das Hinzufügen von JFileChooser ohne Aktion führt dazu, dass Panels nicht gerendert werden

// VERSION 1 

public class test { 

    public static void main(String[] args) { 
     JFrame mainFrame = new JFrame("Test"); 
     JPanel inputPanel = new JPanel(); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel); 
     mainFrame.setBounds(100, 50, 200, 100); 
     mainFrame.setVisible(true); 

     JButton inputFileButton = new JButton("BROWSE"); 
     inputPanel.add(inputFileButton); 
    } 
} 

Es funktioniert wie erwartet. Die Schaltfläche tut nichts, aber es wird korrekt gerendert. Jetzt füge ich einen JFileChooser hinzu (mit dem ich etwas später machen möchte, aber jetzt mache ich es nur instanziieren).

Plötzlich rendert meine Schaltfläche nicht mehr. Warum? Ich kenne zwei Möglichkeiten, um es wieder zum Laufen zu bringen, aber mir macht das keinen Sinn. Ein Weg, um es zu beheben:

// VERSION 3 

public class test { 

    public static void main(String[] args) { 
     JFrame mainFrame = new JFrame("Test"); 
     JPanel inputPanel = new JPanel(); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel); 
     mainFrame.setBounds(100, 50, 200, 100); 
     mainFrame.setVisible(true); 

     JButton inputFileButton = new JButton("BROWSE"); 
     inputPanel.add(inputFileButton); 

     JFileChooser inputFileChooser = new JFileChooser(); // MOVE LINE TO END 
    } 
} 

so dass Zeile am Ende bewegen können Sie die Taste erneut machen, aber das macht noch keinen Sinn für mich, was ein instanziiert JFileChooser mit unverbundener Taste zu tun hat. Eine andere Art, wie ich dieses Problem beheben können:

// VERSION 4 

public class test { 

    public static void main(String[] args) { 
     JFrame mainFrame = new JFrame("Test"); 
     JPanel inputPanel = new JPanel(); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel); 
     mainFrame.setBounds(100, 50, 200, 100); 

     JFileChooser inputFileChooser = new JFileChooser(); 

     JButton inputFileButton = new JButton("BROWSE"); 
     inputPanel.add(inputFileButton); 

     mainFrame.setVisible(true); // MOVE *THIS* LINE TO THE END    
    } 
} 

Es Art von Sinn macht, warum die Version über das Problem behebt ... offensichtlich etwas über die JFileChoose Instanziierung machte meine Taste unsichtbar, aber diese setVisible() -Methode danach bringen es zurück ins Licht. Aber das sagt mir immer noch nicht, WARUM es überhaupt unsichtbar wurde.

Kann mir bitte jemand helfen herauszufinden, was ich vermisse? Vielen Dank!

+3

1) Erstellen und aktualisieren Sie immer die GUI auf dem EDT. 2) Rufen Sie 'setBounds()' oder 'setSize()' nicht auf, rufen Sie stattdessen 'pack()' auf. 3) Die Reihenfolge ist wichtig. a) Fügen Sie Komponenten hinzu b) 'pack()' c) 'setLocationRelativeTo()' (falls erforderlich) d) 'setVisible (true)' –

Antwort

5

Sie machen Ihre mainFrame sichtbar und fügen die Schaltfläche anschließend hinzu. Werfen Sie einen Blick auf this SO question, welche Schritte Sie ergreifen müssen, um sicherzustellen, dass Ihre Schaltfläche sichtbar ist.

Der Grund, warum es in Ihrem ersten Beispiel funktioniert, ist wahrscheinlich reines Glück. Ihr Aufruf zum Hinzufügen der Schaltfläche wird ausgeführt, bevor der EDT Ihre Komponente anzeigt.

Hinweis: Bitte führen Sie die Swing-Operationen am EDT durch

+0

Danke. Ich bin neu in der EDT-Konzept, aber von einigen schnellen Recherchen, die ich getan habe, klingt es wie ich muss nur explizit auf die EDT verweisen, wenn ich in einem anderen Thread bin. Gab es in meinen obigen Beispielen NICHT "Swing-Operationen auf dem EDT?" Ich verstehe jetzt besser die Sequenz, der ich folgen sollte, dank deiner und Andrews Antworten, nur um sicherzustellen, dass ich nichts anderes über den EDT vergesse. – The111

+1

Ihre Hauptmethode wird in einem anderen Thread ausgeführt, sodass keine Swing-Operationen auf dem EDT ausgeführt werden. Sie sollten einen 'SwingUtilities.invokeLater' Aufruf in Ihrer Hauptmethode verwenden, um Ihre UI zu erstellen. Das Muss-Tutorial ist [dieses] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) – Robin

Verwandte Themen