Det grafiska gränssnittet för programmet i java. Förbättra Java -applikationsgränssnittet


Swing bibliotek

Moderna program behöver ett grafiskt användargränssnitt (GUI). Användare har tappat vanan att arbeta via konsolen: de styr programmet och matar in inmatningsdata via de så kallade kontrollerna (i programmeringen kallas de också visuella komponenter), som inkluderar knappar, textfält, listrutor osv. .

Var och en av moderna språk programmering ger många bibliotek för att arbeta med en standard uppsättning kontroller. Minns att under biblioteket i programmering finns en uppsättning färdiga klasser och gränssnitt utformade för att lösa ett visst antal uppgifter.

Java har tre visuella komponentbibliotek för att bygga ett grafiskt användargränssnitt. Den tidigaste av dessa kallas AWT. Det antas att ett antal brister gjordes i dess design, vilket resulterar i att det är ganska svårt att arbeta med det. Swing -biblioteket är utvecklat på grundval av AWT och ersätter de flesta av dess komponenter med sina egna, designade mer noggrant och bekvämt. Den tredje, mest nytt bibliotek, kallad SWT.

Varje bibliotek tillhandahåller en uppsättning klasser för att arbeta med knappar, listor, fönster, menyer etc., men dessa klasser är utformade annorlunda: de har olika set metoder med olika parametrar, därför är det inte så lätt att "överföra" ett program från ett bibliotek till ett annat (till exempel för att öka prestanda). Det är nästan som att byta från ett programmeringsspråk till ett annat: alla språk kan göra samma sak, men alla har sin egen syntax, sin egen programstruktur och dess många knep.

Av denna anledning, istället för att granska alla tre biblioteken, kommer vi att försöka bättre förstå ett av dem - Swing -biblioteket. Komplett grafiskt gränssnitt kan utvecklas med det.

JFrame -fönster

Varje GUI -program körs i ett fönster och kan öppna flera ytterligare fönster under processen.

Swing -biblioteket beskriver JFrame -klassen, som är ett fönster med en ram och en titelfält (med knapparna "Minimera", "Helskärm" och "Stäng"). Det kan ändra storlek och flytta runt på skärmen.

om svängfönster

Det finns flera andra fönsterklasser i Swing. Till exempel är JWindow det enklaste fönstret, utan kant och utan titelfält. Vanligtvis används den för att skapa en stänkskärm för programmet, som måste utföra flera långa åtgärder innan den startas (till exempel laddning av information från databasen).

JFrame () -konstruktorn utan parametrar skapar ett tomt fönster. JFrame (String title) -konstruktören skapar ett tomt fönster med titeln.

Att skriva det enklaste programmet som visar ett tomt fönster behöver vi ytterligare tre metoder:

setSize (int bredd, int höjd) - anger fönstrets storlek. Om du inte anger dimensioner kommer fönstret att ha nollhöjd oavsett vad som finns i det och användaren måste sträcka fönstret manuellt efter lanseringen. Fönstrets dimensioner inkluderar inte bara arbetsområdet, utan även gränserna och titelfältet.

setDefaultCloseOperation (int operation) - låter dig ange vilken åtgärd som ska utföras när användaren stänger fönstret genom att klicka på krysset. Vanligtvis har ett program ett eller flera fönster, vid stängning som programmet slutar fungera. För att programmera detta beteende, passera EXIT_ON_CLOSE -konstanten som beskrivs i JFrame -klassen som operationsparametern.

setVisible (booleskt synligt) - När fönstret skapas är det osynligt som standard. Ring för att visa fönstret på skärmen den här metoden med parametern true. Om du kallar det med den falska parametern blir fönstret osynligt igen.

Vi kan nu skriva ett program som skapar ett fönster, visar det och avslutar när användaren stänger fönstret.

importera javax.swing. *; public class MyClass (public static void main (String args) (JFrame myWindow = new JFrame ("Trial Window"); myWindow.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); myWindow.setSize (400, 300); myWindow.setVisible () )))

Observera att du måste importera java.swing -paketet för att fungera med de flesta Swing -klasser. *

Som regel måste du utföra många fler åtgärder innan du visar ett fönster än i det här enkla programmet. Du måste skapa många kontroller, anpassa dem utseende, placera fönstren på rätt ställen. Dessutom kan programmet ha många fönster och det är obekvämt och felaktigt att konfigurera dem alla i huvudmetoden (), eftersom det bryter mot inkapslingsprincipen: att behålla data och kommandon som behandlar dem tillsammans. Det vore mer logiskt för varje fönster att ta hand om sin storlek och innehåll på egen hand. Därför ser den klassiska strukturen i ett fönsterprogram ut så här:

I filen SimpleWindow.java:

public class SimpleWindow utökar JFrame (SimpleWindow () (super ("Testfönster"); setDefaultCloseOperation (EXIT_ON_CLOSE); setSize (250, 100);))

I Program.java -filen:

public class Program (public static void main (String args) (JFrame myWindow = new SimpleWindow (); myWindow.setVisible (true);))

Från exemplet kan du se att fönstret beskrivs i en separat klass som ärver från JFrame och anpassar dess utseende och beteende i konstruktorn (det första kommandot kallar superklassens konstruktör). Huvudmetoden () finns i en annan klass som ansvarar för att hantera programmets flöde. Var och en av dessa klasser är mycket enkel, var och en gör sina egna saker, så de är lätta att förstå och lätta att underhålla (dvs. förbättra om det behövs).

Observera att setVisible () -metoden inte kallas i SimpleWindow -klassen, vilket är ganska logiskt: fönstret i sig övervakar var knappen sitter och vilken storlek den ska ha, men att bestämma vilket fönster som visas på skärmen är prerogativt av programmets kontrollklass.

Innehållsfönster

Kontrollerna placeras inte direkt i fönstret. För att göra detta, använd innehållsfönstret, som upptar hela fönsterutrymmet *. Du kan komma åt den här panelen med metoden getContentPane () för JFrame -klassen. Med metoden add (Component component) kan du lägga till valfri kontroll till den.

I exemplen på den här lektionen kommer vi bara att använda en kontroll - en knapp (utan att gå in på detaljer om dess design). Knappen beskrivs av JButton -klassen och skapas av en konstruktör med en parameter av typen String - en etikett.

Låt oss lägga till en knapp i innehållsfönstret i vårt fönster med kommandona:

JButton newButton = ny JButton (); getContentPane (). add (newButton);

Som ett resultat får vi ett fönster med en knapp. Knappen upptar hela tillgängligt område i fönstret. Denna effekt är inte användbar i alla program, därför är det nödvändigt att studera olika sätt placering av element på panelen.

Behållarklass

Föremål som innehåller andra föremål kallas behållare. De är alla ättlingar till behållarklassen och ärver ett antal användbara metoder från den:

add (Komponentkomponent) - lägger till ett komponentelement i behållaren;

remove (Komponentkomponent) - tar bort komponentelementet från behållaren;

removeAll () - tar bort alla element i behållaren;

getComponentCount () - Returnerar antalet element i behållaren.

Förutom de som anges i behållarklassen definieras cirka två dussin metoder för att hantera uppsättningen komponenter som finns i behållaren. Som du kan se liknar de metoder för en samlingsklass. Detta är inte förvånande, för i huvudsak är en behållare en samling, men en samling av ett speciellt slag - en visuell. Förutom att lagra element, hanterar behållaren deras rumsliga arrangemang och ritning. Specifikt har den en getComponentAt (int x, int y) metod som returnerar komponenten som pekar med givna koordinater(koordinaterna mäts från komponentens övre vänstra hörn) och ett antal andra. Vi kommer inte att gå in på detaljer om den abstrakta behållaren, utan gå direkt till dess vanligaste ättling - JPanel -klassen.

JPanel -klass (panel)

En JPanel är ett rektangulärt utrymme där du kan placera andra element. Objekt läggs till och tas bort med metoder som ärvts från behållarklassen.

I knappexemplet såg vi hur knappen som läggs till i innehållsfönstret tog all sin plats. Detta händer inte alltid. Faktum är att varje panel har en sk boendechef som definierar strategin ömsesidig disposition objekt som läggs till i panelen. Det kan ändras med setLayout -metoden (LayoutManager -chef). Men för att skicka den nödvändiga parametern till den här metoden måste du veta vad chefer är.

FlowLayout Sekventiell layouthanterare

Den enklaste layouthanteraren är FlowLayout. Det placerar komponenterna som ska läggas till panelen strikt en efter en, rad för rad, beroende på panelens storlek. Så snart nästa element inte passar in nuvarande linje, det överförs till nästa. Detta illustreras bäst med ett exempel. Låt oss ändra konstruktören för SimpleWindow -klassen enligt följande:

SimpleWindow () (super ("Test Window"); setDefaultCloseOperation (EXIT_ON_CLOSE); JPanel panel = new JPanel (); panel.setLayout (new FlowLayout ()); panel.add (new JButton ("Button")); panel. lägg till (ny JButton ("+")); panel.add (ny JButton ("-")); panel.add (ny JButton ( "Knapp med lång bildtext"))); setContentPane (panel); setSize (250, 100); )

Platshanterare beskrivs i paketet java.awt. Glöm inte att importera de klasser du vill ha.

Observera beteendet i fönstret som visas efter att programmet startats. De fyra knapparna i den är ordnade som ord i textredigerare(vid inriktning mot mitten). Effekten kommer att märkas mer om du ändrar storlek på fönstret medan programmet körs.

Låt oss analysera exempeltexten. Den nya layouthanteraren för FlowLayout skapas av den parameterlösa konstruktören. Observera att programmet inte använder en mellanvariabel. Det vill säga istället för två kommandon:

FlowLayout newLayout = nytt FlowLayout (); panel.setLayout (newLayout);

Vi använder en:

Panel.setLayout (ny FlowLayout ());

Detta är ganska acceptabelt i de fall då vi i framtiden inte behöver hänvisa till objektet som skapas (vilket är sant för detta exempel). Vi skapar en layouthanterare, binder den direkt till panelen, och det är det. Nu kommer panelen och chefen att hitta ett gemensamt språk med varandra.

om relationen mellan panelen och dess chef

Panelen lagrar en länk till sin chef och refererar själv till den varje gång den behöver beräkna koordinaterna för element (detta händer när de läggs till, tas bort, ändras storlek och även när fönstret ändras). I princip kan vi till och med skaffa den här chefen med hjälp av metoden getLayout () för JPanel -klassen, men som regel är detta inte nödvändigt alls.

Förresten, JPanel -klassen, förutom en konstruktör utan parametrar, har en konstruktör där platshanteraren är inställd som en parameter. Därför istället för kommandon

JPanel -panel = ny JPanel (); panel.setLayout (nytt FlowLayout ());

du kan skriva:

JPanel -panel = ny JPanel (ny FlowLayout ());

