swingAan de slag met swing


Opmerkingen

Swing is vervangen door JavaFX . Oracle raadt over het algemeen aan om nieuwe toepassingen met JavaFX te ontwikkelen. Toch: Swing zal in de nabije toekomst worden ondersteund in Java. JavaFX kan ook goed worden geïntegreerd met Swing, zodat toepassingen soepel kunnen worden overgezet.

Het wordt ten zeerste aanbevolen om de meeste van uw Swing-componenten op de Event Dispatch Thread te hebben. Het is gemakkelijk om te vergeten uw GUI-instellingen te bundelen in een invokeLater gesprek. Uit de Java-documentatie:

Swing event handling code draait op een speciale thread die bekend staat als de event dispatch-thread. De meeste code die Swing-methoden oproept, wordt ook op deze thread uitgevoerd. Dit is nodig omdat de meeste Swing-objectmethoden niet "thread-safe" zijn: ze aanroepen vanuit meerdere threads, kunnen thread-interferentie of geheugenconsistentiefouten inhouden. Sommige methoden van Swing-componenten zijn in de API-specificatie "thread safe" genoemd; deze kunnen veilig worden opgeroepen vanuit elke thread. Alle andere Swing-componentmethoden moeten worden opgeroepen vanuit de gebeurtenisverzendingsdraad. Programma's die deze regel negeren, kunnen meestal correct functioneren, maar zijn onderhevig aan onvoorspelbare fouten die moeilijk te reproduceren zijn.

Zorg er ook, tenzij om een goede reden, altijd voor dat je setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE) hebt gebeld, anders krijg je mogelijk te maken met een geheugenlek als je vergeet de JVM te vernietigen.

"Hallo Wereld!" op venstertitel met compatibiliteit

Met behulp van java.lang.Runnable we onze "Hallo wereld!" voorbeeld beschikbaar voor Java-gebruikers met versies die helemaal teruggaan tot versie 1.2:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Main {
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run(){
                JFrame frame = new JFrame("Hello World!");
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setSize(200, 100);
                frame.setVisible(true);
            }
        });
    }
}
 

"Hallo Wereld!" op venstertitel met lambda

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Hello World!");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setSize(200, 100);
            frame.setVisible(true);
        });
    }
}
 

In de main methode:
Op de eerste regel wordt SwingUtilities.invokeLater aangeroepen en wordt een lambda-expressie met een codeblok () -> {...} doorgegeven. Hiermee wordt de doorgegeven lambda-expressie op de EDT uitgevoerd, wat staat voor Event Dispatch Thread, in plaats van de hoofdthread. Dit is nodig, omdat er binnen het codeblok van de lambda-expressie Swing-componenten worden gemaakt en bijgewerkt.

Binnen het codeblok van de lambda-expressie:
Op de eerste regel wordt een nieuwe JFrame instantie met de naam frame gemaakt met behulp van een new JFrame("Hello World!") . Dit maakt een vensterinstantie met "Hallo wereld!" op zijn titel. Daarna wordt het frame op de tweede regel geconfigureerd als EXIT_ON_CLOSE . Anders wordt het venster gewoon gesloten, maar de uitvoering van het programma blijft actief. De derde regel configureert de frame instantie 200 pixels breed en 100 pixels hoog met de methode setSize . Tot nu toe zal de uitvoering helemaal niets laten zien. Pas nadat setVisible(true) op de vierde regel is setVisible(true) , is de frame instantie geconfigureerd om op het scherm te verschijnen.

Verhogen met een knop

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

/**
 * A very simple Swing example.
 */
public class SwingExample {
    /**
     * The number of times the user has clicked the button.
     */
    private long clickCount;
    
    /**
     * The main method: starting point of this application.
     *
     * @param arguments the unused command-line arguments.
     */
    public static void main(final String[] arguments) {
        new SwingExample().run();
    }

    /**
     * Schedule a job for the event-dispatching thread: create and show this
     * application's GUI.
     */
    private void run() {
        SwingUtilities.invokeLater(this::createAndShowGui);
    }
    
    /**
     * Create the simple GUI for this application and make it visible.
     */
    private void createAndShowGui() {
        // Create the frame and make sure the application exits when the user closes
        // the frame.
        JFrame mainFrame = new JFrame("Counter");
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        // Add a simple button and label.
        JPanel panel = new JPanel();
        JButton button = new JButton("Click me!");
        JLabel label = new JLabel("Click count: " + clickCount);
        panel.add(button);
        panel.add(label);
        mainFrame.getContentPane().add(panel);
        
        // Add an action listener to the button to increment the count displayed by
        // the label.
        button.addActionListener(actionEvent -> {
            clickCount++;
            label.setText("Click count: " + clickCount);
        });
        
        // Size the frame.
        mainFrame.setBounds(80, 60, 400, 300);
        //Center on screen
        mainFrame.setLocationRelativeTo(null);
        //Display frame
        mainFrame.setVisible(true);
    }
}
 

Resultaat

Zoals de knop met het label "Click me!" wordt ingedrukt, wordt het aantal klikken met één verhoogd:

Lopend programma