JFormattedTextField in einem Celleditor

ElJarno

Mitglied
Hi Leute,
also die Situation ist so: Habe in einen CellEditor ein JFormattedTextField übergeben. Bei dem JFormattedTextField ist es standardmäßig so, dass bei falscher Eingabe die Zelle nicht verlassen wird. Das ist auch in Ordnung so. Nur mein Probleme besteht darin, dass trotzdem die stopCellediting()-Methode aus der Cell-Editor Klasse aufgerufen wird. Meine Frage wäre dahingehend ob ich den Aufruf unterbinden kann. Um die Situation etwas genauer zu erläutern warum ich das möchte. Der Celleditor ist für eine Zeiteingabe bestimmt dessen Format ich über die JFormattedTextField vorgebe "##:##:##". Die Cell-Editor Klasse hab ich selbst geschrieben. In der stopCellEditing()-Methode soll geprüft werden ob die Zeit gültig ist. Also nicht 99:99:99. Wenn jemand einen anderen Lösungweg, sehr gerne. Ansonsten würd ich es so machen wie oben beschrieben.

Gruß Jan
 
Moin,

poste doch einfach mal den relevanten Code (bitte mit den entsprechenden Code-Tags) - alles andere ist sonst Rätselraterei :eek::p

Gruß
Klaus
 
Ich habs einigermaßen hinbekommen so wie ich es wollte.Bei Enter und Focuslost bzw. beim Klicken auf einer Anderen Zelle soll jetzt immer die stopCelleditimg ausgefeührt werden. In dieser Frage ich dann ab ob Leerzeichen vorhanden sind oder eine falsche Zeit einegegeben worden ist und lasse ihn nicht aus der Zelle. Aber trotzdem hier der Code.Vlrt fällt ja meanden eine gewisse edlerer oder saubere Lösung ein;).

Code für den JFormattedTextfield
Code:
	MaskFormatter formatter;
	DefaultFormatterFactory defaultFormatter;
	JFormattedTextField jTextField12 = new JFormattedTextField();
	jTextField12.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "check");
	jTextField12.getActionMap().put("check", new AbstractAction() {
		public void actionPerformed(ActionEvent e) {
			jTable.getColumnModel().getColumn(12).getCellEditor().stopCellEditing();
		}
	});

	try {
		formatter = new MaskFormatter("##:##:##");
		defaultFormatter = new DefaultFormatterFactory(formatter);
		jTextField12.setFormatterFactory(defaultFormatter);
	} catch (ParseException e) {
		e.printStackTrace();
	}

public class FocusListenerTextField implements FocusListener {
	public void focusGained(FocusEvent e) {
	}
	public void focusLost(FocusEvent e) {
		jTable.getColumnModel().getColumn(12).getCellEditor().stopCellEditing();
	}
}

Code für die stopCellEditing()-Methode:
Code:
	public boolean stopCellEditing() {
		JFormattedTextField jtf = (JFormattedTextField) getComponent();
		String sftf = jtf.getText().toString();
		if (sftf != "") {
			String[] stringZeiten = sftf.split(":");
			Vector<Integer> zeiten = new Vector<Integer>();

			for (String stringZeit : stringZeiten) {
				if (stringZeit.contains(" ")) {
					JOptionPane.showMessageDialog(null, "Fehlerhaftes Zeitformat eingegeben: "
							+ "\nDie Zeit muss im Format SS:MM:SS eingegeben werden", "Fehler",
							JOptionPane.WARNING_MESSAGE);
					return false;
				}
				zeiten.add(Integer.valueOf(stringZeit));
			}

			if (zeiten.get(0) < 0 || zeiten.get(0) > 23 || zeiten.get(1) < 0 || zeiten.get(1) > 59
					|| zeiten.get(2) < 0 || zeiten.get(2) > 59) {
				JOptionPane.showMessageDialog(null, "Ungültige Zeit eingegeben: "
						+ "\nDie Zeit muss zwischen 00:00:00 und 23:59:59 liegen", "Fehler",
						JOptionPane.WARNING_MESSAGE);
				return false;
			}
		}
		System.out.println("in CellEdLP  stopCellEditing: " + sftf);
		if (STR != null && STR.equals(sftf)) {
			super.cancelCellEditing();
			return true;
		}
		STR = jtf.getText().toString();
		super.stopCellEditing(); // cellvalue uebernehmen
		return true;
	}
 
Schau dir mal dieses Demo-Programm an:

Java:
/*
Title: Separating Date and Time in a JSpinner
Description: Separating date and time in JSpinner using java swing.
This file came from Planet-Source-Code.com...the home millions of lines of source code
You can view comments on this code/and or vote on it 
at: http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=5512&lngWId=2

The author may have retained certain copyrights to this code...please 
observe their request and the law 
by reviewing all copyright conditions at the above URL.
*/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import javax.swing.JSpinner.DateEditor;

