Swing (Java) - Swing (Java)

Image
Eksempel Swing -widgets i Java

Swing er en GUI -widget -værktøjskasse til Java . Det er en del af Oracle 's Java Foundation Classes (JFC) - et API til at levere en grafisk brugergrænseflade (GUI) til Java -programmer.

Swing blev udviklet til at levere et mere sofistikeret sæt GUI -komponenter end det tidligere Abstract Window Toolkit (AWT) . Swing giver et look og feel, der efterligner udseende og følelse af flere platforme, og understøtter også et pluggbart udseende, der gør det muligt for applikationer at se og føle sig uden relation til den underliggende platform. Det har mere kraftfulde og fleksible komponenter end AWT. Ud over velkendte komponenter som knapper, afkrydsningsfelter og etiketter indeholder Swing flere avancerede komponenter, f.eks. Faneblad, rulleruden, træer, tabeller og lister.

I modsætning til AWT-komponenter implementeres Swing-komponenter ikke af platformspecifik kode. I stedet er de skrevet udelukkende i Java og er derfor platformuafhængige.

I december 2008 udgav Sun Microsystems (Oracles forgænger) den CSS / FXML -baserede ramme, som den havde til hensigt at blive efterfølgeren til Swing, kaldet JavaFX .

Historie

De Internet Foundation Classes (IFC) var en grafisk bibliotek for Java oprindeligt udviklet af Netscape Communications Corporation og først udgivet den 16. december 1996. Den 2. april 1997 Sun Microsystems og Netscape Communications Corporation annoncerede deres hensigt om at indarbejde IFC med andre teknologier til danne Java Foundation Classes . "Java Foundation Classes" blev senere omdøbt til "Swing".

Swing introducerede en mekanisme, der tillod udseende og fornemmelse af hver komponent i en applikation at blive ændret uden at foretage væsentlige ændringer af applikationskoden. Indførelsen af ​​understøttelse af et stik, der kan plugges, gør det muligt for Swing -komponenter at efterligne udseendet af indfødte komponenter, mens de stadig bevarer fordelene ved platformuafhængighed. Oprindeligt distribueret som et separat downloadbart bibliotek, Swing er inkluderet som en del af Java Standard Edition siden udgivelse 1.2. Swing klasser og komponenter er indeholdt i javax.swing pakken hierarkiet.

Udviklingen af ​​Swings efterfølger, JavaFX , startede i 2005, og det blev officielt introduceret to år senere på JavaOne 2007. JavaFX blev open-sourced i 2011, og i 2012 blev det en del af Oracle JDK-download. JavaFX erstatter Swing på grund af flere fordele, herunder at være mere let, have CSS -styling, slanke designkontroller og brugen af FXML og Scene Builder. I 2018 blev JavaFX en del af OpenJDK under OpenJFX -projektet for at øge tempoet i dets udvikling.

Medlemmer af Java Client-teamet, der var ansvarlig for Swing, omfattede James Gosling (arkitekt), Rick Levenson (manager), Amy Fowler & Hans Muller (co-tekniske leads), Tom Ball, Jeff Dinkins, Georges Saab, Tim Prinzing, Jonni Kanerva , og Jeannette Hung & Jim Graham (2D Graphics).

Arkitektur

Swing er en platform-uafhængig, " model-view-controller " GUI rammer for Java, der følger en enkelt gevind programmering model. Derudover giver denne ramme et lag af abstraktion mellem kodestrukturen og den grafiske præsentation af en Swing-baseret GUI.

Fonde

Swing er platformuafhængigt, fordi det er fuldstændigt skrevet i Java. Komplet dokumentation for alle Swing -klasser findes i Java API Guide til Version 6 eller Java Platform Standard Edition 8 API Specification til Version 8.

Kan udvides

Swing er en stærkt modulbaseret arkitektur, som giver mulighed for "tilslutning" af forskellige brugerdefinerede implementeringer af bestemte rammeinterfaces: Brugere kan levere deres egen tilpassede implementering (er) af disse komponenter til at tilsidesætte standardimplementeringerne ved hjælp af Java's arvsmekanisme via javax.swing.LookAndFeel.

Swing er en komponentbaseret ramme , hvis komponenter alle i sidste ende stammer fra javax.swing.JComponentklassen. Svingningsobjekter udløser asynkront hændelser, har bundne egenskaber og reagerer på et dokumenteret sæt metoder, der er specifikke for komponenten. Swing -komponenter er JavaBeans -komponenter, der er i overensstemmelse med JavaBeans -specifikationen .

