• No results found

System för registrering av underhållsjour

N/A
N/A
Protected

Academic year: 2021

Share "System för registrering av underhållsjour"

Copied!
79
0
0

Loading.... (view fulltext now)

Full text

(1)

C-uppsats

LITH-ITN-EX--05/010--SE

System för registrering av

underhållsjour

Fredrik Johansson

Peter Lindvall

2005-05-20

(2)

LITH-ITN-EX--05/010--SE

System för registrering av

underhållsjour

Examensarbete utfört i Datorteknik

vid Linköpings Tekniska Högskola, Campus

Norrköping

Fredrik Johansson

Peter Lindvall

Handledare Rickard Klingberg

Examinator Kenneth Bjerner

(3)

Rapporttyp Report category Examensarbete B-uppsats C-uppsats D-uppsats _ ________________ Språk Language Svenska/Swedish Engelska/English _ ________________ Titel Title Författare Author Sammanfattning Abstract

ISBN

_____________________________________________________

ISRN

_________________________________________________________________

Serietitel och serienummer

ISSN

Title of series, numbering ___________________________________

Nyckelord

Keyword

Datum

Date

URL för elektronisk version

Avdelning, Institution

Division, Department

Institutionen för teknik och naturvetenskap

Department of Science and Technology

2005-05-20

x

x

LITH-ITN-EX--05/010--SE

http://www.ep.liu.se/exjobb/itn/2005/de/010/

System för registrering av underhållsjour

Fredrik Johansson, Peter Lindvall

På Bravikens pappersbruk tillämpas idag ej skiftgående underhåll, istället används en underhållsjour

som kallas ut vid problem. T.ex. om en motor havererat. I dagsläget sker en del av denna registrering på

papper, vilket medför att hanteringen blir tidsödande och ineffektiv. I det här examensarbetet har vi

utvecklat ett program som ska underlätta för vakten att registrera dessa jourtillfällen.

Programspråket Java valdes för att utveckla programmet eftersom det går att skriva applikationer som är

direkt körbara från en webbläsare – sk. applets. Alla på intranätet kan då komma åt programmet.

Nackdelen med applets är att den har väldigt begränsade rättigheter. De får t.ex. inte öppna en socket (en

anslutning) till en annan dator. Detta orsakar problem eftersom appleten och databaserna ligger på skilda

servrar. Problemet löstes genom att installera ett ”vidarbefordringsprogram” på samma server som

appleten. Eftersom appleten får ansluta till samma server den är sparad på, kan anslutningen ske till detta

program istället som i sin tur ansluter till databaserna.

Vi använder databasgränsnittet JDBC för all kommunikation med databaserna. Programmet hämtar

information från en databas och lagrar den i en annan. Ett annat önskemål var att programmet skulle ha

flera fönster öppna samtidigt. Eftersom programmet körs från en webbläsare tyckte vi att det var bättre

att använda sig av flikar. Detta gör att det blir mindre rörigt, och lättare för användaren att navigera

mellan jourtillfällena.

(4)

Upphovsrätt

Detta dokument hålls tillgängligt på Internet – eller dess framtida ersättare –

under en längre tid från publiceringsdatum under förutsättning att inga

extra-ordinära omständigheter uppstår.

Tillgång till dokumentet innebär tillstånd för var och en att läsa, ladda ner,

skriva ut enstaka kopior för enskilt bruk och att använda det oförändrat för

ickekommersiell forskning och för undervisning. Överföring av upphovsrätten

vid en senare tidpunkt kan inte upphäva detta tillstånd. All annan användning av

dokumentet kräver upphovsmannens medgivande. För att garantera äktheten,

säkerheten och tillgängligheten finns det lösningar av teknisk och administrativ

art.

Upphovsmannens ideella rätt innefattar rätt att bli nämnd som upphovsman i

den omfattning som god sed kräver vid användning av dokumentet på ovan

beskrivna sätt samt skydd mot att dokumentet ändras eller presenteras i sådan

form eller i sådant sammanhang som är kränkande för upphovsmannens litterära

eller konstnärliga anseende eller egenart.

För ytterligare information om Linköping University Electronic Press se

förlagets hemsida

http://www.ep.liu.se/

Copyright

The publishers will keep this document online on the Internet - or its possible

replacement - for a considerable time from the date of publication barring

exceptional circumstances.

The online availability of the document implies a permanent permission for

anyone to read, to download, to print out single copies for your own use and to

use it unchanged for any non-commercial research and educational purpose.

Subsequent transfers of copyright cannot revoke this permission. All other uses

of the document are conditional on the consent of the copyright owner. The

publisher has taken technical and administrative measures to assure authenticity,

security and accessibility.

According to intellectual property law the author has the right to be

mentioned when his/her work is accessed as described above and to be protected

against infringement.

For additional information about the Linköping University Electronic Press

and its procedures for publication and for assurance of document integrity,

(5)

Sammanfattning

På Bravikens pappersbruk tillämpas idag ej skiftgående underhåll, istället används en

underhållsjour som kallas ut vid problem. T.ex. om en motor havererat. I dagsläget sker en del

av denna registrering på papper, vilket medför att hanteringen blir tidsödande och ineffektiv. I

det här examensarbetet har vi utvecklat ett program som ska underlätta för vakten att

registrera dessa jourtillfällen.

Programspråket Java valdes för att utveckla programmet eftersom det går att skriva

applikationer som är direkt körbara från en webbläsare – sk. applets. Alla på intranätet kan då

komma åt programmet. Nackdelen med applets är att den har väldigt begränsade rättigheter.

De får t.ex. inte öppna en socket (en anslutning) till en annan dator. Detta orsakar problem

eftersom appleten och databaserna ligger på skilda servrar. Problemet löstes genom att

installera ett ”vidarbefordringsprogram” på samma server som appleten. Eftersom appleten får

ansluta till samma server den är sparad på, kan anslutningen ske till detta program istället som

i sin tur ansluter till databaserna.

Vi använder databasgränsnittet JDBC för all kommunikation med databaserna. Programmet

hämtar information från en databas och lagrar den i en annan. Ett annat önskemål var att

programmet skulle ha flera fönster öppna samtidigt. Eftersom programmet körs från en

webbläsare tyckte vi att det var bättre att använda sig av flikar. Detta gör att det blir mindre

rörigt, och lättare för användaren att navigera mellan jourtillfällena.

(6)

Abstract

At the Braviken paper mill a non-shiftworking maintenance is applied today. Instead they use

a maintenance duty group which is called in for example if an engine has broken down. Today

a part of this registration is on paper which makes the handling time consuming and

inefficient. In this thesis we have developed a program which will make it easier for the guard

to register these duty occasions.

The program language Java was chosen to develop the program, as you can write applications

which are directly applicable from a webreader so-called applets. Then everybody with

intranet can reach the program. The disadvantage with applets is that it has got very limited

rights. Thery must not for example open a socket (a connection) to another computer.This

causes problems as the applet and the database are on different servers. The problem is solved

by installing a forwarding program on the same server as the applet. As the applet is allowed

to connect to the same server on which it is saved, the connection can be done to this program

instead which then connects to the databases.

We use the database limit JDBC for all communication with the databases. The program gets

information from one database and stores it in another one. Another desire was that the

program should be able to have more windows open at the same time. As the program is

driven from a webreader, we thought it was better to use flaps. That makes it less complicated

and easier for the user to navigate between the duty occasions.

(7)

Förord

Det har varit ett väldigt lärorikt examensarbete på Bravikens pappersbruk. Under vår studietid

har vi endast gjort mindre projekt, som varit relativt begränsade. Naturligtvis kan vi inte allt

från början, men har nu sett att vi har kunskaper nog för att läsa in helt nya områden och

förstå dem. Visst har det funnits problem, men inga så stora att de varit oöverkomliga, även

om det sett mörkt ut ibland. Utan dessa problem hade dock arbetet känns ganska platt, och

varit trist att utföra. Det är trots allt misstagen man lär sig av.

Vi vill tacka Bravikens pappersbruk för att vi fick möjlighet att göra vårt examensarbete hos

Er. Ett speciellt tack till Rickard Klingberg för din goda handledning och stora engagemang.

Tack även till Gösta Nilsson och Jan Rask för att Ni ställt upp när vi har haft problem med vår

databas.