Dessutom som standard igen panelen som skapas har exakt layouthanteraren FlowLayout. Därför installerar vi i exemplet ovan chefen snarare för tydlighetens skull, i allmänhet är detta inte nödvändigt.

På samma sätt lägger vi till nya knappar på panelen. Ingen annanstans försöker vi hänvisa till dessa knappar i programmet, så det är ingen idé att ställa in variabler under dem.

Med metoden setContentPane (JPanel panel) kan du byta ut fönsterets innehållsfönster.

BorderLayout Manager

BorderLayout layouthanteraren delar upp panelen i fem områden: mitt, topp, botten, höger och vänster. Du kan lägga till exakt en komponent till vart och ett av dessa områden, och komponenten kommer att uppta hela området som är tilldelat för det. Komponenter som läggs till i de övre och nedre områdena sträcker sig i bredd, de som läggs till höger och vänster sträcker sig i höjd och en komponent som läggs till i mitten sträcker sig för att fylla det återstående panelutrymmet.

När du lägger till ett element på panelen med BorderLayout -layouthanteraren måste du dessutom ange i metoden add () vilket av områdena som avses. För att göra detta, använd raderna med namnen på kardinalpunkterna: "North", "South", "East", "West" och "Center". Men istället rekommenderas att använda de konstanter som definieras i BorderLayout -klassen: NORTH, SOUTH, EAST, WEST och CENTER (eftersom du kan göra ett misstag i en rad och inte märka det, och om du försöker skriva fel namn på en konstant, kommer kompilatorn att utfärda en varning). Om du använder metoden add () som vanligt, med en parameter, läggs elementet till i mitten.

Innehållsfönstret har exakt den här platsen, varför knappen upptog hela fönstret (det lades till i det centrala området). För att se BorderLayout -effekten, låt oss lägga till knappar till alla fem områden:

SimpleWindow () (super ("Testfönster"); setDefaultCloseOperation (EXIT_ON_CLOSE); getContentPane (). Lägg till (ny JButton ("knapp"), BorderLayout.NORTH); getContentPane (). Lägg till (ny JButton ("+"), BorderLayout.EAST); getContentPane (). Lägg till (ny JButton ("-"), BorderLayout.WEST); getContentPane (). Lägg till (ny JButton ( "Knapp med lång bildtext"), BorderLayout.SOUTH); getContentPane (). add (new JButton ("CENTER!")); setSize (250, 100); )

Effekten kommer att observeras väl om fönstret ändras.

Denna placering används inte av misstag i standardinnehållsfönstret. De flesta program använder områden runt kanterna på fönstret för att placera verktygsfält, statusfält och liknande. Och begränsningen för en komponent i det centrala området är absolut obetydlig, eftersom den här komponenten kan vara en annan panel med många element och med vilken layouthanterare som helst.

GridLayout Table Layout Manager

GridLayout delar panelen i celler med samma bredd och höjd (vilket gör att fönstret ser ut som ett bord). Varje objekt som läggs till i en panel med detta arrangemang upptar helt en cell. Cellerna fylls med element en efter en, från början till vänster.

Denna chef, till skillnad från dem som diskuterats tidigare, skapas av en konstruktör med parametrar (fyra heltal). Du måste ange antalet kolumner, rader och avståndet mellan cellerna horisontellt och vertikalt. Följ exemplet nedan och observera effekten.

SimpleWindow () (super ("Testfönster"); setDefaultCloseOperation (EXIT_ON_CLOSE); JPanel panel = ny JPanel (); panel.setLayout (nytt GridLayout (2,3,5,10)); panel.add (ny JButton (" Knapp ")); panel.add (ny JButton (" + ")); panel.add (ny JButton (" - ")); panel.add (ny JButton ( "Knapp med lång bildtext"))); panel.add (ny JButton ("en annan knapp")); setContentPane (panel); setSize (250, 100); )

BoxLayout box manager och Box class

BoxLayout -chefen ordnar objekten på panelen i rad eller i en kolumn.

Vanligtvis, för att arbeta med den här chefen, använd hjälparklass Box, som är en panel som redan är konfigurerad för blockplacering. En sådan panel skapas inte av en konstruktör, utan av en av två statiska metoder som definieras i Box -klassen: createHorizontalBox () och createVerticalBox ().

Objekt som läggs till i en blocklayoutpanel radas upp efter varandra. Standardavståndet mellan element är noll. Men istället för en komponent kan du lägga till en osynlig "distans", vars enda uppgift är att skjuta intilliggande element, vilket ger ett visst avstånd mellan dem. Den horisontella fjäderbenet skapas statisk metod createHorizontalStrut (int width) och vertical görs med createVerticalStrut (int height) -metoden. Båda metoderna definieras i Box -klassen, och en heltalsparameter i varje bestämmer storleken på distansen.

Dessutom kan ytterligare ett speciellt element läggas till en sådan panel - ett slags "fjäder". Om panelstorleken är större än nödvändigt för optimal placering av alla element, försöker de som kan töjas fyllas extra utrymme själv. Om en eller flera "fjädrar" placeras bland elementen, ytterligare en ledigt utrymme kommer att fördelas i dessa luckor mellan elementen. Horisontella och vertikala fjädrar skapas av metoden createHorizontalGlue () respektive createVerticalGlue ().

Det är bättre att förstå särdragen i denna chefs arbete med ett illustrativt exempel. Vi kommer att placera de fyra knapparna vertikalt, placera en "fjäder" mellan de två centrala och mellan de andra - distanser på 10 pixlar.

SimpleWindow () (super ("Testfönster"); setDefaultCloseOperation (EXIT_ON_CLOSE); Låda= Box.createVerticalBox (); box.add (ny JButton ("knapp")); box.add (Box.createVerticalStrut (10)); box.add (ny JButton ("+")); box.add (Box.createVerticalGlue ()); box.add (ny JButton ("-")); box.add (Box.createVerticalStrut (10)); box.add (ny JButton ( "Knapp med lång bildtext"))); setContentPane (box); setSize (250, 100); )

Funktioner för att anpassa element

I exemplet med den vertikala rutan justerades alla knappar till vänster. Denna horisontella inriktning är standard.

Men när du utformar ett programfönster kanske du vill att vissa element ska justeras annorlunda, till exempel högerjusterat eller centrerat. För att ställa in en visuell komponents inriktning (till exempel en knapp eller en panel), använd setAlignmentX (float alignment) - horisontell inriktning och setAlignmentY (float alignment) - vertikala justeringsmetoder. Den enklaste parametern är att använda de konstanter som definieras i klassen JComponent. För horisontell inriktning använder du konstanterna LEFT_ALIGNMENT (vänster), RIGHT_ALIGNMENT (höger) och CENTER_ALIGNMENT (mitten). För vertikal inriktning, BOTTOM_ALIGNMENT (nedre), TOP_ALIGNMENT (överst) och CENTER_ALIGNMENT (mitten).

Inriktningen fungerar dock något annorlunda än förväntat. För att ta reda på detta, låt oss ändra det föregående exemplet för att anpassa den tredje knappen till höger. För att göra detta, ersätt raden:

Box.add (ny JButton ("-"));

Tre andra:

JButton rightButton = ny JButton ("-"); rightButton.setAlignmentX (JComponent.RIGHT_ALIGNMENT); box.add (högerknapp);

Vi var tvungna att införa en variabel för att hänvisa till den här knappen, för nu behöver vi inte göra en, utan två åtgärder med den: ställ in rätt justering och lägg till den i panelen. Det gamla tricket - att skapa en knapp samtidigt och skicka den som en parameter till en metod - fungerar inte här.

Efter start av programmet kommer vi att se ett fönster där knapparna inte är placerade som förmodligen förväntat. Vi är vana vid att högerjustering skjuter objektet till behållarens högra kant, men i det här fallet har alla element omarrangerats och den högerjusterade knappen är den längst till vänster.

Förklaringen är enkel. Objektet högerjusterar och snugglar inte mot komponentens högra kant. I stället är den högerjusterad mot en osynlig inriktningslinje. Alla andra komponenter pressas mot denna linje med sin vänstra kant, och därför erhålls den observerade effekten.