/**
 * Represents the frame used to display the date and time.
 * 
 * @author ali
 */

public class SplitDateTime extends JFrame {

	/**
	 * Label used for date spinner.
	 * 
	 */
	private JLabel dateSpinnerLabel = null;

	/**
	 * Label used for time spinner.
	 */
	private JLabel timeSpinnerLabel = null;

	/**
	 * Spinner component for date.
	 * 
	 */
	private JSpinner dateSpinner = null;

	/**
	 * Spinner component for time.
	 * 
	 */
	private JSpinner timeSpinner = null;

	/**
	 * ContentPane.
	 */
	private Container container = null;

	/**
	 * Panel that holds the dateSpinnerLabel and dateSpinner.
	 * 
	 */
	private JPanel dateHolder = null;

	/**
	 * Panel that holds the timeSpinnerLabel and timeSpinner.
	 * 
	 */
	private JPanel timeHolder = null;

	/**
	 * Label used for spacing.
	 */
	private JLabel spacerLabel = null;

	/**
	 * Default Constructor.
	 * 
	 */
	public SplitDateTime() {
		super("Separating Date and Time in JSpinner");
		initGUI();
		createGUI();
	}// end default constructor.

	/**
	 * Initialize the UI components required for creating the GUI.
	 */
	private void initGUI()
	{
		dateSpinnerLabel = new JLabel("Date");
		timeSpinnerLabel= new  JLabel("Time");
		
		dateSpinner=new JSpinner(new SpinnerDateModel());
		timeSpinner= new JSpinner(new SpinnerDateModel());
		
		dateSpinner.setEditor(new DateEditor(dateSpinner, "dd.MM.yyyy"));
		timeSpinner.setEditor(new DateEditor(timeSpinner, "HH:mm:ss"));
		
		container  = getContentPane();
		
		dateHolder= new JPanel(new BorderLayout());		
		timeHolder=new JPanel(new BorderLayout());
				
		spacerLabel=new JLabel();
		spacerLabel.setPreferredSize(new Dimension(10,10));
	}// end method initGUI.
	
	/**
	 * 
	 * Creates the GUI.
	 **/
	private void createGUI()
	{
		container.setLayout(new BorderLayout());
		
		dateHolder.add(dateSpinnerLabel, BorderLayout.WEST);
		dateHolder.add(dateSpinner, BorderLayout.EAST);
		
		timeHolder.add(timeSpinnerLabel,BorderLayout.WEST);
		timeHolder.add(timeSpinner,BorderLayout.EAST);
		
		container.add(dateHolder, BorderLayout.NORTH);
		container.add(spacerLabel, BorderLayout.CENTER);
		container.add(timeHolder, BorderLayout.SOUTH);
		
		setBounds(200, 200, 350, 75);
		setResizable(false);
		setVisible(true);
	}// end method createGUI.
	
	/**
	 * Ímplementation of the main method.
	 * 
	 * @param args
	 */
	public static void main(String[] args)
	{
		new SplitDateTime();
	}// end method main
}
Damit der Spinner auch das richtige Feld hochzählt, z.B. Minute statt Stunde, muss man natürlich das Caret (den Text-Cursor) dorthin positionieren, beispielsweise per Mausklick. Eine Eingabe per Tastatur ist aber auch möglich.
 
also so richtig habe ich das Problem immer noch nicht gelöst. Noch mal hier die Vorgaben. Also die Zeiteingabe geschieht über einen JFromattedTextField damit die Fromatierung schon mal passt und die Eingabe erleichtert wird. Jetzt soll aber bei der eingabe von z.b "99:99:99" ein JOptionpane oder was Anderes angezeigt werden genauso wie wenn man nur "99:9 : " eingibt. Vorher soll die Zelle auch nicht verlassen werden. Die JFormattedTexField benutze ich deswegen weil ich den CellEditor in einer Tabelle einbette. Deswegen wollte ich jetzt nicht unbedingt den Spinner verwenden. Es sei denn man kann dem Eigenschaften übergeben dass nur die Uhrzeit zwischen 00:00:00 und 23:59:59 liegen soll und bei der Eingabe von 26:00:00 nicht 02:00:00 daraus wird sonder wie gesagt das JOptionPane aufpopt und die Eingabe nicht beendet wird.
 
Dann hänge doch einen ChangeListener an das SpinnerDateModel (Methode addChangeListener, geerbt von AbstractSpinnerModel). Auf diese Weise kannst du verfolgen, welche Werte wie geändert wurden, und entscheiden, was getan werden soll. Alternativ dazu kannst du natürlich auch den ChangeListener dem JSpinner direkt hinzufügen.

PS: Ich persönlich würde das nicht tun, weil ich die vorgegebene Verhaltensweise als praktisch empfinde.
 
Zurück