Examensarbetet har gett oss en liten inblick i hur ett framtida jobb skulle kunna se ut.

Förhoppningsvis har vi även skapat nya kontakter som vi kan dra nytta av senare.

Peter Lindvall

Fredrik Johansson

(8)

Innehållsförteckning

1

INLEDNING... 1

1.1

P

ROBLEMSTÄLLNING

... 1

1.2

S

YFTE

... 1

1.3

O

MFATTNING

... 1

1.4

B

RAVIKENS PAPPERSBRUK

... 1

1.5

R

APPORTENS STRUKTUR

... 2

2

JOURSYSTEMET ... 3

2.1

B

AKGRUND

... 3

2.1.1

Hanteringen idag ... 3

2.1.2

Hanteringen imorgon ... 3

2.1.3

Val av programspråk... 3

2.1.4

Java ... 4

2.1.5

JApplet kontra JFrame... 4

2.1.6

Databasgränssnitt ... 5

2.2

S

ÄKERHETEN I EN

A

PPLET

... 6

2.2.1

Signerad Applet... 6

2.2.2

Oracle Connection Manager... 7

2.3

K

ONFIGURATION AV

O

RACLE

C

ONNECTION

M

ANAGER

... 8

2.4

J

OURDATABASEN

... 8

2.5

P

ROGRAMMERING

... 10

2.5.1

Förarbete och brainstorming ... 10

2.5.2

Egna klasser... 10

2.5.3

Databaskonstruktion ... 13

2.5.4

Konvertering till Applet... 14

2.5.5

Design ... 15

2.5.6

Flikhantering... 18

2.5.7

Test och justeringar... 20

3

RESULTAT ... 22

3.1

S

LUTSATSER

... 22

3.2

R

EKOMMENDATIONER FÖR FORTSATT ARBETE

... 22

4

REFERENSLISTA... 23

4.1

T

RYCKTA KÄLLOR

... 23

4.2

E

LEKTRONISKA KÄLLOR

... 23

5

BILAGOR ... 24

5.1

K

ONFIGURATION AV

O

RACLE

C

ONNECTION

M

ANAGER

... 24

5.1.1

cman.ora ... 24

5.1.2

tnsnames.ora ... 24

5.1.3

Installationsanvisning i Windows... 25

5.2

I

NSTALLATIONSANVISNING FÖR APPLET

... 25

5.2.1

Färdigställande av applet ... 25

5.2.2

Installation på wxebbserver ... 26

5.3

P

ROGRAMKOD

... 27

5.3.1

JourApplet.java ... 27

5.3.2

RapportApplet.java ... 43

5.4

E

GNA KLASSER

... 61

5.4.1

DBControl.java ... 61

5.4.2

TimeDateControl.java... 65

5.4.3

JTableControl.java... 67

(9)

Figur- & tabellförteckning

F

IG

.

1:

F

RÅN

SQLJ

TILL KÖRBART PROGRAM

. ... 5

F

IG

.

2:

S

IGNERAD APPLET

. ... 6

F

IG

.

3:

C

ONNECTION

M

ANAGER

... 7

F

IG

.

4:

S

Å HÄR FUNGERAR VYN

... 8

F

IG

.

5:

V

AD SOM HÄMTAS FRÅN

IFS

NÄR ETT ARBETSORDERNUMMER SKRIVS IN

... 9

F

IG

.

6:

E

XEMPEL PÅ HUR JOURTABELLERNA RELATERAR TILL VARANDRA

. ... 9

F

IG

.

7:

UML-

DIAGRAM ÖVER PROGRAMMETS KLASSER

... 12

F

IG

.

8:

G

RÄNSSNITT

1

(S

TARTSIDAN

) ... 15

F

IG

.

9:

G

RÄNSSNITT

1

MED EXEMPEL PÅ EN COMBOBOX

... 15

F

IG

.

10:

G

RÄNSSNITT

2 ... 16

F

IG

.

11:

I

NMATNING AV ANSTÄLLNINGSNUMMER UTAN ATT TRYCKA ENTER

... 16

F

IG

.

12:

E

FTER ENTERSLAG FYLLS DE ÖVRIGA FÄLTEN I AUTOMATISKT

... 16

F

IG

.

13:

I

NMATNING AV ARBETSORDERNUMMER UTAN ATT TRYCKA ENTER

... 17

F

IG

.

14:

E

FTER ENTERSLAG FYLLS DE ÖVRIGA FÄLTEN I AUTOMATISKT

... 17

(10)

1 Inledning

1.1 Problemställning

De problemställningar en programmerare allmänt ställs inför är inte alltid lätta att förutse, allt

eftersom arbetet fortskridit har nya problem dykt upp. Nedanstående lista visar vilka

funderingar som fanns innan examensarbetet startade.

• Vilket programspråk är lämpligast att utveckla i?

• Vilken databaslösning skall användas?

• Hur sker kommunikationen mot den interna databasen?

• Hur skall användargränssnittet se ut?

• Hur skall jourdatabasen utformas?

• Hur skall programmet skrivas för att vara lättåtkomligt av alla?

1.2 Syfte

På Bravikens pappersbruk tillämpas idag ej skiftgående underhåll, istället används en

underhållsjour som kallas ut vid problem. Planering och avrapportering sker idag helt

manuellt, och en Word-fil på intranätet visar vem som har jouren.

Vår uppgift är att utveckla ett nytt system för att underlätta registreringen av underhållsjouren.

Systemet skall göra det lättare att t.ex. föra statistik, samt underlätta den för tillfället krångliga

hanteringen.

1.3 Omfattning

Det här examensarbetet omfattar 10 veckor, dvs. 10 poäng, och är en del av en

högskoleingenjörsexamen i Data- och Elektroteknik. Vi har utvecklat ett program åt

Bravikens pappersbruk för att på ett enklare och effektivare sätt registrera deras

underhållsjour. Ca sju veckor har avsatts åt utveckling och de resterande tre åtgår till små

justeringar i programmet och rapportskrivning.

1.4 Bravikens pappersbruk

Bravikens pappersbruk ligger utanför Norrköping vid Bråvikens början. Braviken invigdes

1977, och med sina tre pappersmaskiner har de slagit det ena världsrekordet efter det andra.

Produktionskapaciteten är 700.000 ton papper per år och företaget har drygt 700 anställda.

Bravikens pappersbruk tillverkar vitt och färgat papper. T.ex. det rosa papper Aftonbladets

sportbilaga är tryckt på. Huvuddelen av Bravikens produktion säljs på export, endast 10%

stannar i Sverige.

Braviken är ett av fyra bruk i Holmen-koncernen. De övriga är Vargön, Madrid och

Halstavik.

(11)

1.5 Rapportens struktur

Rapporten är uppdelad i fyra delar vilka beskrivs kort nedan.

Kap. 1 : Inledning

Den här delen behandlar bakgrunden till varför detta arbete utförts, vilka problemställningar

som fanns samt en kort presentation av företaget.

Kap. 2 : Joursystemet

Detta är rapportens huvuddel. Den börjar med lite inledande teori, och avslutas med en

detaljerad redogörelse av utvecklingsarbetet och de problem som uppkommit.

Kap. 3 : Resultat

Här presenteras vad vi kommit fram till och vilka slutsatser som gjorts. Avsnittet slutar med

förslag på vidareutveckling av programmet.

(12)

2 Joursystemet

2.1 Bakgrund

2.1.1 Hanteringen idag

Bravikens pappersmaskiner är i drift dygnet runt. På dagtid finns det alltid personal på plats

som kan rycka ut om något går sönder. På natten däremot, jobbar endast skiftlaget. Om något

skulle hända då måste en arbetsorder utfärdas av en processingenjör. Arbetsordern är en

specifikation på vad som har hänt och åtgärder som skall utföras. En motor kan t.ex. haverera,

och behöver i så fall bytas snarast. Arbetsordern skickas sedan till vakten. Vakten i sin tur

ringer ut behövd personal, i det här fallet t.ex. en elektriker och en mekaniker. Jourhavande

vakt registrerar när personalen ankommer och går hem. Detta görs direkt i Bravikens

underhållssystem (IFS).

Skulle det bli fel i inmatningen finns det inget sätt att radera misstaget. Istället skrivs en