Den enda svårigheten för en nybörjare kan vara att det inte alltid är lätt att förstå exakt var denna linje kommer att gå. Dess position beror på storleken och inriktningen av alla element i behållaren. Det är dock lätt att komma ihåg en enkel regel: om alla element i behållaren är inriktade på samma sätt får vi det vanliga beteendet (som var fallet i föregående exempel, när alla komponenter var inriktade till vänster och linje som ett resultat inbäddat mot panelens vänstra kant.

om att anpassa element

Justeringsparametern är faktiskt riktigt nummer i intervallet från 0 till 1. Det visar hur mycket av komponenten som kommer att vara till vänster om inriktningslinjen, dvs. i vilka proportioner kommer komponenten att "skäras". Konstanterna LEFT_ALIGNMENT och TOP_ALIGNMENT är faktiskt 0, RIGHT_ALIGNMENT och BOTTOM_ALIGNMENT är 1, och CENTER_ALIGHNMENT är 0,5. Du kan ersätta dessa nummer direkt (även om användning av konstanter förbättrar tydligheten avsevärt!), Eller så kan du välja valfritt annat nummer från 0 till 1 och skapa en helt godtycklig justering.

Prova att experimentera med det vertikala fältet genom att ställa in olika inriktningar för dess element för att intuitivt förstå logiken bakom placeringen av justeringslinjen. Ändra storlek på fönstret medan programmet körs för att se hur positionen för den här raden ändras.

Manuell placering av element

Om du anger null som panelplaceringshanteraren placeras inte elementen automatiskt. I detta fall måste koordinaterna för varje element anges specifikt, och de beror inte på något sätt på panelens dimensioner och på koordinaterna för andra element. Som standard är koordinaterna lika med noll (dvs. elementet finns i panelens övre vänstra hörn). Elementets storlek måste också anges uttryckligen (annars blir dess bredd och höjd noll och elementet visas inte).

Elementkoordinater kan ställas in med någon av följande metoder:

setLocation (int x, int y),

setLocation (punktpunkt)

Dessa metoder fungerar på ett liknande sätt och sätter vänster övre hörnet element till en punkt med angivna koordinater. Skillnaden ligger i hur punkten ställs in. Du kan representera en punkt med två heltal, eller så kan den vara ett objekt i punktklassen. Point -klassen är i huvudsak samma par av tal, dess konstruktör är Point (int x, int y). En enda koordinat kan nås med hjälp av metoderna getX () och getY ().

Man kan undra: varför använda Point -klassen när du bara kan skicka in ett par nummer? Men faktum är att många användbara metoder returnerar resultatet - koordinaterna för en punkt - som ett objekt i denna klass. Till exempel metoden getLocation (), som returnerar koordinaterna för ett element. Antag att vi vill placera b exakt där a är. Detta kan enkelt uppnås med en rad:

B.setLocation (a.getLocation ());

Elementstorleken ställs in med en av två metoder:

setSize (int bredd, int höjd),

setSize (Dimensionsstorlek)

Dessa metoder fungerar likadant - skillnaden, precis som förra gången, är hur parametern skickas. Dimensionsklassen, som liknar Point -klassen, lagrar helt enkelt två nummer, har en konstruktör med två parametrar: Dimension (int bredd, int höjd) och låter dig komma åt dess komponenter - bredd och höjd - med enkla metoder getWidth () och getHeigth (). För att få den aktuella storleken på ett element kan du använda metoden getSize (), som returnerar ett objekt i klassen Dimension. Element b kan göras exakt samma storlek som element a genom att köra kommandot:

B.setSize (a.getSize ());

Låt oss skapa en panel utan layouthanterare kopplad till den och placera två knappar manuellt på den:

SimpleWindow () (super ("Testfönster"); setDefaultCloseOperation (EXIT_ON_CLOSE); JPanel panel = new JPanel (); panel.setLayout (null); JButton button = new JButton ("Button"); button.setSize (80, 30 ); button.setLocation (20,20); panel.add (knapp); knapp = ny JButton ( "Knapp med lång bildtext"); button.setSize (120, 40); button.setLocation (70,50); panel.add (knapp); setContentPane (panel); setSize (250, 150); )

Vi använder samma variabelknapp för att referera till båda knapparna (dessutom behöver vi inte beskriva det en andra gång). Efter att ha utfört alla nödvändiga operationer med den första knappen och vetat att vi inte längre behöver komma åt den använder vi den "frigjorda" variabeln för att manipulera den andra.

Automatisk dimensionering av komponenter

Om panelen har någon layouthanterare ignorerar den de uttryckliga dimensionerna och koordinaterna för alla dess element. Du kan enkelt verifiera detta genom att ersätta kommandot panel.setLayout (null) med panel.setLayout (ny FlowLayout ()) i föregående exempel. Placeringschefen bestämmer själv koordinaterna och storlekarna på alla element.

Metoden för att bestämma koordinaterna för element på ett uppenbart sätt följer av algoritmerna för varje chefs arbete och därför har vi diskuterat i detalj ovan.

Vi noterade också att komponenter i vissa fall försöker fylla allt utrymme som är tillgängligt för dem. Till exempel hela mittområdet för BorderLayout -chefen eller hela cellen i GridLayout -chefen. Däremot försöker element i en panel med en FlowLayout -chef aldrig gå över vissa gränser. Fundera över vad dessa gränser är.

Varje visuell komponent har tre typer av storlekar: minsta tillåtna, högsta tillåtna och föredragna. Du kan ta reda på vad dessa dimensioner är för en given komponent med hjälp av lämpliga metoder:

getMinimumSize (),

getPreferredSize (),

getMaximumSize ().

Metoderna returnerar ett resultat av typen Dimension. De är programmerade i lämplig klass. Till exempel knappen minsta storlek- noll, maximal storlek inte begränsad, men den föredragna beror på bildtexten på knappen (beräknad som bildtextens storlek plus storleken på fälten).

FlowLayout -chefen anger alltid de önskade storlekarna på elementen. BorderLayout -chefen ställer in önskade bredder på höger och vänster, såväl som önskade höjder på toppen och botten. Resten av måtten anpassas till det tillgängliga panelutrymmet. GridLayout -chefen försöker ändra storlek på alla element för att passa cellerna. BoxLayout -chefen fokuserar på önskade storlekar.

När ett element försöker uppta allt utrymme som är tillgängligt för det, "tar det hänsyn" till önskemålen om att inte bli mindre än sitt minimum eller mer än sitt maximum.

Alla tre storlekar kan styras med lämpliga uppsättningsmetoder:

setMinimumSize (Dimensionsstorlek),

setPreferredSize (Dimensionsstorlek),

setMaximumSize (Dimensionsstorlek).

Oftast används en enkel teknik när ett element "inte rekommenderas" för att växa eller krympa i förhållande till dess önskade storlek. Detta kan enkelt göras med kommandot:

Element.setMinimumSize (element.getPreferredSize ());

Fönster "packning"

I exemplen ovan anger vi uttryckligen fönsterstorleken med setSize () -metoden. Men när du använder någon form av layouthanterare som ordnar elementen och ändrar storlek på dem enligt egna regler, är det svårt att på förhand säga vilka fönsterstorlekar som är de mest lämpliga.

Naturligtvis skulle det mest lämpliga alternativet vara när alla fönsterelement har önskade storlekar eller ligger nära dem *.

Om du i stället för att uttryckligen ange storleken på fönstret ska ringa pack () -metoden, kommer de att väljas optimalt med hänsyn till preferenserna för alla element som placeras i det här fönstret.

SetSize (250, 100);

per lag

Observera att när panelen inte har en placeringsmetod fungerar det här kommandot inte (eftersom panelen inte har någon algoritm för att beräkna dess önskade storlek).

Övningen

Som redan nämnts kan en annan panel vara ett panelelement. Skapa en panel med tre knappar och en layouthanterare FlowLayout och en panel med två knappar och en layouthanterare BoxLayout (horisontellt). Placera båda panelerna i huvudfönstret (utan att ändra layouthanteraren för innehållspanelen): en i mitten och den andra längs med vardera sidan av fönstret.

Ramverk

När paneler inte bara tjänar till att placera element i enlighet med algoritmen för någon chef, utan att visuellt skilja dem från varandra, ramas de in med ramar.

Panellens kant ställs in med metoden setBorder (Border border). Metodens parameter är en ram - ett objekt i gränsklassen. Detta är en abstrakt klass, så dess ättlingar används för att skapa ramen:

EmptyBorder - en tom kant, låter dig skapa vaddering runt panelen. Indragstorlekar anges i konstruktorn som fyra heltal.

TitledBorder - Titelram. Enklaste konstruktör har en parameter av typen String (rubriktext). Rubriken kan placeras längs vilken sida av ramen som helst, ha olika stilar.

EtchedBorder - präglad ram. Kan vara konkav eller konvex.

BevelBorder - en volymetrisk kant (konvex eller konkav). Du kan justera färgerna efter behov för 3D -effekter.

SoftBevelBorder är detsamma som BevelBorder, men möjliggör ytterligare avrundning av hörn.

LineBorder är en enkel kantlinje. Du kan välja färg och tjocklek på linjen, runt hörnen.

MatteBorder är en kant från ett upprepat mönster.

CompoundBorder - Kombinerar två ramar som skickas som parametrar till konstruktören till en ny ram.

Alla listade klasser beskrivs i paketet javax.swing.border.

Låt oss titta på ett exempel. I det här exemplet kommer vi att skapa sex paneler med olika ramar och ordna dem i ett bord. För att inte beskriva proceduren för att skapa en ny panel sex gånger, flyttar vi den till en separat metod:

Privat JPanel createPanel (Border border, String text) (JPanel panel = new JPanel (); panel.setLayout (new BorderLayout ()); panel.add (new JButton (text)); panel.setBorder (new CompoundBorder (new EmptyBorder (new EmptyBorder) 12,12,12,12), kant)); returpanel;)

Metoden createPanel () skapar en panel med en knapp i full storlek. Som parameter skickas etiketten på knappen och ramen som ska läggas till panelen. Ramen läggs inte direkt till, utan genom komposition med en tom ram. Denna teknik används ofta för att förhindra att ramen fastnar vid panelens kant.

Nu kommer vi att använda denna metod sex gånger i konstruktören av programfönstret.

SimpleWindow () (super ("Trial Window"); setDefaultCloseOperation (EXIT_ON_CLOSE); JPanel panel = new JPanel (); panel.setLayout (new GridLayout (2,3,5,10)); panel.add (createPanel (new TitledBorder) ( "Titelram"), "TitledBorder")); panel.add (createPanel (ny EtchedBorder (), "EtchedBorder")); panel.add (createPanel (ny BevelBorder (BevelBorder.LOWERED), "BevelBorder")); panel.add (createPanel (ny SoftBevelBorder (BevelBorder.RAISED), "SoftBevelBorder")); panel.add (createPanel (ny LineBorder (Color.ORANGE, 4), "LineBorder")); panel.add (createPanel (nytt MatteBorder (nytt ImageIcon ("1.gif")), "MatteBorder")); setContentPane (panel); pack (); )

Detta exempel visar vilka konstruktörer som används för att skapa olika ramar och hur de ser ut. Den använder två nya klasser: Color och ImageIcon.

Färgklassen är utformad för att fungera med färg. Den innehåller flera konstanter som beskriver de vanligaste färgerna. I synnerhet inkluderar detta Color.ORANGE.

Klassen ImageIcon beskriver grafisk bild... Parametern till dess konstruktör är sökvägen till filen från vilken bilden kan laddas. I exemplet används det relativa filnamnet "1.gif". För att ImageIcon -objektet ska kunna skapas framgångsrikt måste en fil med detta namn placeras i projektmappen.

Jag kommer att säga direkt - när du arbetar med grafik, troligtvis, med tiden måste du använda alla de medföljande verktygen, utan undantag, för att uppnå det bästa visuell effekt. Detaljerad beskrivning om "vad och hur" kan hittas - detta är den officiella självstudien om Graphics2D. Det borde vara mer än tillräckligt för att du ska få fart.

Jag har redan gett ett litet exempel på att skriva mitt eget gränssnitt, men det finns andra alternativ för att anpassa gränssnittet. Varje separat J -komponent utför sin lättviktiga rendering med paint () -metoden, som enkelt kan åsidosättas och ändras. Det är bättre att inte använda det direkt (inte alltid, men oftast) (jag kommer inte att gå in på detaljer, eftersom detta är ett helt ämne för ett separat ämne). I nästa exempel använder vi metoden paintComponent (). Låt oss se hur det kan tillämpas närmare ...

Jag börjar med ett exempel - ett textfält med visuell feedback i avsaknad av innehåll:

