© 1999-2011, Flemming Koch Jensen
Alle rettigheder forbeholdt
Tabeller
Vejledende løsninger

 

 

1 Først er der framen, der har Viewet: Instansen af JTable:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class PlanTabelFrame extends JFrame {

  public PlanTabelFrame( String title ) {
    super( title );
    
    PlanTabelModel tableModel = new PlanTabelModel();

    JTable tableView = new JTable( tableModel );
    
    // Renderer til centreret tekst
    tableView.getColumn( tableModel.getColumnName( 0 ) )
      .setCellRenderer( new CentreretTextRenderer() );
    
    for ( int col=2; col<tableModel.getColumnCount(); col++ )
      tableView.getColumn( tableModel.getColumnName( col ) )
        .setCellRenderer( new CentreretTextRenderer() );
    
    // plads til stationsnavn
    tableView.getColumn( tableModel.getColumnName( 1 ) )
      .setPreferredWidth( 170 );
    
    JScrollPane pane = new JScrollPane( tableView );

    getContentPane().add( pane, BorderLayout.CENTER );
    
    setDefaultCloseOperation( EXIT_ON_CLOSE );
    setSize( 500, 100 );
    setVisible( true );
  }
}
Vi placerer som (næsten) altid tabellen i en JScrollPane, så vi kan få kolonne-navne.

Vi sætter vores renderer for hver af kolonnerne, og laver lidt ekstra plads til stationsnavnet (Bemærk at de andre kolonners bredde formindskes for at skabe den fornødne plads til den bredere kolonne).

 

Vores renderer til centrering af tekst:
import javax.swing.table.*;

public class CentreretTextRenderer extends DefaultTableCellRenderer {
  
  public CentreretTextRenderer() {
    setHorizontalAlignment( CENTER );
  }
  
  public void setValue( Object value ) {
    setText( value.toString() );
  }
}

 

Dernæst er der Modellen, der er kernen i opgaven:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class PlanTabelModel extends AbstractTableModel {
  
  private String[] station = 
    { "Herning Banegård", "Hammerum", "Ikast" };
  
  private int[] zone = { 10, 10, 15 };
  
  private String[][] tider = {
      { "05:02", "05:09", "05:15" },
      { "05:39", "05:50", "06:00" },
      { "05:40", "",      "05:50" },
      { "06:00", "06:08", "06:20" },
      { "06:05", "06:15", ""      } };
  
  private String[] rute =
    { "Tog", "77", "Tog", "116", "19" };
  
  public String getColumnName( int col ) {
    if ( col == 0 )
      return "Zone";
    else if ( col == 1 )
      return "Station";
    else
      return rute[col-2];
  }
  
  public int getColumnCount() {
    return 7;
  }

  public int getRowCount() {
    return zone.length;
  }

  public Object getValueAt( int row, int col ) {
    if ( col == 0 )
      return new Integer( zone[row] );
    else if ( col == 1 )
      return station[row];
    else
      return tider[col-2][row];
  }
}

 

Endelig er der blot at lave en instans af framen:
public class Main {
              
  public static void main( String[] argv ) {
    new PlanTabelFrame( "Køreplan: Herning-Hammerum-Ikast" );
  }
}
Figur 1:
Frame med køreplan

Man bemærker, at renderen ikke virker på "Tog"-kolonnen mellem 77 og 116. Det skyldes, at vi kun kan få fat i kolonner "by name". Da der er to "tog"-kolonner vil vi altid få fat i den første og aldrig den anden. Vores program sætter derfor renderen to gange for den første kolonne og aldrig for den anden. Jeg er ikke bekendt med hvordan man løser dette problem!

 

2 Først er der framen:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class VejrTabelFrame extends JFrame {

  public VejrTabelFrame( String title ) {
    super( title );
    
    VejrTabelModel tableModel = new VejrTabelModel();

    JTable tableView = new JTable( tableModel );
    
    // Farver
    Color docJavaSourceGreen = new Color( 152, 251, 152 );
    Color docJavaGulligt     = new Color( 255, 255, 200 );
    
    // Renderer til nat-temperaturerne
    DefaultTableCellRenderer natRender =
      new BackgroundColorCellRenderer( docJavaGulligt );
    natRender.setHorizontalAlignment( JLabel.RIGHT );  
      
    tableView.getColumn( "Nat" ).setCellRenderer( natRender );
    
    // Renderer til dag-temperaturerne
    DefaultTableCellRenderer dagRender =
      new DefaultTableCellRenderer();
    dagRender.setHorizontalAlignment( JLabel.RIGHT );
    
    tableView.getColumn( "Dag" ).setCellRenderer( dagRender );

    JScrollPane pane = new JScrollPane( tableView );

    getContentPane().add( pane, BorderLayout.CENTER );
    
    setDefaultCloseOperation( EXIT_ON_CLOSE );
    setSize( 500, 150 );
    setVisible( true );
  }
}

