Swing JSpinner und die Zeit

Status
Nicht offen für weitere Antworten.

elitebiber

Mitglied
Hallo zusammen,

ich hab schon überall nach einer Lösung gesucht und hoffe hier endlich eine zu finden. Und gleich vorweg, ja die SuFu hab ich schon benutzt aber dabei hat mir nichts auf die Sprünge geholfen.

Ich habe in meinem Programm zwei JSpinner denen ich ein festes Datum übergebe. Es wird allerdings nur die Zeit angezeigt weil nur diese geändert werden soll. Wenn ich nun aber die Zeit ändere wird nicht nur die Zeit geändert sondern auch gleich das gesamte Datum auf den 01.01.1970 gesetzt. Wie kriege ich es jetzt also hin, dass wirklich nur die Zeit geändert wird?

Und hier auch gleich mal der entscheidende Codeschnipsel
Java:
JSpinner spStart, spStop;
SpinnerDateModel sdmStart, sdmStop;

sdmStart = new SpinnerDateModel();
sdmStart.setValue(new Date(to.getStartTime()));
spStart = new JSpinner(sdmStart);
spStart.setEditor(new DateEditor(spStart, "HH:mm:ss"));

sdmStop = new SpinnerDateModel();
sdmStop.setValue(new Date(to.getStopTime()));
spStop = new JSpinner(sdmStop);
spStop.setEditor(new DateEditor(spStop, "HH:mm:ss"));

to ist dabei ein Objekt aus dem ich das komplette Datum ziehe.
 

Ebenius

Top Contributor
Zwei Dinge gibt es dazu zu tun.
  1. Das Modell muss mit Minimum und Maximum initialisiert werden, damit beim Knopfdrücken (hoch / runter) das Datum nicht gewechselt wird.
    Java:
    final Calendar cal = Calendar.getInstance();
    cal.setTime(theDate);
    cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
    cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
    cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
    cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
    final Date minDate = cal.getTime();
    cal.add(Calendar.DAY_OF_MONTH, 1);
    cal.add(Calendar.MILLISECOND, -1);
    final Date maxDate = cal.getTime();
    
    final SpinnerModel dateModel =
          new SpinnerDateModel(theDate, minDate, maxDate, Calendar.HOUR);
  2. Außerdem muss man dem Formatter des Editors beibringen, das Datum des Spinner-Modells als Basis zu nehmen und nur die Uhrzeit zu übernehmen.
    Java:
    final JSpinner dateSpinner = new JSpinner(dateModel);
    final DateEditor dateEditor = new DateEditor(dateSpinner, "HH:mm");
    final DefaultFormatterFactory fFactory = new DefaultFormatterFactory();
    fFactory.setDefaultFormatter(new DateFormatter(dateEditor.getFormat()));
    fFactory.setEditFormatter(new DateFormatter(dateEditor.getFormat()) {
    
      @Override
      public Object stringToValue(String text) throws ParseException {
        final Calendar cal = Calendar.getInstance();
        cal.setTime((Date) super.stringToValue(text));
        final int hour = cal.get(Calendar.HOUR_OF_DAY);
        final int minute = cal.get(Calendar.MINUTE);
        final int second = cal.get(Calendar.SECOND);
        final int millisecond = cal.get(Calendar.MILLISECOND);
        cal.setTime((Date) dateModel.getValue());
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, minute);
        cal.set(Calendar.SECOND, second);
        cal.set(Calendar.MILLISECOND, millisecond);
        return cal.getTime();
      }
    });
    dateEditor.getTextField().setFormatterFactory(fFactory);
    dateSpinner.setEditor(dateEditor);
Ich hoffe, das hilft Dir weiter.

Ebenius
 

elitebiber

Mitglied
Das Ergebnis gefällt mir soweit schonmal sehr gut, danke für die schnelle Antwort, aber leider taucht gleich wieder was unschönes auf.

