Dialogdesign med Java Swing – del 2

Börja med en designskiss

Rita med papper och penna, eller med valfritt designverktyg – men undvik att rita i ditt IDE eftersom det är lätt att låsa sig till genererad kod och betydligt lättare att ändra en skiss i det här läget. Därmed undviker du också frestelsen att skapa alla delar i en och samma dialog – det enda det leder till är en oöverskådlig soppa som i sin tur ofta blir ännu värre när du senare inser att olika delar av gränssnittet ska påverkas av andra delar i samma dialog.

Redan på pappret (dvs i designläget) kan du förenkla både för dig och för dina användare genom att dela upp dialogen i olika delar. Det gör både dialogens och de olika panelernas kod mer kompakt, lättläst och enklare att underhålla.

Tyvärr ger de flesta exempel online inte det rådet, vilket gör att man som nybörjare snarare kommer landa i ett hav av oöverskådlig spagettikod där all logik blandas med layouthantering och där det går väldigt fort att gå vilse. De kastar sig snarare in och börjar koda direkt – vänta med det just nu.

Analys och design av dialogmodellen

Av skissen ser vi att vi kommer behöva ha någon form av värdeobjekt som identifierar ett givet tidsintervall och att det intervallet kan komma från två olika källor. Vi kan samtidigt anta att det finns ett för varje källa unikt ID per givet intervall. Det ger oss följande två kodblock:

TidsintervallKalla – en uppräkningsbar typ av källor (lätt att utöka vid behov)

package com.golcher.tidsintervall.komponenter.data;

public enum TidsintervallKalla
{
    Standard,
    Egen
}

TidsintervallVo – det värdeobjekt som ska hålla data om ett specifikt tidsintervall

package com.golcher.tidsintervall.komponenter.data;

public class TidsintervallVo
{
    private final String _id;
    private final TidsintervallKalla _kalla;
    private final String _start;
    private final String _slut;
    private final String _namn;

    public TidsintervallVo(
            String id,
            TidsintervallKalla kalla,
            String start,
            String slut,
            String namn
    )
    {
        _id = id;
        _kalla = kalla;
        _start = start;
        _slut = slut;
        _namn = namn;
    }

    public String getId()
    {
        return _id;
    }

    public TidsintervallKalla getKalla()
    {
        return _kalla;
    }

    public String getStart()
    {
        return _start;
    }

    public String getSlut()
    {
        return _slut;
    }

    public String getNamn()
    {
        return _namn;
    }

    @Override
    public String toString()
    {
        return _start + " - " + _slut + ((_namn.length() > 0) ? "(" + _namn + ")" : "");
    }
}

Som du ser har vi redan brutit ut en egen enum för att ange vilken källa uppgifterna kommer ifrån.

Det kan tyckas knasigt att vi inte valt en boolean istället, men orsaken är att vi dels vinner läsbarhet och dels vinner i anpassningsbarhet genom att ha en uppräkningsbar typ istället för en som bara har två lägen.

Om den här modellen behöver utökas med ytterligare en källa, behöver vi bara utöka vår uppräkningsbara typ – vilket inte går om vi går den “självklara” vägen baserat på vad vi ser i skissen (där det bara finns två källor). Det lönar sig att tänka ett steg extra, i synnerhet när man skapar kod man redan från start vet ska vara så återanvändbar som möjligt.