Konfigurerbar

Swings store afhængighed af runtime -mekanismer og indirekte kompositionsmønstre gør det muligt at reagere på grundtid på grundlæggende ændringer i dens indstillinger. For eksempel er en Swing-baseret applikation i stand til hot-swapping sin brugergrænseflade under runtime. Desuden kan brugerne levere deres eget look and feel -implementering, hvilket giver mulighed for ensartede ændringer i udseende og følelse af eksisterende Swing -applikationer uden nogen programmatisk ændring af applikationskoden.

Let UI

Swings høje fleksibilitetsniveau afspejles i dets iboende evne til at tilsidesætte det native host -operativsystems (OS) GUI -kontroller til at vise sig selv. Swing "maler" sine kontroller ved hjælp af Java 2D API'er, frem for at kalde en native brugergrænseflade værktøjskasse. Således har en Swing -komponent ikke en tilsvarende native OS GUI -komponent og er fri til at gengive sig selv på enhver måde, der er mulig med de underliggende grafiske GUI'er.

I sin kerne er hver Swing -komponent imidlertid afhængig af en AWT -beholder, da (Swing's) JComponentudvider (AWT's) container. Dette gør det muligt for Swing at tilslutte værts -OS'ets GUI -styringsramme, herunder de afgørende enhed/skærmtilknytninger og brugerinteraktioner, såsom tastetryk eller musebevægelser. Swing "transponerer" simpelthen sin egen (OS-agnostiske) semantik over de underliggende (OS-specifikke) komponenter. Så for eksempel maler hver Swing -komponent sin gengivelse på den grafiske enhed som svar på et opkald til component.paint (), som er defineret i (AWT) Container. Men i modsætning til AWT-komponenter, som delegerede maleriet til deres OS-native "heavyweight" widget, er Swing-komponenter ansvarlige for deres egen gengivelse.

Denne transponering og afkobling er ikke kun visuel og strækker sig til Swings styring og anvendelse af sin egen OS-uafhængige semantik til begivenheder, der affyres inden for dets komponentindeslutningshierarkier. Generelt delegerer Swing -arkitekturen opgaven med at kortlægge de forskellige varianter af OS GUI -semantik til et enkelt, men generaliseret, mønster til AWT -containeren. Med udgangspunkt i den generaliserede platform etablerer den sin egen rige og komplekse GUI -semantik i form af JComponentmodellen.

Løst koblet og MVC

Swing Biblioteket gør kraftig brug af model-view-controller software design mønster , som begrebsmæssigt afkobler de data, der set fra brugergrænsefladen kontrol, hvorigennem den er set. På grund af dette har de fleste Swing -komponenter tilknyttede modeller (som er angivet i form af Java -grænseflader ), og programmørerne kan bruge forskellige standardimplementeringer eller levere deres egne. Rammerne indeholder standardimplementeringer af modelgrænseflader for alle dens konkrete komponenter. Den typiske brug af Swing -rammen kræver ikke oprettelse af brugerdefinerede modeller, da rammen indeholder et sæt standardimplementeringer, der som standard er gennemsigtigt forbundet med den tilsvarende JComponentunderordnede klasse i Swing -biblioteket. Generelt er det kun komplekse komponenter, f.eks. Tabeller, træer og nogle gange lister, der muligvis kræver brugerdefinerede modelimplementeringer omkring de applikationsspecifikke datastrukturer. For at få en god fornemmelse af det potentiale, Swing -arkitekturen muliggør, skal du overveje den hypotetiske situation, hvor brugerdefinerede modeller til tabeller og lister er indpakninger over DAO- og/eller EJB -tjenester.

Typisk er Swing -komponentmodelobjekter ansvarlige for at tilvejebringe en kortfattet grænseflade, der definerer begivenheder, der udløses, og tilgængelige egenskaber for den (konceptuelle) datamodel til brug for den tilknyttede JComponent. I betragtning af at det overordnede MVC -mønster er et løst koblet kollaborativt objektrelationsmønster, giver modellen de programmatiske midler til at knytte hændelseslyttere til datamodelobjektet. Disse hændelser er typisk modelcentriske (f.eks. En "række indsat" hændelse i en tabelmodel) og er af JComponent -specialiseringen kortlagt til en meningsfuld begivenhed for GUI -komponenten.