Die JSpinner nehmen leider nicht das übergebene Format "HH:mm:ss" an sondern den Datentyp "dd.mm.yyyy HH:mm" das allgemeine Datum kann dabei ruhig dort stehen, aber die Sekunden sind in meinem Fall auch wichtig.

So ganz nebenbei, ist es auch möglich die Maximalgrenze des 1ten Spinners auf den Wert im 2ten Spinner und ebenso die Minimalgrenze des 2ten Spinners auf den Wert im 1ten Spinner setzen. Dabei muss natürlich die Grenze beim ändern des Wertes jeweils im anderen angepasst werden.

Sorry wenns nen bissel viel ist was ich Frage aber ich steh mal voll aufm Schlauch.

Hier gleich nochma mein Code momentan
Java:
  final Calendar cal = Calendar.getInstance();
  cal.setTime(new Date(to.getStartTime()));
  cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
  cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
  cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
  cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
  final Date minDate = cal.getTime();
  cal.add(Calendar.DAY_OF_MONTH, 1);
  cal.add(Calendar.MILLISECOND, -1);
  final Date maxDate = cal.getTime();

  sdmStart = new SpinnerDateModel(new Date(to.getStartTime()),
                        minDate, maxDate, Calendar.HOUR);

  spStart = new JSpinner(sdmStart);
  final DateEditor sdmStartEditor = new DateEditor(spStart, "HH:mm:ss");
  final DefaultFormatterFactory sdmStartFactory = new DefaultFormatterFactory();
  sdmStartFactory.setDefaultFormatter(new DateFormatter(sdmStartEditor.getFormat()));
  sdmStartFactory.setEditFormatter(new DateFormatter(sdmStartEditor.getFormat()) {
    @Override
    public Object stringToValue(String text) throws ParseException {
      final Calendar cal = Calendar.getInstance();
      cal.setTime((Date) super.stringToValue(text));
      final int hour = cal.get(Calendar.HOUR_OF_DAY);
      final int minute = cal.get(Calendar.MINUTE);
      final int second = cal.get(Calendar.SECOND);
      final int millisecond = cal.get(Calendar.MILLISECOND);
      cal.setTime((Date) sdmStart.getValue());
      cal.set(Calendar.HOUR_OF_DAY, hour);
      cal.set(Calendar.MINUTE, minute);
      cal.set(Calendar.SECOND, second);
      cal.set(Calendar.MILLISECOND, millisecond);
      return cal.getTime();
    }
  });

  sdmStop = new SpinnerDateModel(new Date(to.getStopTime()),
                        minDate, maxDate, Calendar.HOUR);

  spStop = new JSpinner(sdmStop);
  final DateEditor sdmStopEditor = new DateEditor(spStop, "HH:mm:ss");
  final DefaultFormatterFactory sdmStopFactory = new DefaultFormatterFactory();
  sdmStopFactory.setDefaultFormatter(new DateFormatter(sdmStopEditor.getFormat()));
  sdmStopFactory.setEditFormatter(new DateFormatter(sdmStopEditor.getFormat()) {
    @Override
    public Object stringToValue(String text) throws ParseException {
      final Calendar cal = Calendar.getInstance();
      cal.setTime((Date) super.stringToValue(text));
      final int hour = cal.get(Calendar.HOUR_OF_DAY);
      final int minute = cal.get(Calendar.MINUTE);
      final int second = cal.get(Calendar.SECOND);
      final int millisecond = cal.get(Calendar.MILLISECOND);
      cal.setTime((Date) sdmStop.getValue());
      cal.set(Calendar.HOUR_OF_DAY, hour);
      cal.set(Calendar.MINUTE, minute);
      cal.set(Calendar.SECOND, second);
      cal.set(Calendar.MILLISECOND, millisecond);
      return cal.getTime();
    }
  });

Wie du siehst hab ich deinen Code fast 1 zu 1 übernommen.