”inverterad” rad som tar ut den felaktiga. Om det t.ex. blivit åtta timmar av misstag, måste det

korrigeras med en ny rad där det står minus åtta timmar. Denna hantering är omständlig, och

medför att listorna kan bli väldigt plottriga. Registrering av jourtillfälle skickas från vakten,

på papper, till personalavdelningen som skriver in uppgifterna i lönesystemet.

2.1.2 Hanteringen imorgon

Meningen med programmet är att det inte ska behövas någon onödig hantering av papper.

Vakten får precis som förut en arbetsorder, men istället för att sätta den i en pärm för

vidarebefordran, skapar vakten ett nytt jourtillfälle där uppgifterna förs in. På så sätt finns alla

uppgifterna på ett ställe och är tillgängligt för alla parter, eftersom programmet är åtkomligt

från intranätet. Det blir t.ex. lättare för personalen att följa upp sitt eget arbete. Det underlättar

även för sektions- och gruppcheferna att se vilken personal som varit ute under natten, och

vilka åtgärder som utförts. Inom en snar framtid är det även tänkt att lönekontoret skall ta sina

uppgifter direkt från programmet. Andra fördelar med programmet är att det är överskådligt

och lätt att använda. Funktioner som att radera en felaktig rad är nu inte längre omöjligt.

2.1.3 Val av programspråk

Enligt önskemål skall programmet kunna köras i en webbläsare, vilket skulle underlätta då

installation inte behövs. JSP (Java Server Pages), C# och Java är tre programspråk som kan

användas för att lösa uppgiften.

JSP är bra för att det är ett serverbaserat språk och kan användas oberoende av webbläsare.

Det som är mindre bra är att det inte går att skapa ett bra gränssnitt på ett lätt sätt. Språket är

beroende av HTML (Hypertext Markup Language) och CSS (Cascading StyleSheets) för att

bygga designen. Detta är absolut inte det bästa eller lättaste sättet att bygga upp gränssnittet

på.

(13)

C# är ett stabilt och snabbt språk som kan användas för att skapa t.ex. webservices. Det är ett

sätt att exekvera programkod direkt i en webbläsare. Koden körs då via Microsofts .NET

Framework. Eftersom det inte var säkert att Microsoft .NET Framework var installerat på alla

företagets datorer, och p.g.a. att vår kontakt med språket är relativt liten, blev detta inte vårt

val.

Java använder sig av en VM (Virtual Machine) från antingen Sun eller Microsoft. Alla

Bravikens datorer har som standard en VM installerad, vilket är ett väldigt starkt argument för

att välja Java. I vår utbildning har vi dessutom använt detta språk frekvent, och därför blev

detta vårt val.

2.1.4 Java

Java är ett programspråk som utvecklats av Sun Microsystems. Det släpptes 1995 och bygger

på programspråket C++. Språkets första användningsområde var som små applikationer

(applets) som användes för att ge liv åt hemsidor. Det kunde t.ex. handla om små spel och

animationer. Java är dock så mycket mer än så. Det är ett fullvuxet programspråk, som kan

användas för att skapa liknande applikationer som t.ex. i C++.

Det som gör Java speciellt intressant är:

• Java är plattformsoberoende, vilket betyder att det inte spelar någon roll vilket

operativsystem användaren kör. Programmet är alltså körbart oavsett datorsystem.

• Java har utmärkta funktioner för att skapa grafiska användargränssnitt. Även de är

plattformsberoende, och kommer att se likadana ut på alla datorsystem.

• Java är ett objektorienterat språk. Alla variabler är samverkande objekt som beskrivs

av klasser.

• Java stöder trådar (threads) som möjliggör att programmet kan utföra flera saker

samtidigt. T.ex. mata in text samtidigt som en rörlig bild visas.

Detta var fördelarna, men precis som med alla andra språk har Java även nackdelar. Den

största nackdelen är prestandan, exekveringen sker betydligt långsammare än t.ex. C++.

Anledningen till detta är att Java interpreteras i realtid vid programkörning, medan t.ex. C++

gör om koden till maskinkod redan vid kompileringen.

2.1.5 JApplet kontra JFrame

JApplet och JFrame är två Swing-klasser i Java som används för att bygga grafiska

användargränssnitt.

JFrame är ett vanligt programfönster och fungerar precis som vilket annat windows-program

som helst. Allt som går att göra i ett vanligt program kan även göras här, t.ex. radera eller

skapa filer på den lokala hårddisken.

JApplet har till skillnad från en JFrame ingen egen fönsterhanterare. Poängen med en applet

är att den skall köras i din webbläsare. På så sätt kommer programmet att vara tillgängligt

oavsett var du befinner dig, bara det finns en internetuppkoppling.

(14)

Skriv ditt SQLJ-program Översätt och kompilera Kör programmet .sql .class

Det finns egentligen bara tre väsentliga skillnader mellan en JApplet och en JFrame.

• Den klass

1

man konstruerar skall vara en subklass till JApplet istället för JFrame.

• Konstruktorn

2

ersätts mot en init-funktion.

• Det behövs ingen metod med namnet main

3

.

2.1.6 Databasgränssnitt

Java och en databas, av valfri sort, pratar inte samma språk. Det kan jämföras med att en

svensk och en tysk pratar med varandra på respektive modersmål. Ingen av parterna kommer

att förstå varandra. Det behövs alltså en tolk.

Precis på samma sätt behöver Java en tolk för att kunna prata med databasen. JDBC och

SQLJ är de två största databasgränssnitten för Java. Vilken lämpar sig då bäst för uppgiften?

JDBC (Java Database Connectivity) är ett API (programmeringsgränssnitt) för att

kommunicera med en databas med hjälp av Java. Förutom API:n består JDBC även av en

drivrutin. Denna arkitektur innebär att utformningen av javaprogrammet blir den samma

oavsett vilken databas som anropas. Ett byte av databasserver innebär endast ett byte av

drivrutin för att det skall fungera igen. Denna lösning kan därför betraktas som plattforms-

och produktoberoende.

SQLJ är en ny standard för att skriva SQL-frågor direkt i Java. Det är en öppen standard som

utvecklats bl.a. av Oracle och IBM. I SQLJ är det enklare att skriva komplicerade SQL satser.

Detta för att programmeraren enklare kan använda sig av egna variabler i SQL-frågan.

Fig. 1: Från SQLJ till körbart program.

JDBC har inget sätt att kontrollera om SQL-frågan blivit korrekt ställd. SQLJ däremot, har en

inbyggd felkontroll. Koden måste nämligen kompileras för att översätta SQL till Java innan

det går att kompilera själva programmet. Därför hittas alla SQL-fel under kompileringen

istället för vid programkörning, som sker med JDBC.

SQLJ körs ovanpå JDBC, vilket innebär att JDBC måste implementeras innan SQLJ kan

användas. Det betyder att två standarder måste läras in istället för en. Behovet av avancerande

SQL-satser är i detta fall minimalt, därför blev JDBC det givna valet.

1

En beskrivning av hur ett objekt ser ut och beter sig kallas klass

2

Den metod som anropas varje gång det skapas ett objekt av klassen.

3

Den fösta metod som alltid anropas när ett program av typen JFrame körs.

(15)

Applet

³

Signerad Applet

2.2 Säkerheten i en Applet

Att det skulle finnas begränsningar i vad en applet får och inte får göra, var inget som någon

av oss hade en tanke på. Själva idén med att utveckla en applet blev därför inte lika lätt som

förväntat. Det visade sig att en applet inte får göra allt som en applikation får göra. En

applikation har full tillgång till datorn och filsystemet, dvs. det går t.ex. bra att skapa eller ta

bort en fil. Den får även öppna en socket till valfri dator. En applet däremot, kan bara öppna

en socket mot den server den är hämtad från. Den har heller ingen access till det lokala

filsystemet.

Dessa restriktioner finns på grund av att en applet är ett körbart program som kan kommas åt

av alla, eftersom den ligger på en webbserver och inte kräver någon installation. Det räcker

med att användaren surfar in på webbsida för att det skall vara för sent. Om inte dessa

restriktioner fanns skulle appleten enkelt kunna göra mer skada än nytta.

Detta vållade ett stort problem, ty appleten skall vara lättåtkomlig för alla, men samtidigt

kunna ansluta till en annan dator. Efter några dagars forskande uppenbarade sig två lösningar