JTextField -fält = nya JTextField ()
{
privat booleskt lostFocusOnce = false;
privat booleskt felaktigt = falskt;

{
// Lyssnare för att uppdatera valideringstillståndet
addFocusListener (nytt FocusAdapter ()
{
public void focusLost (FocusEvent e)
{
lostFocusOnce = true;

måla om ();
}
});
addCaretListener (ny CaretListener ()
{
public void caretUpdate (CaretEvent e)
{
if (lostFocusOnce)
{
felaktigt = getText () .trim () .equals ("");
}
}
});
}

skyddad tomrumskomponent (grafik g)
{
super.paintComponent (g);

// Utökad återgivning när data är felaktiga
om (felaktigt)
{
Graphics2D g2d = (Graphics2D) g;

// Slå på anti-aliasing för smidig återgivning
g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

// Få vaddering inuti marginalen
Insatser inlägg;
if (getBorder () == null)
{
insets = new Insets (2, 2, 2, 2);
}
annan
{
insets = getBorder () .getBorderInsets (this);
}

// Skapa en understruken form för texten
GeneralPath gp = ny GeneralPath (GeneralPath.WIND_EVEN_ODD);
gp.moveTo (insets.left, getHeight () - insets.bottom);
för (int i = 0; i< getWidth () - insets.right - insets.left; i += 3)
{
gp.lineTo (insets. left + i,
getHeight () - insets.bottom - ((i / 3)% 2 == 1? 2: 0));
}

// Rita den med rött
g2d.setPaint (Color.RED);
g2d.draw (gp);
}
}
};

Närvaron av innehållet kontrolleras igen när det skrivs ut och fältet är ur fokus. Om vi ​​byter till en annan komponent ser vi hur vårt tillägg till JTextField återges:

Den fullständiga exempelkoden kan tas.

Således kan du utöka alla tillgängliga komponenter genom att snabbt omdefiniera och komplettera återgivningsmetoden, utan att behöva skriva separata besvärliga användargränssnitt eller fullfjädrade komponenter. Ett plus givet exempel kan enkelt flyttas till en separat klass och användas som ett färdigt element för ditt gränssnitt.
Ytterligare ett plus den här metoden vad du får är oberoende av den för närvarande installerade LaF / UI -applikationen / komponenten - det kommer alltid att fungera. Naturligtvis, för vissa specifika användargränssnitt kan du behöva en något annorlunda återgivning - för att stödja det eller inte - det är upp till dig.

Även om du ofta vill göra gränssnittet ljusare och mer attraktivt, behöver du inte alltid uppfinna nya komponenter för detta - du kan använda med vanliga medel... Jag kommer att ge ett exempel på att anpassa en enkel kryssruta med en animerad förändring av tillstånd och bakgrund. Den här gången kommer jag igen (ja, du kan slå mig med pinnar) använda de förberedda bilderna från designerens skickliga händer.

8 16x16 bilder tas som grund - 4 tillstånd i kryssrutans bakgrund och 4 tillstånd i kryssrutan (5 faktiskt, men vi lägger till den femte programmatiskt):

Standardrutan har naturligtvis inte möjlighet att ställa in sprites för animeringstillstånd, dessutom måste vi överlagra bilderna av jackdaw på bakgrunden i olika variationer. För detta kommer vi att lägga till en separat metod:

offentlig statisk lista BG_STATES = ny ArrayList ();
offentlig statisk lista CHECK_STATES = ny ArrayList ();

statisk
{
// Bakgrundstillståndsikoner
för (int i = 1; i<= 4; i++)
{
BG_STATES.add (nytt ImageIcon (
MyCheckBox.class .getResource ("ikoner / tillstånd /" + i + ".png")));
}

// Ytterligare "tomt" urvalstillstånd

new BufferedImage (16, 16, BufferedImage.TYPE_INT_ARGB)));

// Urvalstillstånd
för (int i = 1; i<= 4; i++)
{
CHECK_STATES.add (nytt ImageIcon (
MyCheckBox.class .getResource ("ikoner / tillstånd / c" + i + ".png")));
}
}

privat karta iconsCache = ny HashMap ();

