JSpinner mit Text und Ziffern

PeteProgram

Mitglied
Hallo

Ich habe folgendes vor:
Ich möchte über einen JSpinner Zahlenwerte von 1 bis (Integer-) unendlich eingeben lassen können.
Gleichzeitig soll bei einem Wert von 0 automatisch ein Text wie "unbegrenzt" o.ä im Textfeld stehen.
Die JSpinner Funktionalität auf die Pfeilbuttons zum de-/inkrementieren, sowie die Eingabe über das Textfeld sollen trotzdem funktionieren.

ich habe das Problem, dass sobald ich dem JSpinnerEditor einen MaskFormatter a lá

Code:
MaskFormatter mf = new MaskFormatter("AAAAA");

übergebe, das JFormattedTextFeld nicht mehr auf Nutzereingaben reagiert

Hat da jemand einen Vorschlag zu?
 
Zuletzt bearbeitet:
Hallo Pete,

wie man dein Vorhaben mit einem MaskFormatter realisieren könnte, wüsste ich jetzt nicht. Mir ist für diesen Lösungsansatz jetzt spontan nichts eingefallen. Allerdings bin ich einen anderen Weg gegangen und habe ein eigenes SpinnerModel geschrieben. Diesen mit einem KeyListener und einem DocumentListener kombiniert. Es erfüllt die Anforderungen aus deiner Beschreibung soweit ich dich gänzlich richtig verstanden habe. Es sind Werte von 1 bis +unendlich möglich (Integer). Weiterhin gibt es einen Sonderwert "unlimited", sofern man versucht den Wert 1 zu dekrementieren.

Es gibt eigentlich 3 Standard Spinnermodelle Date, Number und List. Die Schwierigkeit lag darin, das du sowohl das Verhaltens eines SpinnerNumberModels als auch einen Sonderwert in Form von Text haben wolltest. Hierfür passt meines Erachtens keine dieser StandardModelle, weswegen die Implementierung eines eigenen Models unumgänglich war.

Java:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class SuperSpinnerExample extends JFrame {

	private JSuperSpinner ss = new JSuperSpinner();

	public SuperSpinnerExample() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setAlwaysOnTop(true);
		this.setLocationByPlatform(true);
		this.add(ss);
		this.pack();
		this.setVisible(true);
	}

	public static void main(String[] args) {
		SuperSpinnerExample spin = new SuperSpinnerExample();
	}

	class JSuperSpinner extends JSpinner {
		private JTextField tf;

		private DocumentListener dl;

		public JSuperSpinner() {
			this.setModel(new SuperSpinnerModel());
			tf = ((DefaultEditor) this.getEditor()).getTextField();
			tf.setEditable(true);
			tf.addKeyListener(new KeyAdapter() {
				public void keyTyped(KeyEvent e) {
					if (!Character.isDigit(e.getKeyChar()))
						e.consume();
				}
			});
			dl = new DocumentListener() {
				Runnable r = new Runnable() {
					public void run() {
						if (tf.getText() != null && tf.getText().length() > 0
								&& tf.getText().matches("0*"))
							tf.setText("unlimited");
					}
				};
				public void insertUpdate(DocumentEvent e) {
					tf.getDocument().removeDocumentListener(dl);
					changedUpdate(e);
					tf.getDocument().addDocumentListener(dl);
				}

				public void removeUpdate(DocumentEvent e) {
					tf.getDocument().removeDocumentListener(dl);
					changedUpdate(e);
					tf.getDocument().addDocumentListener(dl);
				}

				public void changedUpdate(DocumentEvent e) {
					SwingUtilities.invokeLater(r);
				}
			};
			tf.getDocument().addDocumentListener(dl);
		}

		class SuperSpinnerModel extends AbstractSpinnerModel {

			private String value = "1";

			public Object getValue() {
				return value;
			}

			public void setValue(Object value) {
				this.value = (String) value;
				this.fireStateChanged();
			}

			public Object getNextValue() {
				Integer i = null;
				try {
					i = Integer.parseInt(value);
				} catch (Exception e) {
					return "1";
				}
				return "" + (i + 1);
			}

			public Object getPreviousValue() {
				Integer i;
				try {
					i = Integer.parseInt(value);
				} catch (Exception e) {
					return "unlimited";
				}
				if ((i - 1) < 1)
					return "unlimited";
				else
					return "" + (i - 1);
			}
		}
	}
}

Vg Erdal
 
Zuletzt bearbeitet:
Zurück