# Kalender per JTable



## big-mike (31. Mai 2010)

Hallo,
ich möchte einen Kalender programmieren, der mir ein Jahr auf einem Blatt ausgibt und dabei die Felder zu einem links aus dem Datum (also die Tageszahl; der Erste eines Monats mit 1 usw.) bestehen und rechts der Wochentag (abgekürzt natürlich) steht. Wie könnte ich das realisieren? Ich bin leider nicht allzu erfahren mit grafischen Oberflächen, sprich ich habe 0 Erfahrung.
Ich versuche mich grad an JTable aber komme nicht wirklich weiter. Oder sollte ich das anderst lösen?

Mike


----------



## Ebenius (31. Mai 2010)

JTable ist schonmal der richtige Ansatz. Ich würde auch nichts anderes probieren. Wo hängst Du denn fest?

Ebenius


----------



## big-mike (31. Mai 2010)

was mir Probleme bereitet is sozusagen die "Füllung" der einzelnen Zellen mit Tag und Wochentag, ich könnte es zwar manuell machen aber das is ja nicht besonders elegant und dann hätte man nur ein jahr. 
Was ich mir nun überlegt hab ist, dass wenn man auf einen Tag klickt, die Tages, oder Wochenansicht aufgeht und da wüsst ich jetz auch nicht wie das zu realisieren wäre. Geht das überhaupt? Soviel ich jetz weiß kann ich in die Zelle eigentlich ja alles schreiben, oder?! also wäre das doch theoretisch möglich?

Mike


----------



## Ebenius (31. Mai 2010)

Also ich würde mir ein Tabellenmodell (TableModel) schreiben das einen Calendar kennt und aus diesem die Daten holt. Als Arbeitsgrundlage; so kann man anfangen: 
	
	
	
	





```
/* (@)YearCalendarTableModel.java */

/* Copyright 2010 Sebastian Haufe

 * Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       [url]http://www.apache.org/licenses/LICENSE-2.0[/url]

 * Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

package com.ebenius;

import java.util.Calendar;
import java.util.Date;

import javax.swing.table.AbstractTableModel;

/**
 * @version $Revision$ as of $Date$
 * @author Sebastian Haufe
 */
public class YearCalendarTableModel extends AbstractTableModel {

  /** Serial version UID */
  private static final long serialVersionUID = 1L;

  // -------------------------------------------------------------------------
  // Instance fields
  // -------------------------------------------------------------------------

  private Calendar calendar;

  // -------------------------------------------------------------------------
  // Constructors
  // -------------------------------------------------------------------------

  /** Creates a new {@code YearCalendarTableModel}. */
  public YearCalendarTableModel() {
    setCalendar(Calendar.getInstance());
  }

  // -------------------------------------------------------------------------
  // Bean getters and setters
  // -------------------------------------------------------------------------

  public void setCalendar(Calendar calendar) {
    this.calendar = (Calendar) calendar.clone();
    this.calendar.clear(Calendar.HOUR_OF_DAY);
    this.calendar.clear(Calendar.MINUTE);
    this.calendar.clear(Calendar.SECOND);
    this.calendar.clear(Calendar.MILLISECOND);
    fireTableStructureChanged();
  }

  public Calendar getCalendar() {
    return (Calendar) this.calendar.clone();
  }

  // -------------------------------------------------------------------------
  // Implementing TableModel
  // -------------------------------------------------------------------------

  @Override
  public Class<?> getColumnClass(int columnIndex) {
    return Date.class;
  }

  public int getColumnCount() {
    return calendar.getMaximum(Calendar.MONTH)
          - calendar.getMinimum(Calendar.MONTH)
          + 1;
  }

  public int getRowCount() {
    return calendar.getMaximum(Calendar.DAY_OF_MONTH)
          - calendar.getMinimum(Calendar.DAY_OF_MONTH)
          + 1;
  }

  public Object getValueAt(int rowIndex, int columnIndex) {
    calendar.set(Calendar.DAY_OF_MONTH, calendar
          .getMinimum(Calendar.DAY_OF_MONTH));
    calendar.set(Calendar.MONTH, calendar.getMinimum(Calendar.MONDAY)
          + columnIndex);
    final int thisMonthsMinDay =
          calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
    if (rowIndex > calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
          - thisMonthsMinDay) {
      return null;
    } else {
      calendar.set(Calendar.DAY_OF_MONTH, thisMonthsMinDay + rowIndex);
      return calendar.getTime();
    }
  }
}
```
Du könntest, um die Wochenansicht einzublenden, einen CellEditor bauen, der dann einen Dialog öffnet. Oder hab ich Dich falsch verstanden?