Ach ja wenn sich einer für das Projekt interessiert, dass ich gerade schreibe kann unter SourceForge.net: Time My Project nachsehen. Ich suche auch noch immer nach Leuten die Lust haben mich dabei zu unterstützen.
 

Ebenius

Top Contributor
Wie du siehst hab ich deinen Code fast 1 zu 1 übernommen.
Jupp. Leider hast Du diese beiden Zeilen ignoriert. Deshalb geht's auch nicht wie gewünscht:
Java:
dateEditor.getTextField().setFormatterFactory(fFactory);
dateSpinner.setEditor(dateEditor);
Anmerkung am Rande: Wenn Du das gleiche zweimal machst, dann lagere die doppelten Sachen doch aus! Der Quelltext wird dadurch auch gleich mal übersichtlicher. Zum Beispiel so:
Java:
static void adjustSpinnerTimeEditor(JSpinner dateSpinner) {
  final SpinnerModel spinnnerModel = dateSpinner.getModel();
  final DateEditor timeEditor = new DateEditor(dateSpinner, "HH:mm:ss");
  final DefaultFormatterFactory fFactory = new DefaultFormatterFactory();
  fFactory.setDefaultFormatter(new DateFormatter(timeEditor.getFormat()));
  fFactory.setEditFormatter(new DateFormatter(timeEditor.getFormat()) {

    @Override
    public Object stringToValue(String text) throws ParseException {
      final Calendar cal = Calendar.getInstance();
      cal.setTime((Date) super.stringToValue(text));
      final int hour = cal.get(Calendar.HOUR_OF_DAY);
      final int minute = cal.get(Calendar.MINUTE);
      final int second = cal.get(Calendar.SECOND);
      final int millisecond = cal.get(Calendar.MILLISECOND);
      cal.setTime((Date) spinnnerModel.getValue());
      cal.set(Calendar.HOUR_OF_DAY, hour);
      cal.set(Calendar.MINUTE, minute);
      cal.set(Calendar.SECOND, second);
      cal.set(Calendar.MILLISECOND, millisecond);
      return cal.getTime();
    }
  });

  timeEditor.getTextField().setFormatterFactory(fFactory);
  dateSpinner.setEditor(timeEditor);
}

static SpinnerModel createSpinnerTimeModel(Date date) {
  final Calendar cal = Calendar.getInstance();
  cal.setTime(date);

  cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
  cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
  cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
  cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
  final Date minDate = cal.getTime();

  cal.add(Calendar.DAY_OF_MONTH, 1);
  cal.add(Calendar.MILLISECOND, -1);
  final Date maxDate = cal.getTime();

  return new SpinnerDateModel(date, minDate, maxDate, Calendar.HOUR);
}
Das kannst Du eigentlich gleich so in Deinen Quelltext übernehmen. Und dann rufst Du die Methoden so auf:
Java:
sdmStart = createSpinnerTimeModel(new Date(to.getStartTime()));
adjustSpinnerTimeEditor(spStart = new JSpinner(sdmStart));

Ebenius
 
Zuletzt bearbeitet:

elitebiber

Mitglied
Oh man, du bist genial.

Danke dir vielmals. Hast mir gleich mal den Tag gerettet.

Wenn ich dich dann vielleicht gleich noch ein letztes Mal nerven darf, wie schauts denn aus mit dem dynamischen setzen des Maximal- bzw. Minimalwerts?
 

elitebiber

Mitglied
Ich würde gerne die Maximal- und Minimalwerte so setzen. Das ich den 1ten Spinner nicht über den Wert des 2ten setzen kann und den 2ten nicht unter den Wert des 1ten, also das die Differenz zwischen beiden minimal 0 aber nicht negativ wird.

Also müsste demnach ja nach jedem ändern der Zeit in einem der beiden Spinner der Maximal- bzw. Minimalwert neu gesetzt werden, damit dieser nicht über- bzw. unterschritten wird.