på problemet – Signerad Applet och Connection Manager.

2.2.1 Signerad Applet

Ett sätt att helt släppa på de restriktioner som finns är att signera sin applet. Den får då samma

rättigheter som en vanlig applikation. Det första som måste göras är att skapa ett certifikat.

Vid skapandet skall du mata in namn, adress, företagsnamn, och land. Meningen med ett

certifikat är att du som utvecklare intygar att innehållet i appleten är säkert, och inte bringar

någon skada. Eftersom du går i god för programmet, släpps alla säkerhetsrestriktioner.

Problemet är att det inte finns någon kontroll på att ditt certifikat är äkta, d.v.s. innehåller

sanningsenliga uppgifter. Det går jättebra att hitta på alla uppgifter i certifikatet, och på så sätt

slippa allt ansvar. Därför finns det företag som går emellan och intygar att uppgifterna i

certifikatet är riktiga. Företagen tar dock ofta, för att inte säga alltid, ut en rejäl summa pengar

för den här tjänsten.

När certifikatet är skapat skall det kopplas till en applet för att fungera. Varje gång en

användare sedan surfar in på webbsidan får han en fråga om appleten får köras. Om han

godkänner kommer appleten att köras med full access. Detta kan vara riskabelt om inte

användaren vet vem som egentligen signerat appleten.

(16)

Databas

Connection

Manager

Applet

 Dator ett

 Dator två

Fördelen med den här metoden är att appleten får precis alla spärrar hävda, dvs. full access.

Det här är också den enda fördelen. Nackdelarna är desto fler. Till och börja med finns det

ingen standard för hur en applet skall signeras. Processen är beroende av vilken webbläsare

som används, och även vilken version av javatolken som är installerad. Signaturerna är inte

heller kompatibla med varandra.

Under projektets gång testades ett dussin olika sätt att signera appleten. Inget fungerade. Med

tanke på att det saknas en standard för hur signering skall gå till, är metoden ganska värdelös

och ger därför ingen lösning på problemet.

2.2.2 Oracle Connection Manager

En connection manager (hädanefter CM) fungerar ungefär som en router

4

. Det är alltså

möjligt att ansluta till den, och via den ansluta till en annan server. Om t.ex. CM är installerad

på samma server som appleten undviks problemet med att det inte går att skapa sockets till

andra datorer. Appleten ansluter alltså till CM som i sin tur skapar anslutningen till den andra

maskinen.

Fördelarna med det här tillvägagångssättet är att ingen hänsyn behöver tas till vare sig

javatolk eller webbläsare. Appletens säkerhetsrestriktioner finns fortfarande kvar, så

användaren behöver inte vara orolig att något skall hända med dennes dator. Det blir ingen

krånglig hantering med t.ex. certifikat. Användaren kommer inte ens att märka av att CM

arbetar i bakgrunden, appleten beter sig precis som vanligt.

Nackdelarna är att anslutningssyntaxen i koden blir lite annorlunda, jämfört med att ansluta

direkt till den andra datorn. Om appleten avslutats utan att anslutningen stängts på ett riktigt

sätt, kommer anslutningen i CM att ligga kvar och låsa upp processen. Detta medför att CM

måste startas om för att fungera igen. Därför bör programmeraren skriva koden så att

anslutningarna till CM alltid stängs oavsett hur appleten avslutas.

I och med att CM uppfyller allt som behövs blev detta lösningen på problemet.

Fig. 3: Connection Manager

(17)

Applet

Databasvy

A_vy B_vy

Databas

A B

2.3 Konfiguration av Oracle Connection Manager

I filen cman.ora ställs lyssnaren in. Där specificeras vilken ip- och port-adress CM skall

lyssna på.

cman = (ADDRESS_LIST=

(ADDRESS=(PROTOCOL=tcp)(HOST=lyssnarip)(PORT=1630)) )

cman_admin = (ADDRESS=(PROTOCOL=tcp)(HOST=lyssnarip)(PORT=1830))

Lyssnaren ställs in för att datorn skall känna av när ett program försöker ansluta till managern.

I konfigureringsfilen tnsnames.ora anges alla hopp som CM skall kunna göra. Med hopp

menas vilken server CM skall omdirigera trafiken till.

CMAN_IFS.WORLD = (DESCRIPTION = (ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = lyssnarip)(PORT = 1630)) (ADDRESS = (PROTOCOL = TCP)(HOST = databasip)(PORT = 1521)) ) (SOURCE_ROUTE = yes) (CONNECT_DATA = (SERVICE_NAME = pumaprod) ) )

Första adressraden anger vilken port och ip som Connection Managern skall lyssna på. Andra

raden i adresslistan anger vilken adress den skall ansluta till. För varje ny server som skall

läggas till, måste en liknande konfiguration göras i tnsnames.ora.

Managern startas med kommandot cmctl start och ligger därefter som en process på servern.

För att testa om Connection Managern fungerar som den ska kan kommandot tnsping

användas. För att testa ovanstående omdirigering ges kommandot: tnsping cman_ifs. Om allt

fungerar som det ska, skall ett svar från ”HOST = databasip” returneras.

2.4 Jourdatabasen

Bravikens pappersbruk använder Oracles databassystem som koncernstandard. I och med det

användes även Oracles system när jourdatabasen skulle skapas. Data till jourdatabasen hämtas

från IFS. Det är ett relativt nytt system, vilket gör att databasens design fortfarande kan

komma att ändras. Därför skapades s.k. vyer som fungerar som ett mellanled mellan

databasen och programmet. Kolumnerna i vyerna är kopplade till databasens kolumner. Om

en kolumn i databasen ändras, behöver den bara pekas om i vyn och inte ändras i koden.

(18)

IFS-databasen används för att hämta personal- och arbetsorderdata till programmet. Detta

görs dels för att kontrollera om användaren fyllt i rätt uppgifter och dels för att undgå att

behöva skriva sådant som redan finns i systemet. T.ex. hämtas all relevant data om en

arbetsorder så fort ett giltigt arbetsordernummer matas in.

Fig. 5: Vad som hämtas från IFS när ett arbetsordernummer skrivs in.

Jourdatabasen består av tre tabeller – jourid, jourpersonal och jourorder. Den första tabellen

innehåller alla skapade jourtillfällen, de åtskiljs genom ett unikt id-nummer. Id-numret räknas

upp automatiskt när ett nytt jourtillfälle skapas. Jourpersonal och jourorder innehåller den

personal och de arbetsordrar som tillhör respektive jourtillfälle. I dessa två tabeller är inte

id-numret unikt, t.ex. om ett jourtillfälle har flera arbetsordrar, har de också samma id-nummer.

På detta sätt är det lätt att plocka ut vilka ordrar och vilken personal som hör till respektive

jourtillfälle.

Jourid

Id Datum

Tid

1 2005-04-18

22:14

2 …

Jourpersonal

Id Namn

Arbetstid

1 Kalle

Karlsson

08:00

1 Sven

Svensson

03:30

2 Anna

Andersson 04:00

Jourorder

Id AO.nr.

Arbetsbeskrivning

1

324654

Byte av vals

1

554878

Byte av motor

1 426587

Korrigering

av

inloppslåda

2 365533

2 125546

Fig. 6: Exempel på hur jourtabellerna relaterar till varandra.

I exemplet ovan är det lätt att se vilka rader i tabellerna som hör ihop. Det går t.ex. att utläsa

att det skapades ett jourtillfälle den 18 april 2005 klockan 22:14. Kalle Karlsson och Sven

Svensson kallades ut och utförde arbetsordrarna 324654, 554878 och 426587. Observera att

tabellerna är ofullständiga, och bara är till för att tydliggöra hur relationerna fungerar.

(19)

2.5 Programmering

Detta avsnitt behandlar arbetsgången från idé till färdig produkt. Läsaren kommer att guidas

genom hela utvecklingsarbetet med mer detaljerade beskrivningar av eventuella problem och

lösningar.

2.5.1 Förarbete och brainstorming

Den fråga som först dök upp var på vilket sätt programmet skall skrivas för att på ett så enkelt

sätt som möjligt kunna användas av alla. Vi kom snabbt överens om att ett webbgränsnitt var

den bästa lösningen. Javas fördelar övervägde och lösningen med att skriva en applet medför