Ebenius


----------



## big-mike (31. Mai 2010)

ne genau das hab gemeint. Jetzt muss ich schaun wie ich die ganzen Informationen umsetze, bin wie gesagt gar nicht erfahren, was GUI Programmierung angeht. Vielen Dank für die Hilfe. Bei weiteren Problemen weiß ich, an wen ich mich wenden kann =)

Mike


----------



## big-mike (31. Mai 2010)

eine weitere Frage:
Ich hab versucht das Modell zu verwenden und meiner Vorstellung anzupassen, was mir nicht ganz gelungen ist. Kann ich eine Zelle links mit Datum und rechts mit der Abkürzung eines Wochentages beschriften? Wenn nicht würd ich einfach eine Spalte links machen mit 1.-31. und in den Zellen selbst die Wochentage aber das hab ich auch noch nicht hingekriegt. Wie krieg ich es hin, dass mir statt dem Datum (z.Bsp. "23.05.2010") der Wochentag in die Zellen geschrieben wird? Kann ich dann auch die Schriftart bzw. Größe verändern?

Mike


----------



## Ebenius (31. Mai 2010)

Über einen entsprechenden CellRenderer bekommt man das hin. Dazu musst Du das Modell überhaupt nicht ändern, sondern die Date-Objekte drin lassen. So kann das aussehen: 
	
	
	
	





```
table.setDefaultRenderer(Date.class, new DefaultTableCellRenderer() {

  /** Serial version UID */
  private static final long serialVersionUID = 1L;

  final DateFormat df =
        new SimpleDateFormat("'<html><table><tr><td align=\"left\">'"
              + "E"
              + "'</td><td align=\"right\">'"
              + "dd.MM."
              + "'</td></tr></table></html>'");

  @Override
  protected void setValue(Object value) {
    super.setValue(value instanceof Date ? df.format(value) : null);
  }
});
```
Dieser Renderer ist natürlich ziemlich langsam, weil HTML pro Zelle anordnen schon seine Zeit braucht. Besser ist es, wenn Du einen Renderer nimmst, der auf einem JPanel mit zwei JLabels aufbaut; sowas in etwa: 
	
	
	
	





```
table.setDefaultRenderer(Date.class, new DefaultTableCellRenderer() {

  /** Serial version UID */
  private static final long serialVersionUID = 1L;

  final DateFormat weekDayFormat = new SimpleDateFormat("E");
  final DateFormat dateFormat = new SimpleDateFormat("dd.MM.");
  final JLabel weekDayLabel = new JLabel("", SwingConstants.LEADING);
  final JPanel container = new JPanel(new BorderLayout(2, 2)) {

    // some performance boost

    @Override
    public void revalidate() {}

    @Override
    public void repaint(long tm, int x, int y, int width, int height) {}

    @Override
    public void repaint(Rectangle r) {}

    @Override
    public void repaint() {}
  };

  {
    container.add(weekDayLabel, BorderLayout.LINE_START);
    container.add(this, BorderLayout.CENTER);
    this.setHorizontalAlignment(SwingConstants.TRAILING);
  }

  @Override
  public Component getTableCellRendererComponent(
        JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int row,
        int column) {
    super.getTableCellRendererComponent(table, value, isSelected,
          hasFocus, row, column);
    container.setBackground(getBackground());
    container.setOpaque(isOpaque());
    container.setBorder(getBorder());

    weekDayLabel.setForeground(getForeground());
    weekDayLabel.setBackground(getBackground());
    weekDayLabel.setFont(getFont());

    setBorder(null);

    return container;
  }

  @Override
  protected void setValue(Object value) {
    super.setValue(value instanceof Date
          ? dateFormat.format(value)
          : null);
    weekDayLabel.setText(value instanceof Date ? weekDayFormat
          .format(value) : null);
  }
});
```
Und hier noch das Sun Java Tutorial: How to Use Tables // Custom Renderers
Ebenius