For eksempel har den JTableen model kaldet, TableModelder beskriver en grænseflade for, hvordan en tabel ville få adgang til tabulære data. En standardimplementering af dette fungerer på et todimensionalt array .

Visningskomponenten i en Swing JComponent er det objekt, der bruges til grafisk at repræsentere den konceptuelle GUI -kontrol. En sondring mellem Swing, som en GUI -ramme, er dens afhængighed af programmatisk gengivne GUI -kontroller (i modsætning til brugen af ​​det native host -OS's GUI -kontroller). Før Java 6 Update 10 var denne sondring en kilde til komplikationer ved blanding af AWT -kontroller, som bruger native kontrolelementer, med Swing -kontroller i en GUI (se Blanding af AWT- og Swing -komponenter ).

Endelig, hvad angår visuel sammensætning og ledelse, foretrækker Swing relative layout (som angiver positionsforholdene mellem komponenter) i modsætning til absolutte layouts (som angiver komponenternes nøjagtige placering og størrelse). Denne bias mod "flydende" visuel bestilling skyldes dens oprindelse i applet -driftsmiljøet, der indrammede designet og udviklingen af ​​det originale Java GUI -værktøjskasse. (Begrebsmæssigt ligner denne opfattelse af layoutstyringen ganske den, der informerer gengivelsen af ​​HTML -indhold i browsere og adresserer det samme sæt bekymringer, der motiverede førstnævnte.)

Forholdet til AWT

Image
AWT og Swing klasse hierarki

Siden tidlige versioner af Java har en del af Abstract Window Toolkit (AWT) leveret platformuafhængige API'er til brugergrænsefladekomponenter. I AWT gengives og kontrolleres hver komponent af en native peer -komponent, der er specifik for det underliggende vinduesystem.

I modsætning hertil beskrives Swing -komponenter ofte som lette, fordi de ikke kræver tildeling af native ressourcer i operativsystemets vinduesværktøjskasse. AWT -komponenterne betegnes som tungvægtskomponenter .

Meget af Swing API er generelt en komplementær udvidelse af AWT frem for en direkte erstatning. Faktisk eksisterer hver Swing letvægts grænseflade i sidste ende i en AWT sværvægter komponent, fordi alle de øverste niveau komponenter i Swing ( JApplet, JDialog, JFrame, og JWindow) strækker sig en AWT topniveau beholder. Før Java 6 Update 10 blev brugen af ​​både lette og tunge komponenter inden for det samme vindue generelt frarådet på grund af Z-ordens uforenelighed. Senere versioner af Java har imidlertid rettet disse problemer, og både Swing- og AWT-komponenter kan nu bruges i en GUI uden Z-ordensproblemer.

Kerne -gengivelsesfunktionen, der bruges af Swing til at tegne sine lette komponenter, leveres af Java 2D , en anden del af JFC.

Forholdet til SWT

Den Standard Widget Toolkit (swt) er et konkurrerende værktøjskasse oprindeligt blev udviklet af IBM og nu vedligeholdes af Eclipse samfund . SWT's implementering har mere tilfælles med de tunge komponenter i AWT. Dette giver fordele som mere præcis troskab med det underliggende værktøjssæt til native vinduer på bekostning af en øget eksponering for den native platform i programmeringsmodellen.

Der har været betydelig debat og spekulationer om udførelsen af ​​SWT versus Swing; nogle antydede, at SWT's store afhængighed af JNI ville gøre det langsommere, når GUI -komponenten og Java har brug for at kommunikere data, men hurtigere ved gengivelse, når datamodellen er blevet indlæst i GUI, men dette er ikke blevet bekræftet på nogen måde. Et temmelig grundigt sæt benchmarks i 2005 konkluderede, at hverken Swing eller SWT klart overgik det andet i den generelle sag.

Eksempler

Hej Verden

Dette eksempel Swing -program opretter et enkelt vindue med "Hej, verden!" inde:

// Hello.java (Java SE 5)
import javax.swing.*;

public class Hello extends JFrame {
    public Hello() {
        super("hello");
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.add(new JLabel("Hello, world!"));
        this.pack();
        this.setVisible(true);
    }

    public static void main(final String[] args) {
        new Hello();
    }
}

Den første importomfatter alle de offentlige klasser og grænseflader fra javax.swingpakken.

Den Helloklasse extendsaf JFrameklasse; den JFrameklasse implementerer et vindue med en titel bar og en tæt kontrol .

Den Hello() constructor initialiserer rammen ved først at kalde superklassen constructor, passerer parameter "hello", der anvendes som vinduets titel. Det kalder derefter den setDefaultCloseOperation(int)metode, der er arvet fra, for JFrameat indstille standardoperationen, når den tætte kontrol på titellinjen er valgt til WindowConstants.EXIT_ON_CLOSE - dette bevirker, JFrameat den bortskaffes, når rammen er lukket (i modsætning til blot skjult), hvilket tillader den virtuelle Java -maskine for at afslutte, og programmet skal afsluttes. Dernæst JLabeloprettes a til strengen "Hej, verden!" og den add(Component)metode, der er arvet fra Containersuperklassen, kaldes for at tilføje etiketten til rammen. Den pack()metode arvet fra Windowsuperklassen kaldes til størrelse vinduet og læg dens indhold.

Den main()metode kaldes af Java virtuel maskine, når programmet starter. Det instantierer en ny Helloramme og får den til at blive vist ved at kalde den setVisible(boolean)metode, der er arvet fra Componentsuperklassen med den boolske parameter true. Når rammen er vist, får afslutning af mainmetoden ikke programmet til at afslutte, fordi AWT- hændelsesforsendelsestråden forbliver aktiv, indtil alle vinduer i Swing-topniveau er bortskaffet.

Vindue med knap

Image
Den grundlæggende eksempelkode, der kører på Windows 7

Det følgende er et ret simpelt Swing-baseret program. Det viser et vindue (a JFrame), der indeholder en etiket og en knap.

import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;
 
public class SwingExample implements Runnable {

    @Override
    public void run() {
        // Create the window
        JFrame f = new JFrame("Hello, !");
        // Sets the behavior for when the window is closed
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // Add a layout manager so that the button is not placed on top of the label
        f.setLayout(new FlowLayout());
        // Add a label and a button
        f.add(new JLabel("Hello, world!"));
        f.add(new JButton("Press me!"));
        // Arrange the components inside the window
        f.pack();
        // By default, the window is not visible. Make it visible.
        f.setVisible(true);
    }
 
    public static void main(String[] args) {
        SwingExample se = new SwingExample();
        // Schedules the application to be run at the correct time in the event queue.
        SwingUtilities.invokeLater(se);
    }

}

Bemærk, hvordan al instantiering og håndtering af Swing -komponenter udføres ved at oprette en forekomst af klassen, der implementerer Runnable -grænsefladen. Dette køres derefter på Event Dispatch Thread ved hjælp af metoden SwingUtilities.invokeLater(Runnable)), oprettet i hovedmetoden (se Swing og trådsikkerhed ). Selvom Swing-kode kan køres uden at bruge denne teknik (f.eks. Ved ikke at implementere Runnable og flytte alle kommandoer fra køringsmetoden til hovedmetoden), betragtes den som en god form, da Swing ikke er trådsikker , hvilket betyder, at påkaldelse af ressourcer fra flere tråde kan resultere i trådinterferens og hukommelseskonsistensfejl.

Et andet eksempel

I dette eksempel lad javax.swing.JFrame være superklasse og tilføj vores egen widget (er) til den (i dette tilfælde en JButton).

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Sample extends JFrame {
	private final JButton b = new JButton();

	public Sample() {
		super();
		this.setTitle("HelloApp");
		this.getContentPane().setLayout(null);
		this.setBounds(100, 100, 180, 140);
		this.add(makeButton());
		this.setVisible(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	private JButton makeButton() {
		b.setText("Click me!");
		b.setBounds(40, 40, 100, 30);
		b.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(b, "Hello World!");
			}
		});
		return b;
	}

	public static void main(String[] args) {
		// Swing calls must be run by the event dispatching thread.
		SwingUtilities.invokeAndWait(() -> new Sample());
	}
}

Layoutet er sat til null ved hjælp af Container.setLayout(LayoutManager)metoden, da JFrame bruger java.awt.BorderLayout som standard layout-manager. Med BorderLayout placeres alt, hvad der tilføjes beholderen, i midten og strækkes for at rumme andre widgets. Selvfølgelig ville de fleste virkelige GUI-applikationer foretrække at bruge en layout-manager i stedet for at placere alt på absolutte koordinater.

Se også

Referencer

Citater

Kilder

eksterne links