privat synkroniserad void updateIcon ()
{
// Uppdatera kryssrutan
final String key = bgIcon + "," + checkIcon;
if (iconsCache.containsKey (nyckel))
{
// Den obligatoriska ikonen har redan använts tidigare
setIcon (iconsCache.get (key));
}
annan
{
// Skapa en ny ikon som kombinerar bakgrund och tillstånd ovanpå
BufferedImage b = new BufferedImage (BG_STATES.get (0) .getIconWidth (),
BG_STATES.get (0) .getIconHeight (), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = b.createGraphics ();
g2d.drawImage (BG_STATES.get (bgIcon) .getImage (), 0, 0,
BG_STATES.get (bgIcon) .getImageObserver ());
g2d.drawImage (CHECK_STATES.get (checkIcon) .getImage (), 0, 0,
CHECK_STATES.get (checkIcon) .getImageObserver ());
g2d.dispose ();

ImageIcon -ikon = ny ImageIcon (b);
iconsCache.put (nyckel, ikon);
setIcon (ikon);
}
}

Det återstår att lägga till några statliga övergångshanterare så får vi en animerad övergång mellan dem:

Den resulterande komponenten blir mycket enkel att till exempel ändra till en alternativknapp, eller lägga till fler övergångstillstånd till den för mjukare animering etc.
Egentligen lade jag upp hela arbetskoden och bilderna separat.

Således finns det många sätt att anpassa element (även jag förmodligen inte vet / inte vet om några av dem). Vilken metod att välja beror på situationen - vad som behöver erhållas, vilka ändringar som kan göras på en befintlig komponent, etc.

I slutet av detta kapitel ger jag dig ett annat exempel på en helt ny designad UI -knapp med animering, möjligheten att runda vissa hörn, möjligheten att anpassa stilen och några andra förbättringar. Här är några skärmdumpar av det slutliga utseendet (animeringen syns naturligtvis inte här):


Jag kommer inte att ljuga, den här knappens användargränssnitt tog mycket tid, men den skapades utan hjälp och tips från designern med rena Graphics2D- och Swing -verktyg. du kan ladda ner och studera hela källan och demon för detta användargränssnitt om du är intresserad. Den använder ett ganska brett utbud av Graphics2D -funktioner och använder några knep som ofta kan vara användbara.

Så jag tror att det är tillräckligt med tal om grafik - jag kommer att prata mer detaljerat om det i framtida ämnen, och nu kommer jag att ge lite intressant material som jag har samlat på mig under en ganska lång tid med "kommunikation" med Swing och Graphics2D.

DnD och GlassPane

Jag tror det första - ni vet mer än såväl som problemen som är förknippade med det. När det gäller den andra - du har säkert hört talas om GlassPane i förbifarten, eller kanske till och med sett den här gamla bilden (som förresten fortfarande är relevant) om arrangemanget av olika lager av standardramar. Vad är det för fel på det och varför kom jag ihåg detta? Och ännu mer, hur är DnD och GlassPane relaterade, frågar du? Det är exakt hur man kopplar dem och vad som kan komma ur det, och jag vill berätta för dig i det här kapitlet.

Låt oss börja i ordning - vad vet vi om DnD?
Vissa Swing -komponenter har färdiga implementeringar för dra (till exempel JTree och JList) - för andra kan du enkelt lägga till dina egna. För att inte kasta ord i vinden kommer jag att ge ett litet exempel på en DnD -sträng från en etikett:

JLabel -etikett = nya JLabel ( "Liten text för DnD");
label.setTransferHandler (ny TransferHandler ()
{
public int getSourceActions (JComponent c)
{
returnera TransferHandler.COPY;
}

offentlig boolsk canImport (stöd för TransferSupport)
{
return falsk;
}

skyddad Transferable createTransferable (JComponent c)
{
returnera nytt StringSelection ((((JLabel) c) .getText ());
}
});
label.addMouseListener (nytt MouseAdapter ()
{
public void mousePressed (MouseEvent e)
{
if (SwingUtilities.isLeftMouseButton (e))
{
JComponent c = (JComponent) e.getSource ();
TransferHandler handler = c.getTransferHandler ();
handler.exportAsDrag (c, e, TransferHandler.COPY);
}
}
});

Nu är det möjligt att dra texten på denna etikett direkt från gränssnittet till någon annan plats där det är möjligt att infoga texten genom droppen.
I själva verket är TransferHandler ansvarig för vilken data komponenten ger vid muddringen och hur komponenten använder inkommande data när den dras till den.

Men vad händer om du behöver spåra sekvensen av användaråtgärder under själva draget?
För detta finns det ett separat alternativ för att hänga lyssnaren:

DragSourceAdapter dsa = nytt DragSourceAdapter ()
{
public void dragEnter (DragSourceDragEvent dsde)
{
// När muddringen kommer in i någon komponents område
}

public void dragExit (DragSourceEvent dse)
{
// När muddringen kommer in i någon komponents område
}

public void dropActionChanged (DragSourceDragEvent dsde)
{
// När du ändrar dragets åtgärd
}

public void dragOver (DragSourceDragEvent dsde)
{
// Om muddringen kan slutföras korrekt
}

public void dragMouseMoved (DragSourceDragEvent dsde)
{
// Vid flyttning av muddraren
}

public void dragDropEnd (DragSourceDropEvent dsde)
{
// Vid avslutning eller annullering av mudderutrymmet
}
};
DragSource.getDefaultDragSource () .addDragSourceListener (dsa);
DragSource.getDefaultDragSource () .addDragSourceMotionListener (dsa);

Det finns en sista sak kvar - att definiera rollen som GlassPane. GlassPane låter dig faktiskt placera / rita komponenter på sig själv, precis som alla andra behållare, men dess egenhet är att den ligger ovanpå alla Swing -komponenter när den är synlig. De där. om vi ritar något på det, kommer det att täcka hela gränssnittet under det. Detta låter dig placera komponenter oavsett huvudbehållare var som helst, skapa visuella effekter och göra andra roliga saker.

För bättre förståelse kommer jag att ge ett litet exempel på en sådan "effekt" - en ram med flera Swing -komponenter på den. När du klickar i någon del av fönstret visas effekten av en "igenkännande" cirkel, som syns ovanpå alla element. Det som är mest intressant är att denna effekt inte förbrukar resurser och inte kräver en stor hög med kod. Tro mig inte? - titta på demon och ta en titt på källan som ingår i burken.

Förresten, det finns ett ganska intressant bibliotek om detta ämne, samtidigt som det ger ytterligare rullningsfunktioner och flera andra godsaker - JXLayer (off site) (beskrivning # 1 beskrivning # 2 beskrivning # 3). Tyvärr är projekt som finns på java -sajten nu inte i bästa skick, så du måste hänvisa till separata resurser.

Så låt oss nu kombinera allt som jag redan har beskrivit i det här kapitlet och slutligen göra något komplett. Till exempel - visa en mudderpanel med komponenter i ett fönster:

När du drar en panel för en etikett visas en genomskinlig kopia av panelen som visar exakt var panelen kommer att placeras när dragningen är klar. Du kan också avbryta flytten med ESC -tangenten.
Ett fungerande exempel och källkod kan tas.

Självklart skulle det inte vara värt att använda DnD för att implementera den här funktionen - det finns kortare sätt. Allt beror dock på situationen. Med det här alternativet kan du rita genom att dra oberoende av andra komponenter i fönstret. Det är också möjligt, baserat på det, till exempel att implementera en dragpanel mellan programfönster.

AWTUtilities

Eftersom några framtida innovationer från 7ki har inkluderats i JDK6 under lång tid kan jag inte ignorera dem, eftersom det med deras hjälp är möjligt att göra många saker med mycket mindre ansträngning.
Så vi är intresserade av flera metoder från AWTUtilities:
  1. AWTUtilities.setWindowShape (Window, Shape) - låter dig ställa in vilket fönster som helst till en specifik form (vare sig det är en cirkel eller en knepig polygon). För att ställa in formuläret korrekt bör fönstret inte dekoreras med den ursprungliga stilen (setUndecorated (true)).
  2. AWTUtilities.setWindowOpacity (Window, float) - låter dig ställa in fönstrets transparens från 0 (helt transparent) till 1 (ogenomskinlig). I detta fall kan fönstret dekoreras med inhemsk stil.
  3. AWTUtilities.setWindowOpaque (Window, boolean) - låter dig helt dölja visningen av bakgrunden och fönsterdekorationen, men alla komponenter som placeras på den kommer att vara synliga. För korrekt inställning av denna parameter bör fönstret, som i steg 1, inte dekoreras med den ursprungliga stilen.

Vad ger detta oss? Det finns faktiskt ett ganska brett utbud av möjligheter. Fönstren i din applikation kan ställas in alla knepiga former som du bara behöver, göra "hål" i mitten av applikationen, skapa anpassade skuggor under fönstret, göra snygga popup-fönster, etc., etc.

Om vi ​​går till detaljerna - faktiskt använder jag aldrig setWindowShape, eftersom formuläret som tilldelats fönstret är strikt avskuret längs kanten och inte ser särskilt snyggt ut. SetWindowOpaque kommer till undsättning - genom att dölja dekoration och bakgrund av fönstret kan du skapa absolut alla fönster med hjälp av en behållare med en anpassad renderad bakgrund. Jag kommer att ge ett litet exempel på användning (det använder också några av teknikerna från tidigare kapitel i inlägget):

du kan ta en fungerande burk med källkoden. Ärligt talat spenderade jag inte mer än tio minuter på detta exempel (varav fem minuter kom jag på hur jag skulle ordna elementen inuti dialogrutan :). Naturligtvis är detta bara ett av alternativen för att använda dessa nya möjligheter - i själva verket finns det mycket fler av dem.

Det enda irriterande lilla med att använda AWTUtilities är instabilt arbete på Linux -system. De där. Fönstrenas transparens fungerar inte alltid och inte alltid korrekt. Vet inte om detta är ett problem med den nuvarande JDK eller operativsystemet.

Skapa dina egna interaktiva komponenter

Jag har redan ytligt talat om hur man skapar komponenter, användargränssnitt och några "klockor och visselpipor" för gränssnittet i din applikation, men tänk om vi behöver lägga till en funktionell del till en komponent eller skapa vår egen helt nya komponent med viss funktionalitet och styling? Att utforma standardkomponenter och göra separata delar av en ny komponent av dem är en ganska lång och tråkig uppgift, särskilt eftersom med den minsta ändringen i en av komponenterna kan hela kretsen gå. Det är i sådana fall som du ska göra din komponent "från grunden".

Så det är bäst att ta JComponent som grund och använda färgmetoder för att rita innehållet. I själva verket är JComponent i sig en tom duk med några fasta förbättringar för återgivning och färdiga standardmetoder setEnabled / setFont / setForeground / setBackground, etc. Hur du använder (och om du ska använda dem) är upp till dig. Allt du lägger till i återgivningsmetoderna blir en del av komponenten och visas när du lägger till det i en behållare.

Förresten, en liten avvikelse, eftersom vi pratar om behållare - alla ärvare och JComponent i sig är behållare, d.v.s. kan innehålla andra komponenter, som kommer att placeras beroende på layout som är installerad för komponenten. Vad händer med återgivningen av barnkomponenter som ligger i den här och hur är det relaterat till återgivningen av denna komponent? Tidigare gick jag inte in på detaljer om hur Jcomponent-färgmetoderna är arrangerade och kopplade, "men nu kommer jag att beskriva det i detalj ...

Faktum är att paint () -metoden innehåller anrop till tre separata metoder - paintComponent, paintBorder och paintChildren. Naturligtvis hanterar den dessutom några "speciella" återgivningsfall, till exempel utskrift eller omritning av ett visst område. Dessa tre metoder kallas alltid i sekvensen som visas på bilden ovan. Således ritas först själva komponenten, sedan ritas en kant ovanpå och sedan kallas återgivningen av barnkomponenter, som i sin tur också kallar deras paint () -metod, etc. Naturligtvis finns det också olika optimeringar som förhindrar onödig återgivning, men jag kommer att skriva mer om detta senare.

Komponenten återges men är statisk och är bara en bild. Vi måste hantera möjligheten att styra den med musen och olika snabbtangenter.
För att göra detta måste du först lägga till lämpliga lyssnare (MouseListener / MouseMotionListener / KeyListener) till själva komponenten och hantera enskilda åtgärder.

För att inte förklara allt på fingrarna kommer jag att ge ett exempel på en komponent som låter dig visuellt ändra storlek på ImageIcon som skickades till den:

du kan ta ett fungerande exempel med källkoden inuti.

När jag skapar denna komponent skulle jag lyfta fram flera viktiga punkter:

  1. Bestämning av komponentens funktionalitet och utseende- i det här fallet är detta ett område med en bild placerad på den, en kant runt bilden och 4 resizers i hörnen. Var och en av storlekarna gör att du kan ändra storlek på bilden. Det är också möjligt att flytta bilden runt området, "ta" den i mitten.
  2. Bestäm alla parametrar som krävs för att komponenten ska fungera- i det här fallet är det själva bilden och dess "förankringspunkter" (övre vänstra och nedre högra hörnen). Det finns också ett antal variabler som kommer att behövas vid implementering av storlek och dra en bild.
  3. Kasta ett tomt för komponenten (helst en separat klass om du ska använda den mer än en gång)- i det här fallet skapar vi klassen ImageResizeComponent, definierar alla parametrar som är nödvändiga för återgivning, åsidosätter paintComponent () -metoden och återger innehållet. Vi åsidosätter också metoden getPreferredSize () så att själva komponenten kan bestämma dess "önskade" storlek.
  4. Vi implementerar den funktionella delen av komponenten- i detta fall kommer vår MouseAdapter att räcka för oss, men för implementering av storlek och rörelse. När musen klickas i området kontrollerar vi koordinaterna och kontrollerar dem mot koordinaterna för hörnen och själva bilden - om klicket hände i området i ett visst hörn, vi kommer ihåg det och ändrar dess koordinat när du drar, om du var tvungen att klicka på bilden kommer vi ihåg dess initiala koordinater och ändrar dem när du drar. Och slutligen, den sista handen - i mouseMoved () ändrar vi markören beroende på kontrollen under musen.
Inget komplicerat, eller hur? Med implementeringen av "knapp" -delarna i andra komponenter är det ännu enklare - det är nog att kontrollera att klicket var i knappområdet. Parallellt med spårningshändelser kan du också visuellt ändra komponentens visning (som det görs i det här exemplet på resizers). I allmänhet kan du göra allt du har tillräckligt med fantasi för.

Naturligtvis har jag precis beskrivit mina steg när jag skapade komponenter - de är valfria och kan enkelt förlängas och kompletteras.

Viktigt att komma ihåg

Det finns några saker att tänka på när du arbetar med gränssnittselement i Swing - jag tar upp dem i detta separata lilla kapitel.
  1. Alla åtgärder med att rita om / uppdatera komponenter bör utföras inuti händelsestråden för att undvika visuella "häng" i gränssnittet för din applikation. Det är ganska enkelt att köra någon kod i Event Dispatch -strömmen:
    SwingUtilities.invokeLater (ny körbar ()
    {
    public void run ()
    {
    // Placera den körbara koden här
    }
    });
    Det är också viktigt att komma ihåg att händelser som anropas från olika lyssnare av standardkomponenter (ActionListener / MouseListener, etc.) initialt kallas från denna tråd och inte kräver ytterligare behandling.
  2. Under inga omständigheter ska du påverka gränssnittet från några färgmetoder, eftersom detta kan leda till slingor eller blockeringar i applikationen.
  3. Föreställ dig en situation - från färgmetoden ändrar du knappens tillstånd, säg, genom setEnabled (aktiverat). Att kalla den här metoden gör att komponenten ritas om och kallar färgmetoden igen, och vi är återigen på den här ödesdigra metoden. Återgivning av knappen slingas och applikationsgränssnittet hänger helt enkelt i väntan på att rendering ska slutföras (eller åtminstone äta upp en bra del av processorn). Detta är den enklaste versionen av detta fel.
  4. Du bör inte göra tunga beräkningar inuti Event Dispatch -strömmen. Du kan göra dessa beräkningar på en separat vanlig tråd och sedan bara åberopa uppdateringen via SwingUtilities.invokeLater ().
  5. Det är inte heller värt att göra tunga beräkningar inuti ritmetoder. Om möjligt bör du ta ut dem separat och cacha / komma ihåg dem. Detta kommer att påskynda återgivningen av komponenter, förbättra programmets övergripande respons och minska belastningen på tråden för händelseschicka.
  6. För att uppdatera utseendet på komponenterna, använd metoden ommålning () (eller ommålning (rektangel) - om du vet det exakta området som ska uppdateras) måste själva ommålningsmetoden köras i tråden Event Dispatch. Om du vill uppdatera arrangemanget av element i layouten använder du metoden revalidation () (den behöver inte köras i händelsestråden). Metoden updateUI () kan i vissa fall hjälpa till med en fullständig uppdatering av ett element (till exempel byte av tabelldata), men det bör användas noggrant, eftersom det också kommer att åsidosätta det användargränssnitt som du har installerat och ta det användargränssnitt som tillhandahålls av nuvarande LaF.
  7. En komplett installation av LaF för hela applikationen kommer att åsidosätta alla dina manuellt konfigurerade UI -komponenter och installera ovanpå dem UI som den installerade LaF erbjuder. Därför är det bättre att installera LaF när du laddar programmet innan du öppnar fönster och visar bilder.
Genom att följa dessa enkla steg kan du inte oroa dig för oväntade "bromsar" eller blockeringar i applikationsgränssnittet.
Jag tror att denna lista kan kompletteras med ytterligare några punkter, men de kommer redan att vara mycket specifika / valfria.

Resultat

Genom att använda, kombinera och variera ovan beskrivna funktioner och funktioner för att arbeta med gränssnitt är det möjligt att uppnå önskat resultat. Du behöver bara visa lite fantasi i denna fråga. Jag hoppas att även de grundläggande exemplen på det här inlägget gav dig tillräckligt med tankar och kanske hjälpte till med något.

Jag skulle också vilja tillägga att kanske titeln på artikeln kan verka för högljudd och inte helt avslöjad för dig - jag är verkligen inte en designer eller en användbarhetsspecialist. Jag erbjuder dig bara verktyg / metoder som gör att du kan expandera och förbättra applikationsgränssnittet. Det mesta (inte nödvändigtvis allt) av arbetet med att skapa grafik för reglaget / knappen eller definiera den allmänna stilen för komponenterna och själva applikationen ligger alltid hos designern - det går inte att komma ifrån detta.

Alla exempel på artikeln i en enda "flaska". Från det första fönstret kan du välja önskat exempel:

  • gränssnitt
  • dnd
  • anpassning
  • gränssnitt
  • anpassning
  • Lägg till taggar

    Vad är Swing?

    Java Swing är en lätt verktygslåda för grafiskt användargränssnitt (GUI) som innehåller en mängd olika widgets. Det innehåller paketet låter dig göra GUI -komponenter för dina Java -applikationer, och det är plattformsoberoende.

    Swing -biblioteket är byggt ovanpå Java Abstract Widget Toolkit ( AWT), en äldre, plattformsberoende GUI -verktygslåda. Du kan använda Java GUI -komponenter som knapp, textruta, etc. från biblioteket och behöver inte skapa komponenterna från grunden.

    I denna handledning lär du dig-

    Hierarkidiagram för Java Swing -klass

    Alla komponenter i sväng är JComponent som kan läggas till behållarklasser.

    Vad är en behållarklass?

    Behållarklasser är klasser som kan ha andra komponenter på den. Så för att skapa ett GUI behöver vi minst ett containerobjekt. Det finns 3 typer av behållare.

    1. Panel: Det är en ren behållare och är inte ett fönster i sig. Det enda syftet med en panel är att organisera komponenterna i ett fönster.
    2. Ram: Det är ett fullt fungerande fönster med titel och ikoner.
    3. Dialog: Det kan ses som ett popup-fönster som dyker upp när ett meddelande måste visas. Det är inte ett fullt fungerande fönster som ramen.

    Java GUI Exempel

    Exempel: Att lära sig att designa GUI i Java
    Steg 1) Kopiera följande kod till en editor

    Importera javax.swing. *; class gui (public static void main (String args) (JFrame frame = new JFrame ("My First GUI"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.setSize (300,300); JButton button = new JButton ("Press") ); frame.getContentPane (). add (knapp); // Lägger till knapp i innehållsfönstret för ram frame.setVisible (true);))

    Steg 2) Spara, kompilera och kör koden.
    Steg 3) Låt oss nu lägga till en knapp i vår ram. Kopiera följande kod till en editor

    Importera javax.swing. *; class gui (public static void main (String args) (JFrame frame = new JFrame ("My First GUI"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.setSize (300,300); JButton button1 = new JButton ("Press") ); frame.getContentPane (). lägg till (knapp1); frame.setVisible (true);))

    Steg 4) Kör koden. Du får en stor knapp

    Steg 5) Vad sägs om att lägga till två knappar? Kopiera följande kod till en editor.

    Importera javax.swing. *; class gui (public static void main (String args) (JFrame frame = new JFrame ("My First GUI"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.setSize (300,300); JButton button1 = new JButton ("Button 1) "); JButton button2 = ny JButton (" Button 2 "); frame.getContentPane (). Lägg till (button1); frame.getContentPane (). Add (button2); frame.setVisible (true);))

    Steg 6) Spara, kompilera och kör programmet.
    Steg 7) Oväntad utgång =? Knapparna överlappar varandra.

    Java Layout Manger

    Layouthanteraren används för att layout (eller ordna) GUI-java-komponenterna inuti en behållare. Det finns många layouthanterare, men de mest använda är-

    Java BorderLayout

    En BorderLayout placerar komponenter i upp till fem områden: topp, botten, vänster, höger och mitt. Det är standardlayouthanteraren för varje java JFrame

    Java FlowLayout

    FlowLayout är standardlayouthanteraren för varje JPanel. Det lägger helt enkelt ut komponenter i en enda rad efter varandra.

    Java GridBagLayout

    Det är den mer sofistikerade av alla layouter. Det anpassar komponenter genom att placera dem i ett rutnät av celler, så att komponenter kan sträcka sig över mer än en cell.

    Steg 8) Vad sägs om att skapa en chattram som nedan?

    Försök att koda dig själv innan du tittar på programmet nedan.

    // Vanligtvis kommer du att behöva både swing- och awt -paket // även om du bara arbetar med gungor. importera javax.swing. *; importera java.awt. *; class gui (public static void main (String args) (// Creating the Frame JFrame frame = new JFrame ("Chat Frame"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.setSize (400, 400); // Creating menyraden och lägga till komponenter JMenuBar mb = ny JMenuBar (); JMenu m1 = ny JMenu ("FIL"); JMenu m2 = ny JMenu ("Hjälp"); mb.add (m1); mb.add (m2); JMenuItem m11 = ny JMenuItem ("Öppen"); JMenuItem m22 = ny JMenuItem ("Spara som"); m1.add (m11); m1.add (m22); // Skapa panelen längst ner och lägg till komponenter JPanel panel = ny JPanel (); // panelen är inte synlig i utdata JLabel label = new JLabel ("Enter Text"); JTextField tf = new JTextField (10); // accepterar upp till 10 tecken JButton send = new JButton ("Send") ; JButton reset = new JButton ("Reset"); panel.add (label); // Components Added with Flow Layout panel.add (label); // Components Added with Flow Layout panel.add (tf); panel.add (skicka); panel.add (återställ); // Textområde i mitten JTextArea ta = ny JText Area (); // Lägga till komponenter i ramen. frame.getContentPane (). lägg till (BorderLayout.SOUTH, panel); frame.getContentPane (). lägg till (BorderLayout.NORTH, mb); frame.getContentPane (). lägg till (BorderLayout.CENTER, ta); frame.setVisible (true); )))

    Alla utvecklare börjar en tid då det inte längre är roligt att skapa konsolapplikationer, och du vill verkligen lära dig något nytt.
    Sedan finns det flera sökvägar i Java, för flera operativsystem. Beroende på vilket operativsystem du använder eller de miljöer som är installerade i dem.

    Lite förord:
    Jag är själv fortfarande en nybörjare programmerare (jag kan skriva mjukvara av medelstor komplexitet, men jag använder vanligtvis en mager uppsättning funktioner)
    Artikeln är också avsedd för nybörjare. Jag arbetar själv under Debian med Gnome, så det kommer att finnas flera plattformsbibliotek)

    Till att börja med skulle det vara värt att uppmärksamma GTK + -biblioteket

    Det är tillgängligt inte bara för Java, utan också för många andra språk: C ++, C, etc.

    Skriva skrivbordsprogram med GTK bör användas om programmet är utformat för att köras under GNOME -miljön.

    GTK + i sig anses vara ett av de enklaste Jav -biblioteken att lära sig.

    Grunderna för att arbeta med biblioteket:

    Först måste du ansluta själva biblioteket med alla dess konsekvenser:

    importera org.gnome.gdk.Event;
    importera org.gnome.gtk.Gtk;
    importera org.gnome.gtk.Widget;
    importera org.gnome.gtk.Window;
    importera org.gnome.gtk.WindowPosition;

    Om ett fel uppstår är det troligt att du helt enkelt inte har biblioteket installerat.

    Om du använder ett system som Debian eller Ubuntu hjälper ett enkelt kommando från terminalen dig:
    apt-get install libjava-gnome-java

    Efter det borde det inte vara några problem.

    public class DesktopExample utökar fönstret (

    public DesktopExample () (

    SetTitle ( "Provfönster på GTK och Gnome") ; // Applikationsnamn

    Anslut (nytt fönster .DeleteEvent () (
    public boolean onDeleteEvent (widgetkälla, händelsehändelse) (
    Gtk.mainQuit ();
    return falsk;
    }
    } ) ;

    SetDefaultSize (250, 150); // Storleken
    setPosition (WindowPosition.CENTER); // Position vid start, i detta fall mitten
    show ();
    }


    Gtk.init (args);
    nytt DesktopExample ();
    Gtk.main ();
    }
    }

    Som ett resultat får vi ett tomt fönster.

    AWT - betraktas som det ursprungliga systemet för att utveckla grafiska gränssnitt, det skälls för det faktum att det
    det fungerar inte alltid stabilt på olika plattformar, men nu verkar sådana problem inte observeras och det är bekvämt att arbeta med det.
    IMHO, det här är mitt val.
    SWT är hjärnbarnet till IBM, ett uppdaterat och påfyllt system, vanligtvis stabilt i drift och lätt att lära sig.
    Men SWT är tyngre än AWT, har mer funktionalitet, vilket resulterar i att AWT är mer komplicerat.
    Men jag skulle inte använda det ofta, även om det är ganska populärt och håller sina positioner.

    Här är ett exempel på ett AWT -fönster:

    // Vi ansluter alla möjliga funktioner, även om svängning är överflödig här, så skruvade jag upp det i min applikation
    // Detta är bara en kodbit
    importera java.awt.EventQueue;
    importera javax.swing. *;
    importera java.awt. *;
    import java.awt.event. *;

    importera javax.swing.JFrame;

    offentlig klass Main (

    privat JFrame -ram;

    /**
    * Starta ett program, något som inledande installation, skapa ett fönster och så vidare.
    */
    public static void main (String args) (

    EventQueue .invokeLater (new Runnable () (
    public void run () (
    Prova (
    Huvudfönster = nytt Main ();
    window.frame .setVisible (true);
    ) fångst (undantag e) (
    e.printStackTrace ();
    }

    }
    } ) ;
    }

    /**
    * Ring själva initialiseringen
    */
    offentlig Main () (

    Initiera ();
    }

    /**
    * Initiering av fönster
    */
    private void initialize () (
    ram = ny JFrame ( "Rent fönster genererat via Eclipse") ; // Skapa ett nytt fönster med titeln
    frame.setBounds (100, 100, 450, 300);
    frame.setSize (800, 800); // Mått
    frame.setDefaultCloseOperation (JFrame .EXIT_ON_CLOSE);

    }

    Och här är ett exempel på ett fönster på SWT:

    // Vi ansluter alla möjliga funktioner för ett roligt liv
    importera org.eclipse.swt.SWT;
    importera org.eclipse.swt.widgets.Display;
    importera org.eclipse.swt.widgets.Shell;
    importera org.eclipse.swt.widgets.Text;

    public class exempelapp (

    public static void main (String args) (
    Display display = new Display ();
    Skalskal = nytt skal (display);

    Shell.pack (); // Förberedelse (primär)
    shell.open (); // Förbereda
    medan (! shell.isDisposed ()) (// Kör
    if (! display.readAndDispatch ()) display.sleep (); // Sov för tillfället
    }
    display.dispose ();
    }
    }

    Det är inte heller komplicerat i princip, multiplatform. Skiljer sig i ett stort antal funktioner och ett litet antal plug-in-påfyllningar.

    Här är ett exempel på ett svängfönster:

    importera javax.swing.JFrame;
    importera javax.swing.SwingUtilities;

    public class Exempel utökar JFrame (

    offentligt exempel () (
    setTitle ( "Prov Swing -applikation") ;
    setSize (300, 200);
    setLocationRelativeTo (null);
    setDefaultCloseOperation (EXIT_ON_CLOSE);
    }

    public static void main (String args) (
    SwingUtilities .invokeLater (new Runnable () (
    public void run () (
    Exempel ex = nytt Exempel ();
    ex.setVisible (true);
    }
    } ) ;
    }
    }

    Detta var huvudlistan över Java -ramverk. Nästan alla "bitar" som presenteras här är multiplatform
    och fungerar på vilken dator som helst - Win, Linux, Mac.

    Taggar: java, java bibliotek, java GUI

    En skärmform är ett område som är synligt på skärmen som ett fönster med olika element - knappar, text, listrutor etc. Och dessa element själva kallas komponenter.

    Miljöer som låter dig interaktivt placera komponenter på formulär och ställa in deras parametrar under programutveckling kallas RAD -miljöer. RAD står för Rapid Application Development - Rapid Application Development.

    I NetBeans och andra moderna utvecklingsmiljöer är denna process baserad på Component Object Model, varför den kallas Object Oriented Design (OOD).

    NetBeans är en RAD -miljö som låter dig snabbt och enkelt skapa rikt grafiskt användargränssnitt (GUI) applikationer. Även om Java -språkkonstruktioner som låter dig göra detta inte är så enkla, i det inledande skedet av att arbeta med skärmar och deras element, behöver du inte fördjupa dig i dessa finesser. Det räcker att känna till de grundläggande principerna för att arbeta med sådana projekt.

    Först, från början, behärskar du skapandet av fullvärdiga applikationer som kan användas för användbara ändamål. Det är svårt att studera abstrakta begrepp i månader, och bara genom att bli professionell kan du göra något som kan visas för andra. Det är mycket mer intressant och användbart att omedelbart börja tillämpa den kunskap som erhållits i praktiken.

    För det andra kan ett sådant gränssnitt, när man löser ett problem, bättre formulera vilka parametrar som ska anges, vilka åtgärder och i vilken sekvens som ska utföras och vad som slutligen visar sig. Och visa allt detta på skärmen: inmatningsparametrar motsvarar textinmatningsobjekt, åtgärder - knappar och menyalternativ, resultat - textutmatningsobjekt.

    Ett exempel på att öppna ett projekt med befintlig källkod.

    NetBeans 5.0 hade ett bra exempel på ett GUI -program, men NetBeans 5.5 har inte det. Därför bör du för ytterligare arbete kopiera ett liknande exempel från författarens webbplats eller webbplatsen där denna utbildningskurs publiceras. Exemplet kallas JavaApplicationGUI_example.

    Först ska du packa upp zip-arkivet och extrahera mappen med projektfilerna i den i mappen med dina projekt (till exempel C: \ Documents and Settings \ User). Starta sedan NetBeans om det inte körs och stäng alla öppna projekt så att de inte kommer i vägen. Välj sedan ikonen med Arkiv / Öppna projekt eller på verktygsfältet ikonen med en lila mapp som öppnas eller tryck på tangentkombinationen ++ O. Välj en mapp i dialogrutan som öppnas JavaApplicationGUI_example(det är bättre att inte gå in på det, utan bara ställa in markeringen på den här mappen), klicka sedan på knappen Öppna projektmapp.

    Samtidigt, om du inte avmarkerar kryssrutan "Öppna som huvudprojekt", blir projektet automatiskt det huvudsakliga.

    Följande text visas i källredigeringsfönstret:

    * GUI_application.java

    paket java_gui_exempel;

    * @författare Vadim Monakhov

    public class GUI_application utökar javax.swing.JFrame (

    * Skapar ett nytt formulär GUI_application

    offentlig GUI_application () (

    initComponents ();

    / ** Denna metod kallas inifrån konstruktorn till

    * initiera formuläret.

    * VARNING: Ändra INTE denna kod. Innehållet i denna metod är

    * återskapas alltid av formulärredigeraren.

    private void exitMenuItemActionPerformed (java.awt.event.ActionEvent evt)

    * @param argumenterar kommandoradsargumenten

    public static void main (String args) (

    java.awt.EventQueue.invokeLater (new Runnable () (

    public void run () (

    ny GUI_application (). setVisible (true);

    // Variabeldeklaration - ändra inte

    privat javax.swing.JMenuItem omMenuItem;

    privat javax.swing.JMenuItem innehållMenuItem;

    privat javax.swing.JMenuItem copyMenuItem;

    privat javax.swing.JMenuItem cutMenuItem;

    privat javax.swing.JMenuItem deleteMenuItem;

    privat javax.swing.JMenu editMenu;

    privat javax.swing.JMenuItem exitMenuItem;

    privat javax.swing.JMenu fileMenu;

    privat javax.swing.JMenu helpMenu;

    privat javax.swing.JMenuBar menybar;

    privat javax.swing.JMenuItem openMenuItem;

    privat javax.swing.JMenuItem pasteMenuItem;

    privat javax.swing.JMenuItem saveAsMenuItem;

    privat javax.swing.JMenuItem saveMenuItem;

    // Slut på variabeldeklaration

    Låt oss förklara några av dess delar. Vi är redan bekanta med att ange paketet java_gui_example, som innehåller koden för applikationsklassen. Deklarationen för själva GUI_application -klassen är i detta fall något mer komplicerad än tidigare:

    public class GUI_application utökar javax.swing.JFrame

    Det betyder att den offentliga klassens GUI_application specificeras, som ärver från JFrame -klassen som anges i swing -paketet som ligger i javaxen. Ordet extends översätter till "extends" (den ärvande klassen utökar alltid föräldraklassens möjligheter).

    Den offentliga konstruktören GUI_application () skapar ett applikationsobjekt och initierar alla dess komponenter med initComponents () -metoden, som automatiskt genereras av utvecklingsmiljön och döljs i källkoden av den + genererade kodnoden.

    Genom att expandera noden kan du se implementeringen av denna metod, men du kan inte ändra koden. Vi kommer inte att stanna kvar vid det som görs i den.

    private void exitMenuItemActionPerformed

    Det kommer att diskuteras lite senare. Metod

    public static void main (String args)

    vi är redan bekanta - det här är programmets huvudmetod. Det är en metod för vår applikationsklass och körs automatiskt av Java -maskinen när programmet startar. I det här exemplet skapar metoden en applikationsdisplay och gör den synlig. För att förstå hur detta görs måste du studera ganska mycket material inom ramen för denna kurs.

    Kör applikation. En applikation med en utökad meny.

    När applikationen startas ser skärmen ut som den som visas i figuren. Den har redan en tom meny som kan expandera och kollapsa, och till och med Exit -objektet fungerar. När du klickar på den stänger du programmet.

    Operatören exitMenuItemActionPerformed ansvarar för att klicka på detta menyalternativ. När du utformar ett visningsformulär tilldelas det som händelsehanterare- en delprogram som körs när en händelse inträffar. I vårt fall är händelsen valet av menyalternativet Exit och exitMenuItemActionPerformed -hanteraren anropas. Det finns bara en linje inuti den

    Det får huvudmetoden att avsluta och avsluta applikationen med en nollutgångskod. Som regel returneras en nollutgångskod när programmet avslutas onormalt, så att det med dess värde är möjligt att ta reda på orsakerna till programkraschen.

    Skärmredigerare

    Klicka på fliken Design längst upp till vänster i källredigeraren. I det här fallet kommer vi att växla från redigeringsläget för källkoden (fliken Källa är aktiv) till redigeringsläget för skärmform, som visas i figuren.

    Redigera visningsformuläret.

    I stället för källkoden visar displayen utseendet på displayformuläret och komponenterna på det. Till höger om fönstret där skärmen visas i redigeringsläge finns palettfönstren på komponentpaletten och fönstret Egenskaper för att visa och redigera egenskaperna för den aktuella komponenten.

    En egenskap är ett datafält som efter att ha ändrat värdet kan utföra en åtgärd. Till exempel, när du ändrar bredden på en komponent, rita komponenten med den nya bredden på skärmen. Ett "vanligt" datafält kan inte detta. Således är en egenskap ett "smart datafält".

    Komponentpaletten är utformad för att välja den typ av komponent som programmeraren behöver placeras på skärmen. Låt oss till exempel lägga till en JButton -komponent i vårt formulär (kort för Java Button - "Java -knapp"). För att göra detta, klicka på JButton -objektet på paletten och flytta musen till önskad plats på skärmen. När musen går in i ett område i displayformuläret visas en knapp med standardstorlek på den som rör sig med musen. Om du klickar på rätt plats på formuläret får knappen att stanna på den platsen. En ram och små rutor visas runt den, vilket indikerar att vår komponent är vald. För det visas och redigeras egenskaperna i fönstret Egenskaper.

    Dessutom kommer linjer ut från den valda komponenten och snäpps till dem för att ställa in komponentens position på formuläret.

    Som standard anges komponentetiketter som typnamn följt av komponentnummer. Men i stället för en stor bokstav, till skillnad från typnamnet, används en liten bokstav. Därför kommer den första knappen att märkas jButton1, den andra jButton2, och så vidare. Samma namn kommer att förvärvas av variablerna som motsvarar knapparna som skapas automatiskt i källkoden.

    Det finns flera sätt att ändra etiketten på en knapp. Först genom att dubbelklicka på den och redigera texten. För det andra genom att gå till fönstret Egenskaper, ändra värdet på egenskapen Text och klicka för att slutföra inmatningen. För det tredje genom att ändra etikettegenskapen på ett liknande sätt. Slutligen kan du i fönstret Egenskaper redigera texten inte i fältet med en rad för att ange värden för text- eller etikettegenskaperna, utan genom att öppna redigeraren med flera rader genom att klicka på knappen till höger om egenskapen värderedigeringsobjekt. Redigeraren med flera rader hjälper dock inte till att göra etiketten på knappen flera rader.

    Låt oss skriva inskriften "OK" på knappen - använd den här knappen för att lämna programmet.

    Redigera komponentegenskaper

    Komponentens storlek ställs in med musen genom att ta tag i ramen och expandera eller dra ihop sig i lämpliga riktningar. Installation till en ny plats - genom att dra komponenten med musen.

    Vissa egenskaper för den valda komponenten (dess storlek, position, text) kan ändras direkt i visningsområdet. Men de flesta fastigheter visas och ändras i fastighetsredigeringsfönstret. Den består av två kolumner: den vänstra visar egenskaperna på egenskaperna, den högra visar deras värden. Värdena i den högra kolumnen kan i många fall redigeras direkt i tabellcellerna. I det här fallet slutar posten med att klicka på eller lämna den redigerade cellen och du kan avbryta resultaten av oavslutad inmatning genom att trycka på .

    På höger sida av varje cell finns en knapp märkt "..." - i moderna operativsystem är det vanligt att lägga till tre prickar i namnen på menyalternativ och knappar, efter att ha klickat på vilken en dialogruta öppnas. I det här fallet öppnas fönstret för den specialiserade redigeraren för motsvarande egendom, om den finns.

    Om du behöver visa och redigera ett stort antal komponentegenskaper är det mer bekvämt att högerklicka på önskad komponent och välja "Egenskaper" från popup-menyn som visas. I det här fallet öppnas ett separat fönster för redigering av komponentens egenskaper. Du kan hålla öppet samtidigt ett godtyckligt antal sådana fönster.

    Booleanska egenskaper i kolumnen för fastighetsvärden visas som markeringsknappar för rutor - rutor med en kryssruta inuti. Om det inte finns någon kryssruta är fastighetsvärdet falskt, om det finns är det sant.

    Låt oss lista några av de viktigaste egenskaperna som kan ställas in för komponenter med hjälp av ett exempel på en knapp. Många av dem gäller också andra komponenter.

    Egendomsnamn Vad frågar den
    bakgrund Bakgrundsfärg
    componentPopupMenu Låter dig tilldela en popup-meny som visas när du högerklickar i komponentområdet.
    font Teckensnittet som används för att märka komponenten.
    förgrund Färgen på teckensnittet som används för att märka komponenten.
    ikon Bilden som ritas på komponenten bredvid texten.
    text Texten (etiketten) på komponenten.
    toolTipText Ett verktygstips som visas efter ett tag när musen svävar över en komponent.
    gräns Typ av kant runt komponenten.
    kantmålad Om en gräns dras runt komponenten.
    contentAreaFilled Oavsett om det finns en färgfyllning av komponentens inre område (för knappar skapar det en tredimensionell effekt, utan att fylla knappen ser platt ut).
    defaultCapable Kan knappen vara "standardknapp": när den trycks in “standardknappen” trycks automatiskt (det bör finnas en sådan knapp på skärmformuläret).
    aktiverad Är komponenten tillgänglig. Som standard är alla komponenter som skapas i formuläret tillgängliga. Otillgängliga komponenter ritas med bleka färger.

    Låt oss till exempel lägga till ett verktygstips för vår knapp: ange texten "Den här knappen är avsedd att lämna programmet" i fältet som motsvarar egenskapen toolTipText. Tyvärr kan ledtrådarna bara vara enradig - nylinjetecken ignoreras när ledtråden visas, även om de är programmatiskt specificerade på raden.

    Slutligen, låt oss ställa in den åtgärd som ska utföras när knappen trycks in - händelsehanterare(händelsehanterare) knappklick. För att göra detta, välj först knappen, högerklicka sedan på den och välj objektet / händelsen / åtgärden i popup-menyn som visas.

    Eventhanteringsuppdrag

    Händelser betyder "Händelser", Åtgärd betyder "Åtgärd", åtgärd Utförd betyder "utförd åtgärd".

    Därefter sker en automatisk övergång till källkodredigeraren och en stubbe av en händelsehanterare visas där:

    // TODO lägg till din hanteringskod här:

    Ett liknande resultat kan uppnås på ett snabbare sätt - när vi har valt en knapp i formulärredigeringsfönstret (Design) visas namnet på den här knappen och markeras i Navigator -fönstret. Dubbelklicka på det här namnet i navigatorfönstret skapar en stubbe för händelsehanteraren.

    Bredvid jButton1ActionPerformed -hanteraren kommer det att finnas en befintlig händelsehanterare som utlöses när du klickar på menyalternativet "Avsluta":

    private void exitMenuItemActionPerformed (java.awt.event.ActionEvent evt) (

    Låt oss ersätta kommentarsraden i vår händelsehanterare med koden som får programmet att avslutas:

    private void jButton1ActionPerformed (java.awt.event.ActionEvent evt) (

    Nu, efter att vi har startat vår applikation, kommer muspekaren över knappen att leda till att ett verktygstips ser ut, och genom att klicka på knappen stängs programmet.

    Ett vanligt fall visar ett meddelande när en händelse inträffar, till exempel genom att trycka på en knapp. I detta fall kallas panelen med meddelandet:

    javax.swing.JOptionPane.showMessageDialog (null, "jag blev klickad");

    Om klasserna i javax.swing -paketet importeras krävs prefixet javax.swing inte när du ringer.

    Applikationens utseende

    I redigeringssteget motsvarar utseendet på dess komponenter plattformen. Men när det väl är lanserat blir det helt annorlunda, eftersom alla Java-program som standard visas på ett plattformsoberoende sätt:

    Utseende för en applikation som körs med ett plattformsoberoende användargränssnitt som standard

    Dessutom visas vår applikation i det övre vänstra hörnet av skärmen, men vi vill att den ska visas i mitten.

    För att visa applikationen i en plattformsorienterad form (det vill säga i formuläret som använder komponenterna och inställningarna för operativsystemet) måste du ändra koden för applikationskonstruktören genom att infoga en inställning av användargränssnittstypen (Användarens gränssnitt, förkortat användargränssnitt) innan initComponents -metoden anropas:

    importera javax.swing. *;

    importera java.awt. *;

    offentlig GUI_application () (

    UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());

    ) fångst (Undantag e) ();

    initComponents ();

    Dimension screenSize = Toolkit.getDefaultToolkit (). GetScreenSize ();

    Dimension frameSize = getSize ();

    setLocation (ny punkt ((screenSize.width-frameSize.width) / 2,

    (screenSize.height-frameSize.width) / 2)

    Utseende av en applikation som körs med ett plattformsorienterat användargränssnitt i Windows-operativsystemet ® XP

    Koden efter initComponents () -anropet är för att ställa in programfönstret i mitten av skärmen.

    Det är möjligt att definiera en annan plattformsoberoende applikationstyp - i stil med Motiff, som används i operativsystemet Solaris ®. För att ställa in den här typen, istället för att ringa

    UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ()

    Ska skriva

    UIManager.setLookAndFeel ("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

    Utseende av en applikation som körs med ett plattformsoberoende användargränssnitt i stil med Motiff

    De konstruktioner som används kommer att bli tydliga för läsaren efter att ha studerat de ytterligare avsnitten i den metodiska manualen.

    Projektledning

    För att inte bli förvirrad i olika projekt och deras versioner, särskilt med tanke på att utbildningsprojekt ofta måste överföras från en dator till en annan, bör du ta projektledning på allvar. Som ett resultat av många års övning med olika språk och programmeringsmiljöer har författaren utvecklat följande system (justerat för NetBeans -miljön):

    · En mapp med projektets namn skapas för varje projekt. Låt oss kalla det arkivmappen för detta projekt. Namnen på de mappar som används kan vara på ryska, liksom namnen på applikationer och filer.

    · När du skapar ett nytt projekt uppmanar utvecklingsmiljön dig att ange namnet på mappen där den ska lagras - du bör ange namnet på arkivmappen. Dessutom uppmanas du att ange ett namn på projektet. Detta namn kommer att användas av NetBeans för att skapa projektmappen och namnet på din applikation. För att göra det enklare att arbeta med din ansökan i olika länder, rekommenderas att göra detta namn på engelska. I projektmappen skapar utvecklingsmiljön automatiskt ett undermappsystem för projektet och alla dess filer. NetBeans projektmappstruktur beskrevs tidigare.

    · Om du tar ett projekt med befintlig källkod kopieras mappen till vår arkivmapp antingen manuellt eller genom att välja lämplig sekvens av åtgärder i New NetBeans Project Wizard.

    · När du får en fungerande version av projektet bör du göra en arkivkopia av det. För att göra detta, högerklickar du på projektnamnet i ett öppet projekt i fönstret "Projekt" och väljer "Kopiera projekt" i popup-menyn som visas. Ett dialogformulär öppnas där ett automatiskt genererat kopieringsnamn föreslås - ett understreck och ett kopieringsnummer läggs till i det ursprungliga projektnamnet. För det första exemplaret är det _1, för det andra är det _2, och så vidare. Dessutom är huvudmappen i arkivet som standard densamma som för det ursprungliga projektet. Vilket är mycket bekvämt, eftersom det gör det möjligt att skapa en kopia med bara tre musklick utan att skriva något från tangentbordet.

    Gör en arbetskopia av ett projekt

    Det kopierade projektet visas automatiskt i fönstret Projekt, men blir inte det huvudsakliga. Det vill säga att du fortsätter att arbeta med det tidigare projektet, och alla dess öppna fönster sparas. Du kan omedelbart stänga ett nytt projekt-högerklicka på dess namn och välj "Stäng projekt" i popup-menyn som visas.

    Vad är ett sådant projektledningssystem för? Faktum är att nybörjare programmerare har för vana att förstöra resultatet av sitt eget arbete. De utvecklar projektet utan att bevara arkiv. De tar det till ett nästan fungerande tillstånd, förbättrar det sedan lite mer, sedan ett till - och allt slutar fungera. Och eftersom de är helt förvirrade är det inte längre möjligt att återställa en fungerande version. Och de har inget att visa läraren eller chefen!

    Därför bör du vänja dig vid att kopiera till arkivet alla mellanliggande versioner av projektet, som är mer effektiva än de som redan har sparats i arkivet. I verkliga projekt är det svårt att komma ihåg alla ändringar som gjorts i en viss version, och ännu viktigare, alla relationer som orsakade dessa förändringar. Därför måste även erfarna programmerare säga då och då: "Ingenting fungerar!" Och för att återställa versionen, som ännu inte hade de innovationer som ledde till förvirring. Dessutom händer det ofta att en ny version inte fungerar korrekt i vissa situationer. Och du måste gå tillbaka dussintals versioner på jakt efter den där det inte fanns några sådana "fel". Och jämför sedan noga arbetet med de två versionerna för att ta reda på varför den senare versionen inte fungerar. Eller se till att alla tidigare versioner också fungerade fel, märkte bara inte felet.

  • Sovjetunionens utrikespolitik under kriget. Hyreskontrakt. Teherankonferens. Jalta och Potsdam konferenser 1945 Skapande av FN.
  • Sovjetunionens utrikespolitik under kriget. Lend-Lease. Teherankonferens. Jalta och Potsdam konferenser 1945 Skapande av FN.
  • Återupptagande av BSG -aktiviteter. Skapande av Belnats -partier och organisationer





  • 

    2021 gtavrl.ru.