----------



## big-mike (1. Jun 2010)

nochmals vielen Dank für die Hilfe, es sieht schonmal nicht schlecht aus =) . 
Wie kann ich einen CellEditor bauen der mir ein neues Fenster aufmacht wenn ich eine Zelle anklicke? Was ich dannach brauch kann ich mir vorstellen. Dann muss ja nur eine neue Tabelle erzeugt werden, die die Woche enthält und ich hab mir gedacht, ich mach links eine Spalte mit den Uhrzeiten, von 0-24 Uhr in 2 h Schritten. Nur leider komm ich gar nicht so weit. Hab im Internet nach CellEditor gesucht aber leider nichts (für mich) brauchbares gefunden. 

Mike


----------



## big-mike (1. Jun 2010)

Die Schriftart müsste man doch bei  "weekDayLabel.setFont(getFont());" ändern können?! Ist mir nämlich auch noch nicht gelungen.
und wie ändert man die Farbe der Schrift, bzw. macht sie fett gedruckt? 
Sonst wird die Jahresansicht nämlich unübersichtlich und weniger anschaulich.

Mike


----------



## big-mike (1. Jun 2010)

```
table.setDefaultRenderer(Date.class, new DefaultTableCellRenderer() {

 ....


    // some performance boost

    @Override
    public void revalidate() {}

    @Override
    public void repaint(long tm, int x, int y, int width, int height) {}

    @Override
    public void repaint(Rectangle r) {}

    @Override
    public void repaint() {}
  };
```

Ebenius[/QUOTE]

warum brauch ich hier Repaint auch für ein Rectangle?  Das macht für mich keinen Sinn

Mike


----------



## Ebenius (1. Jun 2010)

Das sind nur Performance-Optimierungen. Normale Komponenten machen in diesen Methoden einiges. CellRenderer-Komponenten brauchen die Funktionalität nicht, die Methoden werden aber trotzdem an einigen Stellen aufgerufen. Deswegen sind die Methoden leer überschreiben; weil leere Methoden nunmal schneller sind.

Ein CellEditor für Popups ist ebenfalls in dem Tutorial das ich oben verlinkt habe erklärt. Arbeite Dich da mal ein. 

Fettdruck geht über den Font, Schriftgröße, Schrägschrift ebenfalls: [c]blablaLabel.setFont(table.getFont().deriveFont(Font.BOLD | Font.ITALIC, 24f));[/c]. Die Schriftfarbe kommt aus der Vordergrund-Farbe des Labels [c]blablaLabel.setForeground(Color.GREEN);[/c]

Ebenius


----------



## big-mike (1. Jun 2010)

Eine Frage: Ich habe versucht, die Tabellenköpfe auch umzugestalten, indem ich statt Strings Labels übergebe. Die Getter Methode will aber unbedingt einen String. Ich habe auch versucht mit override die Methode aus dem AbstractTableModel "auszuschalten" aber das geht auch nicht. Leider kann man ja Strings nicht verändern und mir fällt keine andere Methode ein den Tabellenkopf zu bearbeiten.
Wie kann ich außerdem die Zahl eines Datums ändern. Leider funktioniert das ja nicht wie bei den Wochentagsabkürzungen.

Mike


----------



## Ebenius (2. Jun 2010)

big-mike hat gesagt.:


> Eine Frage: Ich habe versucht, die Tabellenköpfe auch umzugestalten, indem ich statt Strings Labels übergebe.


Auch dafür lautet die Antwort: Eigenen TableCellRenderer bauen. Den hängt man dann an den der Tabelle gehörenden JTableHeader. Im Renderer kannst Du auf die Tabelle und darüber auch wieder auf das Modell zugreifen. Man sollte dabei  immer den Standard-Renderer des TableHeaders das eigentliche Rendering übernehmen lassen, weil dieser zum jeweiligen LAF passt. So in etwa würde ich das also machen: 
	
	
	
	