att programmet blir lättåtkomligt utan krångliga installationer.

Från början önskades det att varje jourtillfälle skulle ha ett eget fönster, och flera fönster

skulle kunna vara öppna samtidigt. Det kanske inte var den bästa lösningen. Istället funderade

vi på att använda oss av flikar. Detta gör att det endast behövs ett fönster, samt att det blir

lättare att organisera de olika jourtillfällena.

2.5.2 Egna klasser

Programmet är till största del uppbyggt av tabeller i olika storlekar. All information, som inte

matas in manuellt, hämtas från databaser. Det skall finnas bra hantering för datum och tid,

med möjlighet att beräkna tidsskillnader som sträcker sig över datumgränsen. Med detta i

åtanke skapades tre klasser för dessa ändamål.

JTableControl.java

Klassen används för att kontrollera och styra allt som har med tabeller att göra. Den ser ut på

följande sätt.

Instansvariabler

DefaultTableModel model Tabellmodell. JTable t Tabell. JScrollPane sp Rullningslist.

int nrColumns Håller reda på hur många kolumner en tabell innehåller. boolean COL_SELECT Bestämmer markeringsläge.

boolean ROW_SELECT Bestämmer markeringsläge.

boolean REORDER Anger om tabellens kolumner får byta plats med varandra eller inte.

Instansmetoder

JTableControl(boolean editable) Konstruktor. Skapar ett nytt tabellobjekt. Editable sätts till true om tabellen inte skall vara editerbar.

getTableInScrollpane() Returnerar tabellen i en rullningslist.

getTable() Returnerar tabellen. getTableModel() Returnerar tabellens modell.

GetCellValue(int row, int col) Returnerar värdet på cellposition (rad, kolumn). setSizeOfTable(int x, int y) Bestämmer tabellens storlek i pixlar. setColumnNames(String[] s) Sätter kolumnnamn via en bifogad strängarray. AppendRow(Object[] o) Lägger till en rad sist i tabellen. deleteRow(int rowNr) Tar bort rad på position rowNr. deleteAllRows() Tar bort alla rader från tabellen.

addEmptyRow(int n) Lägger till n stycken tomma rader i tabellen. addComboToColumn(int nrCols, String[] s)

Ändrar kolumnens inmatningsläge till valbar lista. Variablen nrCols bestämmer i vilken kolumn ändringen skall ske, s innehåller de val som skall gå att göra.

getSelRow() Returnerar den markerade radens index. getSelColumn() Returnerar den markerade kolumnens index. setColumnWidth(int c, int width) Bestämmer kolumnbredd.

(20)

TimeDateControl.java

Det finns även en del tidsberäkningar som behöver göras. När ett jourtillfälle skapas ska

programmet automatiskt registrera aktuellt datum och tid. Det ska även gå att beräkna

tidsskillnaden mellan två tider, oavsett om de överskrider datumgränsen. T.ex. beräkna tiden

mellan 22.10 idag till 01.10 imorgon. För att lösa detta beräknas tiden från tillfälle ett till

tillfälle två i millisekunder. Sedan omvandlas den totala tiden till timmar och minuter.

public String calcDifference(TimeDateControl dtc) {

long diffMillis = dtc.c.getTimeInMillis()-this.c.getTimeInMillis(); long diffMins = (diffMillis/(60*1000))+(dtc.hour*60+dtc.min)- (this.hour*60+this.min);

long diffHours = diffMins/60; diffMins = diffMins%60;

return timeFormat((int)diffHours,(int)diffMins); }

Variabeln diffMillis lagrar skillnaden mellan datumen i tillfälle ett och två, och sparar det

svaret som millisekunder. Sedan omvandlas diffMillis till minuter i diffMins, där tas även

hänsyn till den aktuella tiden på respektive tillfälle. Antalet timmar och minuter returneras

genom funktionen timeFormat, som ger tiden rätt form. Åtta timmar och 2 minuter blir

”08:02” istället för ”8:2”.

Instansvariabler

Calendar c Kalenderobjekt int year År

int month Månad int day Dag int hour Timme int min Minut

Instansmetoder

TimeDateControl() Dafaultkonstruktor. Skapar ett tidsobjekt med aktuell tid och datum. TimeDateControl(int h, int m)

Konstruktor. Skapar ett tidsobjekt där variablerna h sätter timmarna och m sätter minuterna.

TimeDateControl(String timestamp)

Konstruktor. Skapar ett tidsobjekt med valbar datum och tid, genom att skicka med en timestamp: ”YYYY-MM-DD, HH:MM”. timeFormat(int h,int m) Justerar tidsformat från t.ex. 8:3 till 08:03. getTime() Returnerar aktuell tid.

getDate() Returnerar aktuellt datum. getYesterday() Returnerar gårdagens datum.

calcDifference(TimeDateControl dtc) Beräknar tidsskillnaden mellan två tidsobjekt. isAnkAfterKlar(TimeDateControl dtc) Returnerar true om ankomsttid är före klartid.

(21)

Jourapplet DBControl TimeDateControl JTableControl JApplet ActionListener TableChangeListener

Den sista klassen hanterar allt som har med databaser och anslutningar att göra. Klassen

innehåller funktioner som att ansluta till, ställa frågor och infoga data i databasen.

Funktionerna är samlade i filen DBControl.java.

Instansvariabler

Statement s Behövs för att ställa frågor till databasen. Connection c Behövs för att skapa en anslutning. ResultSet rs Svaren från databasen sparas här. String DB_ADR_LISTEN Connection Managerns adress. String DB_PORT_LISTEN Connection Managerns portnr. String DB_ADR Databasens adress.

String DB_PORT Databasens portnr. String DB_SID Databasens SID. String USER Användarnamn. String PASS Lösenord.

Instansmetoder

DBControl(String dba, String dbp, String dbi, String u, String p)

Konstruktor. Skapar ett databasobjekt med all information som behövs för att ansluta. Dba anger ip-adress, dbp anger port, dbi anger vilket SID som skall användas, u är avändarnamn och p är lösenord. dbConnect() Ansluter till databasen

dbDisconnect() Kopplar från anslutningen getResultSet() Returnerar databasens svar som ett ResultSet.

getResult(String s) Returnerar svaret som en stringarray. S anger vilken kolumn som skall hämtas. dbQuery(String vars, String table, String

order)

Skapar databasfråga med kolumnnamn, tabell och sortering som inparametrar. dbQuery(String vars, String table) Skapar databasfråga med kolumnnamn, tabell som inparametrar. dbQuery(String sql) Skapar databasfråga med hela SQL-strängen som inparameter. insertRow(String tbl, String value)

Lägger till en rad i databasen. Tbl anger vilken tabell som skall ändras, och value vilken information som skall skrivas. isRsEmpty() Returnerar true om databasens svar är tomt.

Nedan följer huvudklassens relation till de andra klasserna.

(22)

2.5.3 Databaskonstruktion

På följande sätt skapades de tre tabeller som används av programmet. Tabellerna är skapade

med hjälp av SQL*Plus, som är ett databashanteringsprogram i Oracles programpaket.

CREATE TABLE JourId ( id NUMBER(6) PRIMARY KEY, datum VARCHAR2(10), tid VARCHAR2(5), prodavd VARCHAR2(40), anmalare VARCHAR2(40), registrerare VARCHAR2(40) );

CREATE TABLE JourPersonal ( id NUMBER(6), anstnr NUMBER(5), namn VARCHAR2(30), org VARCHAR2(10), kallad VARCHAR2(17), ank VARCHAR2(17), klar VARCHAR2(17), tid VARCHAR2(5), lonetid VARCHAR2(5), biltaxi VARCHAR2(4) );

CREATE TABLE JourOrder ( id NUMBER(6), aonr NUMBER(6), objid VARCHAR2(20), beskrivning VARCHAR2(50), skapad VARCHAR2(25), arbetsbeskrivning VARCHAR2(150) );

Kolumnerna definieras genom att först skriva namn följt av vilken typ av värden som

kolumnen skall innehålla. Följande typer är använda i databasen.

• NUMBER(n) Heltalsvariabel

med

n teckens längd.

NUMBER(3) betyder t.ex. ett tal mellan 0 och 999.

• VARCHAR2(n)

En textsträng med n teckens längd.

