Videregående programmering i Java

Dag 7 - Swing og MVC

Grafiske komponenter (opsamling)

Overblik over Swing-komponenterne

Evaluering

Swing: MVC, Datamodeller, JTable, evt. JTree

Evt.: Swing: Præsentations- og kontroldel

Læsning: VP 6

Dette materiale er under Åben Dokumentlicens, se http://www.sslug.dk/linuxbog/licens.html

Swing-demo

Prøv til øvelserne: Demo i jdk1.4/demo/jfc/SwingSet2/SwingSet2.jar

Model-View-Controller

Muligheder for opdatering af præsentation:

A - Præsentationer undersøger modellen

B - Kontroldel underretter præsentationer

C - Modellen underretter præsentationer

Diskussion:

Genbrug af kode?

Flere præsentationer af samme data?

Hvornår skal præsentation opdatere skærm?

C - Model underretter præsentation

Eksempel:

Swing-komponenter og MVC

Datamodellen er skilt ud fra komponenten

Programmøren kan selv bestemme hvilket objekt der skal være datamodel

Ved at:

implementere interface, f.eks. TableModel

arve fra klasse med basisfunktioner (AbstractTableModel)

arve fra standardimplementation (DefaultTableModel)

bruge standardimpl (new DefaultTableModel(new String[10][50]))

Swing og MVC

Alle Swing-komponenter har deres 'datamodel' skilt ud i et separat objekt

Hvilken type model (klasse) der anvendes afhænger af komponenten

I JTextField, JTextArea og de andre tekstredigeringsfelter er datamodellen et objekt af typen Document, og læses hhv. sættes med metoderne getDocument() og setDocument(). Har man f.eks. to tekstfelter...

JTextField jTextField1 = new JTextField();

JTextField jTextField2 = new JTextField();

kan man få dem til at redigere i den samme tekst ved at sætte den ene til at bruge den andens datamodel:

Document datamodel = jTextField1.getDocument();

jTextField2.setDocument( datamodel );

Øvelse: Lav program med to tekstfelter, der deler samme Document-objekt.

Datamodellen i JTable

Designmønstret Adapter

Eksempel: Få data (en liste af Kunde-objekter) til at passe ind i en JTables forventning om et TableModel-objekt

import java.util.*;

import javax.swing.table.*;

public class KundelisteTableModelAdapter extends AbstractTableModel

{

private List liste;

public KundelisteTableModelAdapter(List liste1) { liste = liste1; }

public int getRowCount() { return liste.size(); }

public int getColumnCount() { return 2; } // navn og kredit

public String getColumnName(int kol)

{

return kol==0 ? "Navn" : "Kredit";

}

public Object getValueAt(int række, int kol)

{

Kunde k = (Kunde) liste.get(række);

return kol==0 ? k.navn : ""+k.kredit;

}

}

Præsentation i JTable

import javax.swing.*;

import javax.swing.table.*;

import java.awt.*;

public class Talpraesentation extends DefaultTableCellRenderer

{

public void setValue(Object værdi)

{

if (værdi instanceof Double) {

if (((Double) værdi).doubleValue()<0) setForeground(Color.red);

else setForeground(Color.blue);

}

else setForeground(Color.black);

setText(værdi.toString());

}

}

public class Farvepraesentation implements TableCellRenderer

{

JLabel jLabel = new JLabel(); // genbrug den samme komponent

public Component getTableCellRendererComponent(JTable tabel, Object værdi,

boolean erValgt, boolean harFokus, int række, int kolonne)

{

if (værdi instanceof Color) // er værdien af type Double?

{

Color f = (Color) værdi;

jLabel.setBackground(f); // hele baggrunden viser farven

jLabel.setForeground(f.darker()); // tekstfarven er lidt mørkere

jLabel.setOpaque(true); // uigennemsigtig så baggrunden kan ses

jLabel.setText("farve"); // vis bare en eller anden tekst

} else {

jLabel.setBackground(Color.white); // er objektet ikke en farve, så vis

jLabel.setForeground(Color.black); // det som toString() giver

jLabel.setText(værdi.toString());

}

return jLabel; // returnér komponenten der skal vises

}

}

Datamodellen i JTree

Datamodellen i JTree

Videregående programmering i Java

Præsentatoner fra kurset

2004-08-30T12:23:21