Programmeren in Java

advertisement
Programmeren in Java
Een stoomcursus door Edgar de Graaf, november 2006
Deze tekst geeft een zeer korte inleiding in de programmeertaal Java, uitgaande van
kennis van de taal C++. Daarnaast bestudere men de sheets van het college. In de tekst
hieronder staan enkele programmeeropgaven, gemarkeerd met &. Zie verder:
http://www.liacs.nl/home/kosters/pm/java.pdf (de sheets)
http://www.liacs.nl/home/kosters/pm/javatekst.doc (deze file)
De Onderdelen 1. Terminal uitvoer en compilatie. Hiermee wordt de werking van de Java compiler
getoond. Verder laten wij zien hoe schermuitvoer gaat: dit verschilt van C++.
2. Java en bestanden. Bestanden inlezen gaat anders in Java. Bij dit onderdeel laten
wij zien hoe je met Streams en Readers kunt omgaan. Ook Exceptions zullen kort
aan bod komen. Java is volledig object­georiënteerd, en daarom zullen wij hier
ook objecten behandelen.
3. Graphical User Interfaces. Objecten maken het bouwen van een grafische
interface (GUI) eenvoudiger. In dit onderdeel zullen wij een Applet bouwen.
Terminal uitvoer en compilatie
Eén van de sterke punten van de programmeertaal Java is de platform­onafhankelijkheid,
die men bereikt door broncode om te zetten naar bytecode. Deze bytecode ligt tussen
machinecode en broncode in. Bytecode is verschillend van machinecode omdat het
onafhankelijk is van het platform en het is verschillend van broncode omdat het een
binair bestand is, geoptimaliseerd voor de interpreter. De bytecode­interpreter noemen
wij de Java Virtual Machine (JVM).
Java kent verschillende versies, lopend van de oude versie Java 1.0 tot Java 1.5 op het
moment van schrijven van dit document. Deze versies verschillen soms sterk van elkaar,
vooral tussen versie 1.0 en 1.1 en tussen versie 1.1 en 1.2 (vanaf 1.2 heet het Java 2). Men
kan de Java compiler gratis downloaden van de Java website: http://java.sun.com
Sun (de maker van Java) stelt verschillende technologieën beschikbaar die allemaal Java
in hun naam hebben. De laatste Java­compiler noemt men J2SE (Java 2 Standard
Edition). Verder stelt men de JRE (Java Runtime Environment) en de SDK (Software
Development Kit) beschikbaar. Deze laatste gebruiken wij. Java staat al geïnstalleerd op
de meeste systemen in het Snellius, het installeren is alleen nodig voor thuis. Test welke
versie het universitair systeem beschikbaar stelt. Open een (Linux/UNIX) terminal en
gebruik hiertoe het volgende commando:
java -version
Het java commando roept de Java­interpreter aan. Hiermee kun je straks jouw Java
bytecode uitvoeren. Het commando javac roept de Java­compiler aan waarmee de
bytecode gemaakt wordt, mits je geen fouten maakt uiteraard. Het volgende programma
bevat een veel voorkomende fout. Maak een directory en maak in deze directory een
bestand genaamd Main.java. Neem de code met de fout vervolgens over (copy/paste):
import java.io.*;
public class Main {
public Main(String naam){
System.out.println("Hello smart student " + naam)
int moeilijk = 1 + 1;
System.out.println("1 + 1 = " + moeilijk);
}//Main
public static void main(String args[]) throws IOException
{
BufferedReader input =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("Please type your name: ");
new Main(input.readLine());
}//main
}//class Main
Compileer de code met het volgende commando:
javac *.java
Java­programma’s bestaan vaak uit verschillende classes en elke class zit doorgaans in
een apart .java bestand. Met bovenstaand commando worden ze allemaal
gecompileerd. Merk op: het .java bestand moet dezelfde naam hebben als de class die
erin zit; let hierbij ook op hoofdletters.
De compiler zal je vervolgens vertellen dat achter System.out.println("Hello
smart student" + naam) een ; nodig is. Verbeter deze fout en compileer
opnieuw. De compiler zal Main.class maken; dit is de bytecode die je kunt
uitproberen door het volgende commando:
java Main
Een aantal verschillen met C++ zullen meteen duidelijk zijn:
• De main­functie zit in de Main class. Deze class mag elke andere naam hebben,
de main functie moet er ongeveer zo uitzien. Executie begint bij deze main.
• Voor uitvoer naar het scherm gebruikt men System.out.println voor een zin met
een regelovergang erbij, en System.out.print voor idem zonder.
• Invoer gaat via System.in en twee Readers, hierover later meer. • De include­bibliotheek heet hier import. De package naam java.io kun je
eenvoudig opzoeken in de Java API documenten die zijn te downloaden op de
Java website.
• Java heeft alle informatie over een class in een bestand, het kent geen header
bestanden.
• Voor elke functie wordt aangeven of deze public, private of protected is: buiten de
package beschikbaar, alleen binnen de class of alleen binnen de package. Een
package is een verzameling van bij elkaar horende classes.
• Het declareren van een object betekent niet dat automatisch de constructor wordt
aangeroepen.
• Een object wordt pas gemaakt bij het ‘new’­commando dat je alleen op de
aangeven manieren kunt maken.
• Java kent geen call­by­reference of pointers (geen delete's, wel new's). Verder
werkt men vaak met String, in principe niet met char arrays. String is een object
en daarom schrijven wij het met een hoofdletter. Echter, int is geen object en wij
schrijven dat dan ook met een kleine letter.
Opgave &
1. Schrijf een Hello World programma, compileer en run het. Tip: kopieer steeds
benodigde Java­code uit de elektronische versie van dit document!
2. Schrijf een Java­programma dat aan de gebruiker twee getallen vraagt, en hun product
afdrukt op het beeldscherm.
3. [Thuis] Neem het gedeelte van de eerste C++­programmeeropgave dat bij gegeven
datum de bijbehorende dag bepaalt, en zet dit om in Java.
Java en bestanden
In het vorige onderdeel had je al gezien dat het afhandelen van bestanden heel anders
verloopt in Java. Alle bestandsafhandeling wordt gedaan door de (objecten van) classes
uit het java.io package. Zoek uit welke classes in deze package zitten door gebruik te
maken van de API documentatie te vinden op de volgende website:
http://java.sun.com/j2se/1.5.0/docs/api/
De class Reader is een abstract class. Dit wil zeggen dat bepaalde onderdelen van deze
class (blauwdruk voor een object) nog niet zijn geïmplementeerd. Deze implementatie zal
gedaan worden in zijn subclass en van een abstract class kun je dan ook geen object
maken. Zoek in de documentatie van java.io de Reader class, en noteer wat Readers doen
volgens deze documentatie. Een voorbeeld van zulke implementatie’s zijn de BufferedReader en de FileReader. Zoek
ook op wat beide doen en noteer dit in eigen woorden. Objecten van deze twee classes zal
je vaak gebruiken voor het inlezen van bestanden. Hun verschillende functionaliteit wordt
gecombineerd zoals bij het voorbeeld in het vorige onderdeel (het ene object als
parameter voor de constructor van het andere object). Zoals je kunt zien in dat voorbeeld,
objecten worden gemaakt door gebruik te maken van het commando new. Een class moet je zien als een blauwdruk, bijvoorbeeld een class Mens zal omschrijven
wat er gebeurt als een mens zijn armspier spant, een voorbeeld van een object van de
class Mens ben jij. Mens is weer een subclass van de abstracte class Organisme. Deze is
abstract omdat nog moet worden aangeven hoe het organisme ademt en zich
voortbeweegt. Bij de Reader zal dit betekenen dat het bekend is dat een Reader karakters
leest, maar hoe hij dat doet en uit welke bron wordt gespecificeerd in bijvoorbeeld de
BufferedReader.
De Java documentatie geeft bij readLine van BufferedReader aan ‘throws IOException’.
Het gebruik van Exceptions is min of meer verplicht in Java. Deze Exceptions handelen
fouten af die niet bij compilatie optreden, maar tijdens het runnen. In het voorbeeld van
het eerste onderdeel werd deze Exception gewoon ‘doodgegooid’. Dit is geen mooie
afhandeling van Exceptions, verander dit:
import java.io.*;
public class Main {
public Main(String naam){
System.out.println("Hello smart student " + naam);
int moeilijk = 1 + 1;
System.out.println("1 + 1 = " + moeilijk);
}//Main
public static void main(String args[]){
try {
BufferedReader input =
new BufferedReader(new FileReader("mijnbest.txt"));
System.out.print("Please type your name: ");
new Main(input.readLine());
input.close();
} catch(IOException ex){
System.out.println("Inleesfout");
ex.printStackTrace();
}//catch
}//main
}//class Main
Compileer dit programma en voer het uit zonder het bijhorende bestand
mijnbest.txt te maken, en kijk wat er gebeurd. De functie (method in Java)
printStackTrace van het IOException object drukt de details van de fout af naar het
scherm. Deze method gebruik je eigenlijk alleen tijdens debugging. De try­catch
constructie zorgt er voor dat Exceptions worden afgevangen als zij in een method
optreden. Opgave &
Maak nu zelf een class die de eerste 3 letters van een bestand inleest en afdrukt op het
beeldscherm.
In het package java.io kun je ook nog InputStreams vinden. Deze groep van classes zorgt
voor al het inlezen waar je met ingewikkelder zaken werkt in plaats van met karakters.
Een voorbeeld is de ObjectInputStream, deze leest complete objecten in die zijn
weggeschreven met de ObjectOutputStream. OutputStreams handelen alles af wat met het
schrijven van bytes te maken heeft. Writers daarentegen schrijven karakters en strings
naar bestanden. Opgave &
Maak een programma dat gebruik maakt van een PrintWriter en een FileWriter om een
String naar een bestand te schrijven. Let op: je kunt deze string in één keer naar het
bestand laten schrijven, dus het hoeft niet karakter voor karakter.
Graphical User Interfaces
Het is vrij eenvoudig om met Java een grafische interface te maken. Dit komt onder
andere door het object georiënteerde karakter. Het is mogelijk een grafische interface te
maken die werkt via Internet, een Applet geheten, en/of een interface die buiten Internet
om is uit te voeren, een Frame geheten. Wij zullen een Applet bouwen die via een knop
een Frame opent met een menu.
Eerst maken wij een Applet en zijn bijhorende HTML bestand:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.*;
public class MyApplet extends JApplet {
public void init(){
}//init
}//class MyApplet
<HTML>
<HEAD>
<TITLE>Een eerste applet</TITLE>
</HEAD>
<BODY>
<APPLET CODE="MyApplet.class" WIDTH=400 HEIGHT=200>
<PARAM NAME="buttonName" VALUE="Klik hier">
</APPLET>
</BODY>
</HTML>
Compileer eerst de Applet. Als je nu de HTML­pagina opent gebeurt er niets: je ziet
alleen een grijs vierkant. Het kan overigens ook zonder browser: gebruik dan het
commando appletviewer.
We voegen een Button toe; deze button komt uit de Swing package. De AWT package
(Abstract Windows Toolkit) bevat de oude grafische elementen zoals Button, en Swing
bevat de nieuwe zoals JButton. Voeg de button toe binnen de init method:
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
myButton = new JButton(getParameter("buttonName"));
myButton.setBounds(10,10,100,50);
myButton.setToolTipText("Aardigheidje ..");
contentPane.add(myButton);
Voeg nu nog een button object toe aan de class, nog net buiten de init method:
private JButton myButton;
Nu kan je de Applet weer compileren en uitvoeren (door de HTML pagina te openen). Bij
sommige browsers is het nodig om alle windows eerst te sluiten, anders blijft de oude
Applet staan.
De contentPane is het blad van de Applet waaraan je de componenten, zoals de JButton,
toevoegt. Normaal gesproken werk je met layout managers, maar deze zullen wij niet
behandelen. Vervolgens maken wij de button, stellen zijn positie en omvang in en voegen
hem toe aan het blad van de Applet.
De button heeft nu nog geen functionaliteit behalve het oplichten als je er op drukt. Java
is event­driven wat wil zeggen dat het drukken op een button een event genereert dat wij
af moeten vangen en af moeten handelen. Voeg eerst achter extends JApplet (voor de
accolade) het volgende toe:
implements ActionListener
ActionListener is een interface die je verplicht bepaalde methodes te implementeren, in
dit geval:
public void actionPerformed(ActionEvent evt){
Object source = evt.getSource();
if (source == myButton){
myButton.setText("Test");
}//if
}//actionPerformed
Voeg deze toe aan de MyApplet class, en compileer en bekijk het resultaat.
Nu moet je de events van de button nog koppelen met de ActionListener (de MyApplet
class). Voeg het volgende toe onder de setBounds in de init method:
myButton.addActionListener(this);
Het zou nu aardig moeten werken.
En hoe lees je tekst in uit een “textbox”? Hier staan de benodigde elementen:
...
private JTextField myText;
...
myText = new JTextField(15);
myText.setText("Uw getal aub");
myText.addActionListener(this);
contentPane.add(myText);
...
else if (source == myText){
String tekst = myText.getText();
int i = Integer.parseInt(tekst);
JOptionPane.showMessageDialog(null,"Kwadraat: "+(i*i));
}//if
...
Opgave &
bestudeer onderstaand programma. Ter oefening kun je het zelf mogelijk maken dat de
title van de Frame verandert als je item1 selecteert. Maak hiervoor gebruik van de
ActionListener.
Opgave &
Tot slot: maak een GUI voor de datum­opgave. Voor liefhebbers met een Jslider :­)
Wil je het eventueel nog mooier maken, fabriceer dan een aparte class MyFrame in een
apart bestand genaamd MyFrame.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyFrame extends JFrame {
public MyFrame(){
setTitle("Mijn Eerste JFrame Object");
setBounds(100,100,300,200);
JMenu eenMenu = new JMenu("Menu 1");
JMenu eenMenu2 = new JMenu("Menu 2");
item1 = new JMenuItem("Item1");
item2 = new JMenuItem("Item2");
item3 = new JMenuItem("Item3");
eenMenu.add(item1);
eenMenu.add(item2);
eenMenu2.add(item3);
JMenuBar menuBar = new JMenuBar();
menuBar.add(eenMenu);
menuBar.add(eenMenu2);
setJMenuBar(menuBar);
setVisible(true);
}//MyFrame
JMenuItem item1;
JMenuItem item2;
JMenuItem item3;
}//class MyFrame
Vervolgens moet je nog in de actionPerformed method van MyApplet de regel met
setText vervangen met het volgende:
new MyFrame();
Download