Her anvender vi en speciel renderer til nat-temperaturerne, mens dag-temperaturerne ordnes med en instans af DefaultTableCellRenderer, der indstilles mht. allignment.

 

Renderen til nat-temperaturerne er BackGroundColorCellRenderer:
import javax.swing.table.*;
import java.awt.*;

public class BackgroundColorCellRenderer extends DefaultTableCellRenderer {
  
  public BackgroundColorCellRenderer( Color c ) {
    setBackground( c );
  }
  
  public void setValue( Object value ) {
    setText( value.toString() );
  }
}

 

Modellen er givet ved klassen VejrTabelModel:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class VejrTabelModel extends AbstractTableModel {
  
  private String[] by = 
    { "Barcelona", "Beograd", "Bergen", "Berlin",
      "Bruxelles", "Bucarest", "Budapest" };
  
  private int[] dag = { 14,  2,  3,  4, 10,  1,  3 };
  private int[] nat = {  6, -1,  2,  0,  3, -1, -4 };
  
  private String[] beskrivelse = {
    "halvskyet", "overskyet", "overskyet", "skyet",
    "overskyet", "sne", "overskyet" };
  
  private String[] columnName =
    { "By", "Dag", "Nat", "Beskrivelse" };
  
  public String getColumnName( int col ) {
    return columnName[col];
  }
  
  public int getColumnCount() {
    return 4;
  }

  public int getRowCount() {
    return by.length;
  }

  public Object getValueAt( int row, int col ) {
    switch ( col ) {
      case 0: return by[row];
      case 1: return new Integer( dag[row] );
      case 2: return new Integer( nat[row] );
      case 3: return beskrivelse[row];
      default: return null;
    }
  }
}
Figur 2:
Frame med temperaturer

 

3 Vi har igen først framen:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class ValutaTabelFrame extends JFrame {

  public ValutaTabelFrame( String title ) {
    super( title );
    
    ValutaTabelModel tableModel = new ValutaTabelModel();

    JTable tableView = new JTable( tableModel );
    
    for ( int col=2; col<tableModel.getColumnCount(); col++ )
      tableView.getColumn( tableModel.getColumnName( col ) )
        .setCellEditor( new DefaultCellEditor( new JTextField() ) );
    
    JScrollPane pane = new JScrollPane( tableView );

    getContentPane().add( pane, BorderLayout.CENTER );
    
    setDefaultCloseOperation( EXIT_ON_CLOSE );
    setSize( 500, 300 );
    setVisible( true );
  }
}

for-løkken gennemløber de relevante kolonner og sætter editoren.

 

Modellen er givet ved klassen ValutaTabelModel:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class ValutaTabelModel extends AbstractTableModel {
  
  private String[] valuta = 
    { "US-dollars", "Euro", "Pund Sterling", "D-mark",
      "Svenske kroner", "Schweizerfranc", "Gylden", "Franske franc",
      "Japanske yen", "Finske mark", "Norske kroner", "Lire",
      "Pesetas", "Belgiske franc", "Irske punt", "Escudos",
      "Australske dls.", "New Zealand dls."
    };
  
  private String[] valutaKode = 
    { "USD", "EUR", "GBP", "DEM",
      "SEK", "CHF", "NLG", "FRF",
      "JPY", "FIM", "NOK", "ITL",
      "ESP", "BEF", "IEP", "PTE",
      "AUD", "NZD"
    };
  
  private double[] feb23 = {
      741.35, 744.69, 1192.27, 380.75,
      86.70, 462.51, 337.93, 113.53,
      6.6938, 125.25, 90.95, 0.3846,
      4.476, 18.460, 945.56, 3.714,
      460.79, 361.71
    };
    
  private double[] feb24 = {
      746.30, 744.66, 1195.47, 380.74,
      86.94, 462.38, 337.91, 113.52,
      6.7141, 125.24, 91.29, 0.3846,
      4.475, 18.460, 945.52, 3.714,
      462.12, 363.32
    };
  
  public String getColumnName( int col ) {
    switch ( col ) {
      case 0: return "Valuta";
      case 1: return "Kode";
      case 2: return "24. feb.";
      case 3: return "23. feb.";
      default: return null;
    }
  }
  
  public int getColumnCount() {
    return 4;
  }

  public int getRowCount() {
    return valuta.length;
  }
  
  public boolean isCellEditable( int row, int col ) {
    if ( col > 1 )
      return true;
    else
      return false;
  }
  
  public void setValueAt( Object value, int row, int col ) {
    if ( col > 1 ) {
      double kurs = Double.parseDouble( (String) value );
      
      if ( col == 2 )
        feb24[row] = kurs;
      else if ( col == 3 )
        feb23[row] = kurs;
    }
  }

  public Object getValueAt( int row, int col ) {
    switch ( col ) {
      case 0: return valuta[row];
      case 1: return valutaKode[row];
      case 2: return new Double( feb24[row] );
      case 3: return new Double( feb23[row] );
      default: return null;
    }
  }
}
Figur 3:
Frame med valutaer