```
final JTableHeader tableHeader = table.getTableHeader();
final TableCellRenderer actualHeaderRenderer =
      tableHeader.getDefaultRenderer();
tableHeader.setDefaultRenderer(new TableCellRenderer() {

  /** Serial version UID */
  private static final long serialVersionUID = 1L;

  final DateFormat monthFormat = new SimpleDateFormat("MMMM");

  public Component getTableCellRendererComponent(
        JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int row,
        int column) {
    /* get the first row's value for the header */
    final int modelColumn = table.convertColumnIndexToModel(column);
    value = table.getModel().getValueAt(0, modelColumn);
    value = monthFormat.format(value);

    /* let the default header renderer render our new value */
    return actualHeaderRenderer.getTableCellRendererComponent(table,
          value, isSelected, hasFocus, row, column);
  }
});
```



big-mike hat gesagt.:


> Wie kann ich außerdem die Zahl eines Datums ändern. Leider funktioniert das ja nicht wie bei den Wochentagsabkürzungen.


Dein Renderer von oben besteht aus einem Panel und *zwei* Labels. Das eine Label kennst Du schon und das andere Label ist die Renderer-Instanz selbst. Also einfach [c]this.setFont(…)[/c] und dergleichen im Renderer aufrufen, dann wird alles gut.

Ebenius


----------



## big-mike (4. Jun 2010)

langsam wird es peinlich, aber wie kann ich mit dem Renderer für die Tabellenköpfe die Schrift in den Tabellenköpfen verändern?
Ich nerv vermutlich schon, aber ich komme nicht darauf.

Mike


----------



## Ebenius (4. Jun 2010)

Ach das ist nicht peinlich. Schlägst Dich doch gut. Immerhin stellst Du nicht immer die gleiche Frage neu. 

Bezogen auf mein Beispiel oben: 
	
	
	
	





```
final JTableHeader tableHeader = table.getTableHeader();
final TableCellRenderer actualHeaderRenderer =
      tableHeader.getDefaultRenderer();
tableHeader.setDefaultRenderer(new TableCellRenderer() {
 
  /** Serial version UID */
  private static final long serialVersionUID = 1L;
 
  final DateFormat monthFormat = new SimpleDateFormat("MMMM");
 
  public Component getTableCellRendererComponent(
        JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int row,
        int column) {
    /* get the first row's value for the header */
    final int modelColumn = table.convertColumnIndexToModel(column);
    value = table.getModel().getValueAt(0, modelColumn);
    value = monthFormat.format(value);
 
    /* let the default header renderer render our new value */
    final Component rendererComponent = actualHeaderRenderer
            .getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    rendererComponent.setFont(myNewFont);

    return rendererComponent;
  }
});
```
Ebenius


----------



## big-mike (6. Jun 2010)

ich hab ein ziemlich großes Problem mit dem CellRenderer. Sobald der eingebaut ist, generiert das Programm nur den Kalender bis zum 28. des Monats und man kann nicht weiter runter scrollen. Ich weiß nicht woran das liegen kann.

Mike


----------



## big-mike (6. Jun 2010)

ich habe das Öffnen eines neuen Fensters nun anderst gelöst und es tut auch so weit, solang ich ein JTable mit dem YearCalendarTableModel aufmache:


```
//Öffnet neues Fenster bei Doppelklick
    
   table.addMouseListener(new MouseAdapter() {
    	   public void mouseClicked(MouseEvent e) {
    		       		 		   
    	      if (e.getClickCount() == 2) {
    	         JTable target = (JTable)e.getSource();
    	         int row = target.getSelectedRow();
    	         int column = target.getSelectedColumn();
    	         Date value = (Date) target.getValueAt(row, column);
 	                	             	         
    	         JFrame newFrame = new JFrame("Wochenansicht");
    	         
   	         newFrame.setSize(new Dimension(1000, 650));
   	         newFrame.setVisible(true);
   	                    	        	          
   	         JTable table = new JTable(new WochenKalenderTableModel());
   	             
    	         table.setPreferredScrollableViewportSize(new Dimension(1000, 650));
    	         table.setRowHeight(31);
    	         table.setFillsViewportHeight(true);
    	          
    	         //Create the scroll pane and add the table to it.
    	         JScrollPane scrollPane = new JScrollPane(table);

    	         //Add the scroll pane to this panel.
    	         newFrame.add(scrollPane);
    	        }
    	   }
    	});
```