VARCHAR2(5) betyder t.ex. att maximalt antal tecken i

strängen får vara fem.

• PRIMARY KEY

Egentligen ingen datatyp, utan mer en begränsning på hur

kolumnens innehåll får bete sig. Om kolumnen är märkt

PRIMARY KEY måste dess innehåll vara unikt och skiljt

från NULL

5

.

5

NULL är inte noll, även om det kan liknas med värdet noll. NULL är inget värde, det är ett tillstånd. Därför

(23)

2.5.4 Konvertering till Applet

Fram tills nu är klasserna och funktionerna testade i små applikationer. Detta för att det är

enklare att provköra en applikation. Det är nu dags att sammanfoga dessa i det som skall

komma att bli själva programmet. Till en början uppstod inga direkta problem. Allt fungerade

tills databasklassen skulle implementeras – då uppstod ett stort problem som ingen hade tänkt

på.

Precis som nämnts tidigare hindrar appletens säkerhetsrestriktioner anslutningen till

databasen. Programutvecklingen avstannade helt, och övergick till febril felsökning. Eftersom

denna säkerhetsaspekt hade undgått oss båda blev den första uppgiften att ta reda på vad som

orsakade felet. Det hade lika gärna kunnat vara ett konverteringsfel som något annat. Efter två

dagars informationssökning visade sig problemet vara just säkerheten. När väl felet var

identifierat hittades snabbt tre möjliga lösningar.

1. Signerad Applet

2. Oracle Connection Manager

3. Börja om, och utveckla en vanlig applikation istället

Eftersom val tre inte ens var att tänka på, lades all tid på att försöka lösa problemet genom

någon av de två första valen. Signerad applet utvärderades först. Det visade sig att detta sätt

helt tog bort säkerhetsrestriktionerna. Dessvärre visade det sig att det var totalt omöjligt att

göra en fungerade signerad applet. Varje version av javatolk och varje webbläsare hade sitt

eget sätt att signera appleten, och de var inte kompatibla med varandra. Ljuset släcktes när vi,

efter många lästa foruminlägg på Suns egen webbplats, plötsligt såg rubriken: ”SIGNED

APPLET – FORGET ABOUT IT!!!!!”. Det var alltså uppenbart att det var fler som hade

väldiga problem med detta.

Nu lades all krut på att få igång en fungerande Connection Manager. Gösta Nilsson, som är

systemansvarig för teknisk service, konsulterades. Han bidrog med installationsskivor för

Oracles Connection Manager, nu fattades bara konfigureringen. Eftersom ingen av oss hade

kunskaper om Oracles program blev första delmomentet att studera diverse litteratur i ämnet.

Efter många tester och misslyckade konfigurationer hittades tillslut en fungerande variant.

Problemet var nu äntligen löst, efter ganska precis en veckas intensivt arbete, och

utvecklingsarbetet kunde därmed fortskrida.

(24)

2.5.5 Design

Fig. 8: Gränssnitt 1 (Startsidan)

Gränssnitt ett består av två tabeller. I den övre tabellen är det meningen att användaren skall

fylla i uppgifter om det nya jourtillfället, så som produktionsavdelning, vem som utfärdat

arbetsordern samt vem som registrerat den. All information lagras i comboboxar. Kontrollen

av inmatad data blir då obefintlig, och överblicken av de olika valen blir enklare.

Fig. 9: Gränssnitt 1 med exempel på en combobox.

Den andra tabellen är en översiktstabell, som listar alla jourtillfällen mellan två valbara

datum. Detta gör att det blir väldigt lätt för användaren att ha en bra översikt över vilka

jourtillfällen som skapats. När programmet startar visas det senaste dygnets jourtillfällen. Det

är möjligt att dubbelklicka på valfri rad i översiktstabellen för att visa det markerade

jourtillfället som en ny flik.

(25)

När användaren skapar ett nytt jourtillfälle, eller öppnar ett befintligt, visas gränssnitt två i en

egen flik. Fliken får sitt namn från jourtillfällets kreationsdatum och tid, samt vilken

produktionsavdelning som angetts. Om flera tillfällen är öppna samtidigt blir det, på detta sätt,

lättare att navigera till rätt flik.

Fig. 10: Gränssnitt 2

Gränssnitt två består av tre tabeller, och två knappar. Tabell ett innehåller samma information

som ges vid skapandet av ett jourtillfälle inklusive datum och tid. Denna tabell går inte att

redigera. Tabell två håller reda på vilken personal som blivit utkallad under det aktuella

jourtillfället. Användaren behöver bara skriva in anställningsnummer, resten av fälten fylls då

i automatiskt.

Fig. 11: Inmatning av anställningsnummer utan att trycka enter.

Fig. 12: Efter enterslag fylls de övriga fälten i automatiskt.

Anställningsnumret matchas mot IFS och rätt namn skrivs in i namn-kolumen. Samtidigt som

detta görs fylls även kallad, ankomst och klar med aktuellt datum och tid. Tid och lönetid

beräknas utifrån ankomst och klar, lönetiden underskrider aldrig tre timmar. Den sista

kolumnen visar bil som default, men kan ändras till taxi via en combobox. Ankomst och klar

skall sedan ändras när den utkallade anmäler sig i vakten och när arbetet är utfört. Detta kan

göras helt manuellt, men enklast genom att markera och dubbelklicka (eller trycka CTRL+T)

(26)

Tabell tre fungerar på samma sätt som föregående, men istället för anställningsnummer

skriver användaren in arbetsordernumret. Diverse information om arbetsordern hämtas från

IFS och visas i tabellen.

Fig. 13: Inmatning av arbetsordernummer utan att trycka enter.

Fig. 14: Efter enterslag fylls de övriga fälten i automatiskt.

För att datorn skall känna av när ett fält ändrats och därefter utföra önskade åtgärder behövs

en lyssnare, i ovanstående fall en TableChangeListener. Lyssnaren fungerar inte på alla

tabeller i programmet, utan behöver kopplas till de tabeller som den skall verka på.

TabledefautModel m = new TableDefaultModel(); JTable t = new JTable(m);

. .

t.addTableModelListener(this); //här koppas lyssnaren till tabellen t. .

. .

//Hit hoppar programmet när det sker en ändring i tabellen t. public void tableChanged(TableModelEvent e)

{

//här sker de åtgärder som skall utföras vid ändringen. }

I ovanstående fall behövs lyssnaren bara när något ändras i första kolumnen (kolumn 0). Om

något t.ex. ändras i kolumnen ”ankomst” kommer programmet att försöka hämta personaldata

igen, och ett fel uppstår. Därför har en begränsning lagts till som ser till att endast koden

utförs när kolumn 0 är markerad.

public void tableChanged(TableModelEvent e) {

int column = e.getColumn(); //hämtar markerad kolumn

if (column==0) //ser till att det är kolumn 0 som är markerad {

//här sker de åtgärder som skall utföras vid ändringen. }

(27)

2.5.6 Flikhantering

Användandet av fliksystem skapar vissa problem. Varje flik blir en egen arbetsyta med sina

egna komponenter, så som knappar och tabeller. När en ny flik skapas måste den alltså fyllas

med nya knappar och tabeller. Från början sparades tabellerna i en array och knapparna i en

annan array. Vid skapandet läggs då t.ex. knappen spara i position noll i array 1 och tabell ett

i array 2. I och med det har de samma position i arrayerna och det är lätt att hålla reda på vad

som hör ihop. Om ytterligare en ny flik skapas så sker samma process, men det lagras på

nästa position istället.

Fig. 15: Tabeller och knappar för flik 1 lagras i respektive array med samma index.

Problemet är att programmeraren måste bestämma hur många flikar som får skapas. Så länge

användaren inte överskrider det antalet är det inga problem. Skulle användaren däremot skapa

fler flikar än förutbestämt kommer det att uppstå ett fel. Programmet inte vet var den ska lagra

informationen.

Lösningen på problemet är att använda sig av en vektor. En vektor bygger på samma princip

som en array, men istället för att i förväg bestämma storleken, skapas en ny position allt

eftersom det behövs. Datorns arbetsminne begränsar nu hur många flikar som kan skapas. Det

betyder i stora drag att det inte finns någon begränsning, då flikarna inte tar upp så mycket

minne samt att arbetsminnet oftast är väldigt stort. Ett annat problem som uppkommer är att

det nu t.ex. kan finnas tio stycken spara-knappar i en vektor. Hur skall programmet veta

vilken knapp som är nedtryckt? Om knappen inte finns lagrad i en vektor, utan är ”ensam”,

används följande kod för att ta reda på om den blivit nedtryckt:

//Knapplyssnaren

public void actionPerformed(ActionEvent e) {

//Lägger "klickad" knapp i o Object o = e.getSource();

//Knappen Skapa Nytt if (o==gr1_btnSkapa) {

//Här sker det som skall utföras när man klickar på knappen! } }

Array 2 0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 10 Array 1 Flik 1

(28)

Det går tyvärr inte att göra på samma sätt när knappen ligger i en vektor. Den första lösningen

på problemet var att göra en for-sats som loopade igenom hela vektorn och jämförde alla

knappar. Detta fungerade, men kanske inte var den bästa lösningen. Eftersom flik-index hör

ihop med vektorernas index, borde det gå att ta hjälp av vilken flik som är aktiv för att veta

vilken knapp som tryckts ner. Flik-hanteraren har en medlemsfunktion som heter

getSelectedIndex(), funktionen returnerar den aktiva flikens positionsnummer. I och med att

den första fliken alltid är öppen (gränssnitt ett), så kommer alltid det första jourtillfället att få

flik-index ett. Därför subtraheras ett från getSelectedIndex() för att hamna på rätt position i

vektorerna

//Knapplyssnaren

public void actionPerformed(ActionEvent e) {

//Lägger "klickad" knapp i o Object o = e.getSource(); //Knappen Klar if (jtp.getSelectedIndex()-1>=0) if (o==gr2_btnKlar.get(jtp.getSelectedIndex()-1)) {

//Här sker det som skall utföras när man klickar på knappen! }

}

Varje gång en knapp trycks ner hoppar programmet till funktionen actionPerformed. Varje

knapp i funktionen motsvarar en if-sats, som synes i ovanstående kod. Eftersom den första

fliken har index 0 måste det finnas en kontroll att inte indexet blir -1 då användaren befinner

sig där. Om användaren t.ex. trycker på ”Öppna Jourtillfälle” kommer getSelectedIndex() att

returnera noll, eftersom första fliken är aktiv. Programmet kommer ändå att kontrollera alla

andra knappars if-satser i funktionen actionPerformed. Därför behövs en kontroll att inte

indexet blir negativt, vilket görs i den första if-satsen i koden ovan.

När användaren trycker på knappen klar så stängs fliken, men den är egentligen bara stängd

visuellt. I minnet ligger fortfarande alla komponenter som tillhör fliken kvar, därför måste

även flikens komponenter ”stängas”. Detta görs genom att frigöra de positioner i vektorerna

som inte längre behövs.

//Hämtar aktuellt position

int index = jtp.getSelectedIndex()-1; //Frigör minnesutrymme gr2_tblId.removeElementAt(index); . . .

Variabeln index är som tidigare nämnts den variabel som håller reda på vektorns position,

m.h.a. vilken flik som är vald. Medlemsfunktionen removeElementAt(n) raderar position n

från vektorn och frigör minnet.

(29)

2.5.7 Test och justeringar

Efter sju veckors programmering har en fungerande applet växt fram. Det är nu dags att

testköra och visa handledaren Rickard Klingberg appleten. Givetvis är inte programmet

perfekt från början, vissa detaljer behöver självklart finslipas. Efter testkörning gjordes

följande förbättringar:

Anst.nr. och AO.nr. får bara finnas en gång per jourtillfälle. Vid inmatning av

anställnings- och arbetsordernummer, skall det kontrolleras att samma nummer inte finns med

tidigare i listan. Detta löstes på följande sätt:

int r = pers.getSelRow()-1; if (r>=0) { String s = (String)pers.getCellValue(r+1,0); while (r>=0) { if (pers.getCellValue(r,0).equals(s)) {

//Om numret finns raderas den nya raden }

r--; }

}

Den inmatade radens nummer jämförs med alla ovanstående rader. Om numret hittas raderas

den senast inmatade raden. En dialogruta gör användaren uppmärksam på att numret redan

finns i listan.

Inga tomma rader mellan personal och arbetsorder. I och med att tabellerna innehåller

elva fasta rader, kommer det förr eller senare att uppstå problem, då användaren skriver på fel

rad. D.v.s. det finns en eller flera tomma rader mellan posterna. Dels blir tabellerna

svåröverskådliga, samt att det blir problem när data skall sparas till databasen.

Sparafunktionen avbryts nämligen när en tom rad påträffas.

//Ser till att det inte finns tomma rader mellan posterna public void emptyRowsBetween(JTableControl p,int fr) {

while (fr>=0 && p.getCellValue(fr,0)=="") { p.deleteRow(fr); p.addEmptyRow(1); fr--; } }

Funktionen söker efter tomma rader ovanför den nya inmatningen och avbryter när den träffar

på en cell som innehåller data. Varje tom rad som påträffas raderas och en ny rad läggs till sist

i listan, på så sätt flyttas den inmatade raden upp ett steg. Detta utförs tills det inte finns några

tomma rader kvar.

Infoga en extra rad. För att inte begränsa programmet finns det möjlighet att utöka antalet

rader i personal- och arbetsordertabellerna utöver de elva rader som redan finns. Med ett tryck

på insert utökas tabellen med en extra rad, detta kan givetvis upprepas önskat antal gånger.

(30)

Problem vid radering av rad. Från början var Personal- och arbetsordertabellerna kopplade

till en lyssnare, som triggar på alla ändringar. Detta gick bra så länge användaren skrev in

information på en befintlig rad, men om en rad togs bort eller lades till uppstod ett problem.

Det var inte meningen att lyssnaren skulle trigga vid dessa tillfällen. Lite efterforskning gav

oss tre händelser som utlöser lyssnaren – UPDATE, INSERT och DELETE. Därför

begränsades tabellyssnaren till att enbart lyssna på UPDATE-händelser. På så sätt undviks

problemet, eftersom att lägga till eller ta bort en rad inte är någon UPDATE-händelse.

//Körs om det sker en ändring i en tabellcell public void tableChanged(TableModelEvent e) {

if (e.getType() == TableModelEvent.UPDATE) {

//Här utförs allt som skall ske när en cell ändras }

}

Det skall inte gå att öppna tomma eller ”omarkerade” rader. Många funktioner kräver att

en cell skall vara markerad för att fungera. Det går tyvärr att komma åt dessa funktioner utan

att någon cell markerats. Om detta sker kommer programmet peka på en ogiltig minnesadress

och därefter krascha. För att undvika att hela programmet kraschar fångas dessa händelser upp

m.h.a. en try/catch sats.

try {

//Här utförs kod som kan orsaka t.ex. minnesfel. }

catch (Exception e) {

//Om det blir fel i try-satsen kommer det att fångas upp i //efterförljande catch som i sin tur kan visa en varningsruta,

//istället för att krascha hela programmet. }

På detta sätt löses många av de kritiska kodrader som finns i programmet. Ett annat sätt är att

se till att aldrig hamna i dessa situationer. I detta fall returnerar getSelRow() minus ett om

ingen rad är markerad, då går det också bra att göra på nedanstående sätt.

int sel = order.getSelRow(); if (sel!=-1)

{

//Utför ändringar på markerad rad. }

else {

//Felutskrift om ingen rad är markerad. }

(31)

3 Resultat

Vi har valt att endast behandla jourappleten i denna rapport, men vi har även utvecklat en

rapportapplet. Den är nästan identisk med jourappleten och den enda skillnaden är att det inte

går att skapa nya jourtillfällen i den. Rapportappleten är endast till för att det skall gå att söka

bland bokförda jourtillfällen.

3.1 Slutsatser

Vi lyckades kringgå appletens säkerhetsrestriktioner och öppna en socket mot en annan dator,

i detta fall en databas. Och därmed skapa en koppling mellan databaserna och appleten. Vi

använde också comboboxar istället för att använda vanlig inmatning vid skapandet av ett nytt

jourtillfälle, vilket gjorde att felkontrollen blev minimal. Flikar istället för fönster är att

föredra, eftersom hanteringen blir lättare och mer kontrollerat. Dessa är de mest väsentliga

slutsatserna vi kan dra angående programmet, men vi vill även poängtera strukturen och

arbetsgången.

Det hade varit bättre att arbeta med applets hela tiden, istället för som vi gjorde i början,

skriva små applikationer. Resultatet hade ändå blivit den samma, men vi hade kanske undvikt

en del problem istället.

Att börja med att utveckla de funktioner och klasser som skall användas, för att sedan bygga

ett programskal, visade sig vara ett bra arbetssätt. Arbetet blir mer strukturerat. Det blir även

lättare att gå vidare och bygga på programmets funktioner allt eftersom. Ett program skall inte

bara vara en fungerande enhet. Det skall även vara relativt lätt för någon annan att sätta sig in

i, och skriva egna modifieringar. Utan struktur och kommenteringar blir det annars tämligen

värdelöst på längre sikt.

3.2 Rekommendationer för fortsatt arbete

Jourappletens webbsida bör på något sätt lösenordsskyddas. Som det är nu kommer alla som

känner till adressen åt appleten, och kan lägga till egna jourtillfällen. Meningen är att endast

vakten skall ha access till denna sida. Detta löses enklast genom att lösenordsskydda

webbsidan på servern, vilket lätt kan åtgärdas av administratören.

Det pratas mycket om ergonomi i dagens samhälle. Under slutfasen av arbetet fick vi reda på

att allt fler på företaget klagar på krämpor i arm och handled – s.k. musarm. Vi kanske borde

tänkt på att programmet skall gå att styra enbart med tangentbordet om så önskas. I och för sig

tror vi att användaren avsätter högst fem till tio minuter i sträck framför programmet. Därför

kommer inte detta påverka användaren nämnvärt. Det är viktigare att användarens

datorrutiner ses över. En paus på 2 minuter varje timme, där användaren sträcker på sig och

mjukar upp leder, räcker för att undvika förslitningar.

(32)

4 Referenslista

4.1 Tryckta källor

Jan Skansholm och Studentlitteratur 1998, 2003 , Java Direkt med Swing (fjärde upplagan),

Lund, Studentlitteratur, ISBN 91-44-04254-X

Magnus Merkel, 1999, Tekniska Rapporter och Examensarbeten, Linköping, Linköpings

Universitet

4.2 Elektroniska källor

http://www.javaalmanac.com/

http://www.sun.com

(33)

5 Bilagor

5.1 Konfiguration av Oracle Connection Manager

5.1.1 cman.ora

#============================================================================== # Connection Manager config file

# cman.ora

#============================================================================== #

# cman's listening addresses #

cman = (ADDRESS_LIST=

(ADDRESS=(PROTOCOL=tcp)(HOST=webbserverns ip)(PORT=1630)) )

cman_admin = (ADDRESS=(PROTOCOL=tcp)(HOST=webbserverns ip)(PORT=1830)) #

# cman's configurable params #

# MAXIMUM_RELAYS defaults to 128 # LOG_LEVEL defaults to 0 # TRACING defaults to no

# TRACE_DIRECTORY defaults to .../network/trace # RELAY_STATISTICS defaults to no

# SHOW_TNS_INFO defaults to no # USE_ASYNC_CALL defaults to yes # AUTHENTICATION_LEVEL defaults to 0 # MAXIMUM_CONNECT_DATA defaults to 1024 # ANSWER_TIMEOUT defaults to 0 # MAX_FREELIST_BUFFERS defaults to 2048 # cman_profile = (parameter_list= (MAXIMUM_RELAYS=1024) (LOG_LEVEL=1) (TRACING=no) (RELAY_STATISTICS=yes) (SHOW_TNS_INFO=yes) (USE_ASYNC_CALL=yes) (AUTHENTICATION_LEVEL=0) (REMOTE_ADMIN=FALSE) )

5.1.2 tnsnames.ora

#Anslutning via Conection Manager till IFS CMAN_IFS.WORLD =

(DESCRIPTION = (ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = webbserverns ip)(PORT = 1630)) (ADDRESS = (PROTOCOL = TCP)(HOST = databasens ip)(PORT = 1521)) ) (SOURCE_ROUTE = yes) (CONNECT_DATA = (SERVICE_NAME = pumaprod) ) )

#Anslutning via Connection Manager till Jour-databasen CMAN_JOUR.WORLD =

(DESCRIPTION = (ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = webbserverns ip)(PORT = 1630)) (ADDRESS = (PROTOCOL = TCP)(HOST = databasens ip)(PORT = 1521)) ) (SOURCE_ROUTE = yes) (CONNECT_DATA = (SERVICE_NAME = utv_puma) ) )

(34)

5.1.3 Installationsanvisning i Windows

1. Installera Oracle Connection Manager på den server där appleten skall användas.

2. Skapa filerna cman.ora och tnsnames.ora och kopiera dem till

%ORACLEHOME%\network\ADMIN\.

3. Starta kommandotolken och skriv cmctl start. Detta kommando startar managern som en

process i operativsystemet.

4. Med kommadot tnsping <anslutning> kan anslutningarna i tnsnames.ora kontrolleras.

Om de är rätt konfigurerade kommer respektive databas att svara.

Kommandon som kan vara bra att känna till:

cmctl status visar statusen på connection managern.

cmctl shutdown avslutar connection managern.

cmctl close_relay all stänger alla aktiva anslutningar, men lämnar managern igång.

5.2 Installationsanvisning för applet

5.2.1 Färdigställande av applet

Efter kompilering av koden skall följande punkter utföras för att programmet skall fungera i

en webbläsare. Alla kommandon skrivs i kommandotolken. För att kommandona skall

fungera i alla kataloger på hårddisken, kan java-katalogens sökväg behöva läggas till i

systemet. Skriv path %path%;<sökväg för java> för att göra detta.

1. Byt till katalogen där dina klassfiler är sparade.

2. Döp om huvudfilen (den fil som appleten körs ifrån) I vårt fall blir jourapplet.class

omdöpt till jourapplet.buf.

3. Skriv jar cf paket.jar *.class, där paket.jar kan döpas till valfritt namn. Alla klassfiler

utom huvudklassen packas nu ihop i denna .jar-fil.

4. Döp nu om jourapplet.buf till jourapplet.class igen.

5. Kopiera nls_charset12.jar och classes12.jar från java-katalogen till katalogen där dina

klassfiler är sparade. Dessa behövs för att kopplingen till databasen skall fungera.

6. Skapa en html-sida i valfritt program, t.ex. anteckningar. Se exempel som följer.

<html> <head>

<title>Bravikens Joursystem</title> </head>

<body>

<center><applet code="JourApplet.class" archive="paket.jar, nls_charset12.jar, classes12.jar" width="900" height="600"></applet></center>

</body> </html>

7. Spara filen som index.html och testkör appleten genom att dubbelklicka på filen.

8. Om allt fungerar skall nu appleten köras i vald webbläsare.

References

Related documents

FAR har erbjudits tillfälle att lämna synpunkter över Finansdepartementets utkast till lagrådsremiss Vissa ändringar i skattelagstiftningen till följd av

Motsvarande föreslås gälla i det fall ett undantag från begränsning av rätten att utnyttja kvarstående negativt räntenetto vid ägarförändringar eller vid fusion eller

Remissvar avseende utkast till lagrådsremiss Vissa ändringar i skattelagstiftningen till följd av resolutionsregelverket. Fondbolagens förening har beretts möjlighet att

Föreningen Svenskt Näringsliv har beretts tillfälle att avge yttrande över angivna utkast till lagrådsremiss och ansluter sig till vad Näringslivets Skattedelegation anfört i

Juridiska fakultetsstyrelsen, som anmodats att yttra sig över rubricerat betänkande, får härmed avge följande yttrande, som utarbetats av professor Mats Tjernberg.

Regelrådet saknar möjlighet att behandla ärendet inom den angivna svarstiden och avstår därför från att yttra sig i detta ärende.. Christian Pousette

Vid den slutliga handläggningen har också följande deltagit: överdirektören Fredrik Rosengren, rättschefen Gunilla Hedwall, enhetschefen Tomas Algotsson och sektionschefen

De skattemässiga följderna av ett resolutionsärende är dock komplexa och svåra att överblicka, särskilt utan erfarenhet från tidigare tillämpning. Mot den bakgrunden har