Hört sich jetzt wahrscheinlich nen bissel verworren an, aber ich hoffe du verstehst was ich meine.
 

Ebenius

Top Contributor
Jetzt hört sich's nicht mehr verworren an. Jetzt verstehe ich Dich. Das ganze löst Du am einfachsten über eine Verbindung zwischen beiden Modellen. Zum Beispiel:
Java:
static void crossReferenceSpinnerDateModels(
      final SpinnerDateModel lowerDateModel,
      final SpinnerDateModel upperDateModel) {
  lowerDateModel.addChangeListener(new ChangeListener() {

    public void stateChanged(ChangeEvent e) {
      final Date upperDate = upperDateModel.getDate();
      final Date value = ((SpinnerDateModel) e.getSource()).getDate();
      if (upperDate.compareTo(value) < 0) {
        upperDateModel.setValue(value);
      }
      upperDateModel.setStart(value);
    }
  });
  upperDateModel.addChangeListener(new ChangeListener() {

    public void stateChanged(ChangeEvent e) {
      final Date lowerDate = lowerDateModel.getDate();
      final Date value = ((SpinnerDateModel) e.getSource()).getDate();
      if (lowerDate.compareTo(value) > 0) {
        lowerDateModel.setValue(value);
      }
      lowerDateModel.setEnd(value);
    }
  });
}
Ebenius
 

elitebiber

Mitglied
Ich kann dir gar nicht genug danken.

So funktionierts perfekt, genauso wie ich das wollte.

Hoffe ich kann mich irgendwann mal bei dir revanchieren.
 

steve12345

Mitglied
hi!

gibt es eine Möglichkeit dem JSpinner auch Zeitwerte größer 24:00 zu erlauben?
das DateFormat mit setlenient zu bearbeiten brachte keinen erfolg
 

Ebenius

Top Contributor
Ein DateFormat ist hier der falsche Ansatz. DateFormat macht aus Date-Instanzen (also konkreten Zeitpunkten) eine textliche Darstellung und umgekehrt. Sofern Du keinen Kalender hast, bei dem es am fünfundvierzigsten März sechsundfünfzig Uhr dreiundneunzig werden kann, kannst Du auch diese Zeit nicht darstellen. Ein nachlässiges (lenient) DateFormat ist ledliglich so großzügig beim Parsen bspw. eine Uhrzeit 27:00 als einen Tag später 3:00 auszuwerten. Beim Formatieren stellt es aber die Zeit so dar, wie sie laut Kalender existieren kann.

Ein JSpinner kann im Prinzip alles darstellen. Du brauchst einen eigegen Editor im Spinner und der muss über ein eigenes Format seine Textdarstellung/Textinterpretation so machen wie Du das willst. Ist aber nicht eben mal trivial.

Ebenius
 

steve12345

Mitglied
danke für den klapps auf den hinterkopf ;)


hab das ganze erstmal mit 2 JSpinnern gelöst:

Java:
SpinnerNumberModel model = new SpinnerNumberModel(0,0,99,+1);
JSpinner stunde = new JSpinner(model);
stunde.setEditor(new JSpinner.NumberEditor(stunde,"#0"));

model = new SpinnerNumberModel(0,0,59,+1);
JSpinner minute = new JSpinner(model);
minute.setEditor(new JSpinner.NumberEditor(minute ,"00"));