ich hab mich an meinem eigenen TableModel versucht und stoße nun auf Schwierigkeiten:


```
public class WochenKalenderTableModel extends AbstractTableModel{
	
		Object [][] rowData; 
	
		String Zeilen []= new String[]{"0:00","2:00","4:00","6:00","8:00","10:00","12:00","14:00",
					"16:00","18:00","20:00","22:00","24:00"};
	
		private Object[] columns = {
                                                //hier sollte dann stehen: value,value+1 oder sowas in der Art};
	
		
		public Class <?> getColumnClass(int row,int col) {
	        return getValueAt(row, col).getClass();
	    }
		

		public Object getColumnNames(int column){
			if(1<column&&column<7){
				return columns[column];
			}
			return "Uhr";
				
			}
			
		
		public int getRowCount() { return Zeilen.length; }
		public int getColumnCount() { return columns.length; }
		public Object getValueAt(int row, int col) {
		   	int i;
			for(i=1;i<13;i++){
				rowData[i][1]=Zeilen[i];
			}
	       return rowData[row][col];
		    }
		    
		public void setValueAt(Object value, int row, int col) {
		        rowData[row][col] = value;
		        fireTableCellUpdated(row, col);
             
		    }
}
```


Um die Köpfe zu füllen brauch ich ja den Wert aus der Zelle, die angeklickt wurde. Da ich aber das Model in eine andere Klasse gepackt hab, kann ich nicht darauf zugreifen und finde nicht heraus wie ich auf die Variable value nun kommen kann. Außerdem will ich die erste Spalte als Uhr mit Uhrzeiten nutzen und da weiß ich auch nicht ob mein Ansatz der richtige ist. 
Zu guter letzt wollt ich fragen, was mir die Methode, die eine Class zurückliefert bringt, ich sehe den Sinn dahinter nicht so ganz.

Mike


----------



## Ebenius (6. Jun 2010)

big-mike hat gesagt.:


> ich hab ein ziemlich großes Problem mit dem CellRenderer. Sobald der eingebaut ist, generiert das Programm nur den Kalender bis zum 28. des Monats und man kann nicht weiter runter scrollen. Ich weiß nicht woran das liegen kann.


Das kann ich leider überhaupt nicht nachvollziehen. :-(



big-mike hat gesagt.:


> [JAVA=5]
> String Zeilen []= new String[]{"0:00","2:00","4:00","6:00","8:00","10:00","12:00","14:00",
> "16:00","18:00","20:00","22:00","24:00"};[/code]


Alle variablen in Java beginnen mit einem kleinen 
	
	
	
	





```
buchStaben
```
.



big-mike hat gesagt.:


> [JAVA=12]
> public Class <?> getColumnClass(int row,int col) {
> return getValueAt(row, col).getClass();
> }[/code]


Die Methode heißt [c]getColumnClass(int column)[/c]. Du solltest vor alle überschriebenen [c]@Override[/c] schreiben; also: 
	
	
	
	





```
@Override
		public Class <?> getColumnClass(int column) {
	        return column == 0 ? Date.class : Object.class;
	    }
```
 


big-mike hat gesagt.:


> [JAVA=28]
> public Object getValueAt(int row, int col) {
> int i;
> for(i=1;i<13;i++){
> ...


_
Das solltest Du lieber im Konstruktor tun. Hier hat die Initialisierung Deiner Zelldaten nichts verloren.



big-mike hat gesagt.:



			Um die Köpfe zu füllen brauch ich ja den Wert aus der Zelle, die angeklickt wurde. Da ich aber das Model in eine andere Klasse gepackt hab, kann ich nicht darauf zugreifen und finde nicht heraus wie ich auf die Variable value nun kommen kann.
		
Zum Vergrößern anklicken....

Wieso baust Du nicht eine Methode in das Modell ein, rufst diese auf und übergibst dort die Daten die Tabellenmodell angezeigt werden sollen?



big-mike hat gesagt.:



			Außerdem will ich die erste Spalte als Uhr mit Uhrzeiten nutzen und da weiß ich auch nicht ob mein Ansatz der richtige ist.
		
Zum Vergrößern anklicken....

Ja. Dieser Ansatz ist da schon richtig. Allerdings würde ich auch hier eher [c]Date[/c] als Wert benutzen als String. So wie es das YearDingsdaModel auch macht.



big-mike hat gesagt.:



			Zu guter letzt wollt ich fragen, was mir die Methode, die eine Class zurückliefert bringt, ich sehe den Sinn dahinter nicht so ganz.
		
Zum Vergrößern anklicken....

Diese Methode sagt der Tabelle, welchen Wertetyp eine Tabellenspalte hat. Diesen Typ benutzt die Tabelle dann, um einen passenden Renderer und einen passenden Editor für die Zellen zu finden. Dafür gibt es dann JTable.setDefaultRenderer(Class, TableCellRenderer) und JTable.setDefaultEditor(Class, TableCellEditor).

Ebenius_


----------



## big-mike (6. Jun 2010)

Ich habe die Fehlerquelle identifiziert: ich habe, um Sonntage einzufärben eine if Verzweigung eingebaut:


```
if(weekDayLabel.getText().equals("Sonntag")){
    		  
    		  weekDayLabel.setForeground(Color.RED);
    	  };
```

woran kann der Fehler liegen. Ich finde ein Kalender sollte Sonntage rot gefärbt haben. 
Naja wenigstens weiß ich wo der Fehler liegt. Gibt es eine andere Möglichkeit, die Sonntage einzufärben?

Ich habe übrigens gemerkt, warum ich nicht auf die Variable value zurückgreifen konnte. Sie muss statisch sein, damit sie von anderen Klassen aus aufgerufen werden kann. Es war mir schon klar dass ich das über eine Methode regeln kann. Ich dachte das wäre aus der Frage heraus klar 

Hast du eine Idee wie ich die Wochenansicht hinkriegen könnte? ich habs mit der Variable value versucht, die in dem Array columns zu verwenden, aber ich komm grad nicht weiter und habe keine weitere Idee.

Mike

Mike


----------



## Ebenius (6. Jun 2010)

big-mike hat gesagt.:


> Ich habe die Fehlerquelle identifiziert: ich habe, um Sonntage einzufärben eine if Verzweigung eingebaut:
> 
> 
> ```
> ...


In dem Fall würde ich dem Renderer selbst ein Calender-Objekt als Feld verpassen. Dort dann das Datum setzen. Und den Calendar danach fragen, ob Sonntag ist. Auf keinen Fall solltest Du den Text vergleichen; der ist ja in jeder Sprache anders!

So könnte's aussehen: 
	
	
	
	





```
table.setDefaultRenderer(Date.class, new DefaultTableCellRenderer() {

  /** Serial version UID */
  private static final long serialVersionUID = 2L;

  final Calendar calendar = Calendar.getInstance();
  final DateFormat weekDayFormat = new SimpleDateFormat("E");
  final DateFormat dateFormat = new SimpleDateFormat("dd.MM.");
  final JLabel weekDayLabel = new JLabel("", SwingConstants.LEADING);
  final JPanel container = new JPanel(new BorderLayout(2, 2)) {

    // some performance boost

    @Override
    public void revalidate() {}

    @Override
    public void repaint(long tm, int x, int y, int width, int height) {}

    @Override
    public void repaint(Rectangle r) {}

    @Override
    public void repaint() {}
  };

  {
    container.add(weekDayLabel, BorderLayout.LINE_START);
    container.add(this, BorderLayout.CENTER);
    this.setHorizontalAlignment(SwingConstants.TRAILING);
  }

  @Override
  public Component getTableCellRendererComponent(
        JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int row,
        int column) {
    setBackground(null); // always set back default renderer background
    super.getTableCellRendererComponent(table, value, isSelected,
          hasFocus, row, column);

    if (value instanceof Date && !isSelected) {
      calendar.setTime((Date) value);
      if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
        setBackground(Color.RED);
      }
    }

    container.setBackground(getBackground());
    container.setOpaque(isOpaque());
    container.setBorder(getBorder());

    weekDayLabel.setForeground(getForeground());
    weekDayLabel.setBackground(getBackground());
    weekDayLabel.setFont(getFont());

    setBorder(null);

    return container;
  }

  @Override
  protected void setValue(Object value) {
    super.setValue(value instanceof Date
          ? dateFormat.format(value)
          : null);
    weekDayLabel.setText(value instanceof Date ? weekDayFormat
          .format(value) : null);
  }
});
```



big-mike hat gesagt.:


> Ich habe übrigens gemerkt, warum ich nicht auf die Variable value zurückgreifen konnte. Sie muss statisch sein, […]


Auf keinen Fall! Dann machst Du etwas anderes falsch. Mach's doch so wie ich's oben vorgeschlagen habe. Dem TabellenModell beim Erzeugen das ReferenzDatum mitgeben. Spiel mal ein bisschen mit rum, auf Zuruf kann man hier schlecht weiter helfen.

Ebenius


----------



## big-mike (8. Jun 2010)

Ebenius hat gesagt.:


> Wieso baust Du nicht eine Methode in das Modell ein, rufst diese auf und übergibst dort die Daten die Tabellenmodell angezeigt werden sollen?
> Ebenius



Die einzige Möglichkeit, die ich sehe, ist, die Daten dem Konstruktor zu übergeben, aber dann kann ich nur im Konstruktor damit arbeiten so weit ich weiß.



Ebenius hat gesagt.:


> Ja. Dieser Ansatz ist da schon richtig. Allerdings würde ich auch hier eher [c]Date[/c] als Wert benutzen als String. So wie es das YearDingsdaModel auch macht.
> 
> Ebenius



Ich habe jetzt nur die Möglichkeit gefunden, aus Strings [c]Date[/c] zu parsen. Meintest du das?



Ich hänge grad an dem TableModell und weiß nicht weiter. Es sieht im Prinzip so aus wie Sonntag außer deinen vorgeschlagenen Veränderungen. Was fehlt dem Model noch?! Die Tutorials im Internet helfen mir leider auch nicht weiter, genau so wenig wie das YearCalenderModell, da dieses sich ja im Kalender bedient. Mein Problem ist, dass die einfachen JTables aus den Tutorials zeilenweise gefüllt werden. Müsste ich das auch so machen? Dann würde ich ja x-mal "null" hineinschreiben. Außerdem möchte ich den Kalender, wenn wir in der Schule lernen mit Datenbanken umzugehen, "befüllen" und dann stellt diese eher unelegante Lösung, meiner Ansicht nach, ein Problem dar.

Mike


----------



## Ebenius (9. Jun 2010)

Stopp mal. Also Du willst im Endeffekt Termine im Kalender anzeigen, oder? Dann fang doch mal an und definiere Dir eine Klasse Termin, die alles kennt was sie kennen muss. Also solche Sachen wie Startdatum (als [c]Date[/c]; enthält also Datum und Uhrzeit), Enddatum, Beschreibung, vielleicht eine Kurzbeschreibung, und so weiter. Danach bauen wir dann ein Tabellenmodell zusammen, welches eine Wochenansicht erzeugt und die Termine an den einzelnen Tagen darstellt. Einverstanden?

Ebenius


----------



## big-mike (9. Jun 2010)

Deinen Vorschlag finde ich gut 
also ich hab hier eine Termin-Klasse zusammengebastelt:


```
import java.util.Date;


public class termin {

	 Date start,ende;
	 String notiz,kurzbeschreibung;
	 
	 
	 public termin(){
		 
	 }
	 
	 public termin(Date lstart,Date lende,String lnotiz,String lkurzbeschreibung){
		 
		 this.start=lstart;
		 this.ende=lende;		 	
		 this.notiz=lnotiz;
		 this.kurzbeschreibung=lkurzbeschreibung;
	 }

	
	public Date getStart(){
		return this.start;
	}
	
	public void setStart(Date lstart){
		this.start=lstart;
	}
	
	public Date getEnde(){
		return this.ende;
	}
	
	public void setEnde(Date lende){
		this.ende=lende;
	}
	 
	public String getNotiz(){
		
		return notiz;
	}
	
	public void setNotiz(String lnotiz){
		
		this.notiz=lnotiz;
	}
	
	public String getKurzbeschreibung(){
		
		return this.kurzbeschreibung;
	}
	
	public void setKurzbeschreibung(String lkurzbeschreibung){
		this.kurzbeschreibung=lkurzbeschreibung;
	}
}
```

ich denk mal diese Klasse beinhaltet alles was nötig ist !? 

Wenn es machbar wäre, würd ich gerne z.B. bei einfachem Klicken eine Tagesansicht und bei Doppelklick eine Wochenansicht erstellen. Die Dateien aus der Datenbank zu verarbeiten werd ich erst nächstes Schuljahr in Angriff nehmen, da wir dann das Umgehen mit Datenbanken lernen werden. Wichtig ist, dass die Oberfläche funktioniert 

Mike


----------



## Ebenius (10. Jun 2010)

Unterscheiden sich Wochen- und Tagesansicht in irgendeiner Weise (außer dass 6 Spalten fehlen)? Klassennamen beginnen mit GrossBuchStaben.

Ebenius


----------



## big-mike (10. Jun 2010)

Ebenius hat gesagt.:


> Unterscheiden sich Wochen- und Tagesansicht in irgendeiner Weise (außer dass 6 Spalten fehlen)?



Nein, das wäre der einzige Unterschied.

Mike


----------



## big-mike (18. Jun 2010)

so nach ner langen schulwoche hoff ich mit dem programmieren weiter zu kommen =) 
was ich sozusagen nebenbei fragen wollte ist, ob meine lösung mit dem mouselistener für die klicks ok ist, weil du einen CellRender vorgeschlagen hattest. Eigentlich sollte das ja keinen Unterschied machen oder?

Mike


----------



## big-mike (18. Jun 2010)

```
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.table.AbstractTableModel;



public class TagKalenderTableModel extends AbstractTableModel{

	private static final long serialVersionUID = 1L;

	
	
	
	Object [][] rowData; 
	Object[] columns ={"Uhr",null};
	
	 public TagKalenderTableModel(Date valueOfCell) {
		 
			String zeilen []= new String[]{"0:00","2:00","4:00","6:00","8:00","10:00","12:00","14:00",
					"16:00","18:00","20:00","22:00","24:00"};
			int i;
			for(i=1;i<13;i++){
				rowData[i][0]=zeilen[i];}
			
			final DateFormat tagesdatum= new SimpleDateFormat ("dd-MMM-yy");
	        final DateFormat wochentag = new SimpleDateFormat("EEEE");
			String cellDatum= tagesdatum.format(valueOfCell);
		    String cellTag= wochentag.format(valueOfCell);	
		    columns[1]=cellDatum;
	}
	
		
	
		@Override
        public Class <?> getColumnClass(int column) {
            return column == 0 ? Date.class : Object.class;
        }
		

		public Object getColumnNames(int column){
			if(0<column&&column<7){
				return columns[column];
			}
			return "Uhr";
				
			}
			
		public int getRowCount() { return 14; }
		public int getColumnCount() { return 2; }
		public Object getValueAt(int row, int col) {
		   			
	       return rowData[row][col];
		    }
		    
		public void setValueAt(Object value, int row, int col) {
		        rowData[row][col] = value;
		        fireTableCellUpdated(row, col);
           }
}
```

so sieht bisher mein Model aus, wie soll ich nun Daten vom Typ Date einbauen? 
Irgendwie bekomme ich eine NullPointerException bei den rowData[][], woran liegt das?

Mike


----------