aber so richtig zufrieden bin ich damit natürlich noch nicht... ich werd mal weiter basteln...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
D TAB Taste innerhalb eines JSpinner AWT, Swing, JavaFX & SWT 2
C JSpinner AWT, Swing, JavaFX & SWT 6
C Hilfe bei JSpinner und JList AWT, Swing, JavaFX & SWT 1
K Swing JSpinner mit NULL AWT, Swing, JavaFX & SWT 3
V LookAndFeel JSpinner Hintergrund Farbe mit Nimbus LaF AWT, Swing, JavaFX & SWT 0
R Int aus JSpinner auslesen und Tabelle erstellen AWT, Swing, JavaFX & SWT 3
K JSpinner in passender Breite erstellen oder automatisch anpassen AWT, Swing, JavaFX & SWT 2
D JCheckbox und JSpinner in JTable AWT, Swing, JavaFX & SWT 9
M JSpinner, setValue AWT, Swing, JavaFX & SWT 7
N Swing JSpinner mit Datum aber ohne Uhrzeit AWT, Swing, JavaFX & SWT 2
J Swing JSpinner mit zusätzlichem Text? AWT, Swing, JavaFX & SWT 2
B JSpinner ChangeEvent erzwingen AWT, Swing, JavaFX & SWT 6
B JSpinner Textgröße anpassen AWT, Swing, JavaFX & SWT 2
B JSpinner welche Taste? AWT, Swing, JavaFX & SWT 5
B JSpinner Enter AWT, Swing, JavaFX & SWT 7
G JSpinner ohne Tausendertrennzeichen AWT, Swing, JavaFX & SWT 5
N Wertanzeige mittels JSpinner AWT, Swing, JavaFX & SWT 3
S JSpinner AWT, Swing, JavaFX & SWT 11
G Swing JSpinner nur mit Buttons ändern AWT, Swing, JavaFX & SWT 8
T JSpinner in JTable: Problem beim Auslesen, funktioniert erst beim Zellwechsel AWT, Swing, JavaFX & SWT 7
T Swing JSpinner in JTable AWT, Swing, JavaFX & SWT 9
C Größe von JSpinner fixieren AWT, Swing, JavaFX & SWT 4
J JSpinner + SpinnerNumberModel int auslesen AWT, Swing, JavaFX & SWT 2
C Zwei JSpinner mit dem gleichen Wert AWT, Swing, JavaFX & SWT 2
Eldorado Swing Popup-Menü mit Jspinner AWT, Swing, JavaFX & SWT 4
X Den Wert von JSpinner setzen ohne Event AWT, Swing, JavaFX & SWT 3
M JSpinner als TableCellEditor; buttons nur bei fokus sichtbar AWT, Swing, JavaFX & SWT 14
M JSpinner Font ändern AWT, Swing, JavaFX & SWT 4
Spin JSpinner AWT, Swing, JavaFX & SWT 10
T JSpinner, 3 JSpinner aber nur ein SpinnerDateModel AWT, Swing, JavaFX & SWT 7
S JSpinner der Floats anzeigt..? AWT, Swing, JavaFX & SWT 4
D Swing Eigene Komponente mit JSpinner AWT, Swing, JavaFX & SWT 4
T JSpinner Problem AWT, Swing, JavaFX & SWT 6
G JSpinner umdrehen? AWT, Swing, JavaFX & SWT 2
G JSpinner und ChangeListener AWT, Swing, JavaFX & SWT 3
K JSpinner - Model <-> View, unterschiedliche Werte AWT, Swing, JavaFX & SWT 9
Tom299 JSpinner nur Zeitangabe AWT, Swing, JavaFX & SWT 13
G JSpinner Frage AWT, Swing, JavaFX & SWT 2
H JSpinner mit Kalenderwoche und Jahr AWT, Swing, JavaFX & SWT 6
M JSpinner in einer JTable? AWT, Swing, JavaFX & SWT 5
P Frage zu JSpinner AWT, Swing, JavaFX & SWT 3
B JTextFiled, JCheckBox, JSpinner Eigenschaften speichern AWT, Swing, JavaFX & SWT 2
R Konvertieren von Werten im JSpinner AWT, Swing, JavaFX & SWT 2
K JSpinner Werte verschwinden bei Panel Wechsel AWT, Swing, JavaFX & SWT 2
B JSpinner passt optisch nicht zu anderen Komponenten AWT, Swing, JavaFX & SWT 2
D JSpinner ohne Edit Möglichkeit AWT, Swing, JavaFX & SWT 5
J JSpinner mit zahlen AWT, Swing, JavaFX & SWT 10
P JSpinner Objekt anstatt Zahlen sollen man Namen auswählen AWT, Swing, JavaFX & SWT 2
L JSpinner + addRow() AWT, Swing, JavaFX & SWT 3
M .txt unter Verwendung von JSpinner in Textfeld schreiben AWT, Swing, JavaFX & SWT 4
N JDK1.4- Überladen d. Methoden getValue setValue von JSpinner AWT, Swing, JavaFX & SWT 2
S JSpinner: Editieren einschränken AWT, Swing, JavaFX & SWT 4
F JSpinner FocusListener AWT, Swing, JavaFX & SWT 2
W JSpinner: Button vertikal anordnen AWT, Swing, JavaFX & SWT 2
R JSpinner rotieren AWT, Swing, JavaFX & SWT 6
A JSpinner in Dialogbox integrieren? AWT, Swing, JavaFX & SWT 3
D JSPinner Größe verändern - setSize() funktioniert nicht AWT, Swing, JavaFX & SWT 7
javasdann JSpinner & KeyListener. AWT, Swing, JavaFX & SWT 8
G jspinner schrittweite in Abhängigkeit vom aktuellen Wert AWT, Swing, JavaFX & SWT 3
G JSpinner bringt bei anklicken eine CastException AWT, Swing, JavaFX & SWT 5
flashfactor Un mal ein Problem mit JSpinner AWT, Swing, JavaFX & SWT 7
I jSpinner.getValue() AWT, Swing, JavaFX & SWT 2
G JSpinner für Datumsanzeige AWT, Swing, JavaFX & SWT 2
izoards Textfeld für Zeit AWT, Swing, JavaFX & SWT 4
S Swing JLabel Text mit der Zeit ändern AWT, Swing, JavaFX & SWT 1
F JavaFX Aktuelle Zeit in einem TextField anzeigen AWT, Swing, JavaFX & SWT 7
P JavaFX StackedAreaChart mit Datum und Zeit AWT, Swing, JavaFX & SWT 2
2 Zeit Differenz automatisch aktualisieren AWT, Swing, JavaFX & SWT 1
B GUI Darstellungsfehler mit der Zeit AWT, Swing, JavaFX & SWT 3
P LayoutManager Design meines Projekts (hätte wer zeit?) AWT, Swing, JavaFX & SWT 9
X Java Komponenten jeder Zeit hinzufügen können AWT, Swing, JavaFX & SWT 3
D Swing jSlider soll selber weiterwandern, je nach zeit der musik AWT, Swing, JavaFX & SWT 5
R 2D-Grafik Messdiagramm - Diagramm über Zeit AWT, Swing, JavaFX & SWT 5
D JTree zur richtigen Zeit aktualisieren. AWT, Swing, JavaFX & SWT 3
E JLabel nach Zeit X ausblenden AWT, Swing, JavaFX & SWT 12
G Statusmeldung anzeigen und nach gewisser Zeit ausblenden AWT, Swing, JavaFX & SWT 4
mabe83 Kontinuierlich verbleibende Zeit in JTable Spalte anzeigen AWT, Swing, JavaFX & SWT 2
P JTable:Sortierung nach der Zeit/Spalte mit Calendar-Objekten AWT, Swing, JavaFX & SWT 2
G GUI für kurze Zeit stillstehen lassen. AWT, Swing, JavaFX & SWT 23
A JTable: Zeit in Spalte ausgeben AWT, Swing, JavaFX & SWT 2
M Spalte mit fortlaufener Zeit AWT, Swing, JavaFX & SWT 6
O JTextField: Text nur für kurze Zeit anzeigen AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben