# In Textfeld Kommazahl anzeigen aber ohne Komma eingeben



## forrest (27. Apr 2010)

Hallo zusammen,

ich versuche gerade ein Problem zu lösen, dass folgendermaßen aussieht:
Ich muss in einer Oberflöche viele Zahlen nacheinander eingeben, die immer gleich formatiert sind: ein oder zwie Vorkommazahlen und eine Nachkommazahl. Damit ich die Eingabe einfacher gestalten kann möchte ich gerne die Zahl ohne Komma eingeben. Das Textfeld soll allerdings direkt die Zahl korrekt formatieren. Bei einer Eingabe von 78 soll also direkt 7,8 angezeigt werden. Ich komme hier leider nicht weiter. Kann mir dabei jemand helfen?

Danke,

Forrest


----------



## EdelStoff (27. Apr 2010)

Du könntest dem TextField einen KeyListener hinzufügen und darin dann etwas in diese Richtung machen:

```
private void jTextFieldKeyReleased(KeyEvent evt) {
		String text = jTextField.getText();
		text = text.replaceAll(",", "");
		jTextField.setText(text.substring(0, text.length() - 1) + ","
				+ text.substring(text.length() - 1));
}
```

geht mit sicherheit noch schöner, aber etwas besseres ist mir auf die schnelle nicht eingefallen.


----------



## forrest (27. Apr 2010)

Das scheint zu funktionieren. Danke Dir! 
Wenn es tatsächlich noch eine schönere Variante geben sollte, wäre ich auch nicht abgeneigt


----------



## w0ddes (27. Apr 2010)

How to Use Formatted Text Fields (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)

Könnte auch helfen und dürfte vllt sogar einfacher sein


----------



## forrest (27. Apr 2010)

Das habe ich auch ausprobiert, allerdings muss man dabei immer das Trennzeichen miteingeben. Jedenfalls habe ich keinen Weg gefunden, wie man das umgehen kann.


----------



## w0ddes (27. Apr 2010)

War nur n Vorschlag, hab selber noch nich damit gearbeitet


----------



## Ebenius (27. Apr 2010)

EdelStoff hat gesagt.:


> Du könntest dem TextField einen KeyListener hinzufügen und [...]


Key Listener ist hier ungünstig. Zum Beispiel kann ich ja als Benutzer auch über die Maus Daten in das Textfeld kopieren. Ein Key Listener schlägt dann nicht an. Aber die selbe Lösung lässt sich sicher auch über einen DocumentListener realisieren...



forrest hat gesagt.:


> Das habe ich auch ausprobiert, allerdings muss man dabei immer das Trennzeichen miteingeben. Jedenfalls habe ich keinen Weg gefunden, wie man das umgehen kann.


Indem man einen eigenen Formatter implementiert und diesen dem JFormattedTextField übergibt.

Ebenius


----------



## Ebenius (27. Apr 2010)

Ebenius hat gesagt.:


> Indem man einen eigenen Formatter implementiert und diesen dem JFormattedTextField übergibt.


Man muss die Formatter nicht mal selber implementieren. Hier mal ein Beispiel: 
	
	
	
	





```
/* (@)FormattedTextFieldTestGui.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.awt.BorderLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.text.DecimalFormat;

import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;

/**
 * Sample code for formatted text fields with separate display and edit
 * formatters.
 * 
 * @version $Revision$ as of $Date$
 * @author Sebastian Haufe
 * @since Playground-3.8
 */
public class FormattedTextFieldTestGui {

  /** Creates the GUI. Call on EDT, only! */
  static void createAndShowGui() {
    /* create custom number formats */
    final DecimalFormat displayFmt = new DecimalFormat("#.00");
    final DecimalFormat editFmt = new DecimalFormat("#.##");

    /* create custom formatters */
    final NumberFormatter editFormatter = new NumberFormatter(editFmt);
    final NumberFormatter displayFormatter = new NumberFormatter(displayFmt);

    /* create formatted text field with my formatters */
    final JFormattedTextField ftf = new JFormattedTextField();
    ftf.setFormatterFactory(new DefaultFormatterFactory(displayFormatter,
          displayFormatter, editFormatter));

    /* select all on focus gained */
    ftf.addFocusListener(new FocusAdapter() {

      @Override
      public void focusGained(final FocusEvent e) {
        SwingUtilities.invokeLater(new Runnable() {

          public void run() {
            ((JFormattedTextField) e.getComponent()).selectAll();
          }
        });
      }
    });

    /* create and show test frame */
    final JPanel contentPane = new JPanel(new BorderLayout(6, 6));
    contentPane.add(ftf);
    contentPane.add(new JButton("Dummy"), BorderLayout.SOUTH);

    final JFrame f = new JFrame("Test Frame: FormattedTextFieldTestGui");
    f.setContentPane(contentPane);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setVisible(true);
  }

  /** @param args ignored */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

      public void run() {
        createAndShowGui();
      }
    });
  }
}
```
Ebenius


----------



## forrest (28. Apr 2010)

Hallo Ebenius,

mit Deinem Code kann man allerdings auch nicht etwa eine 75 eingeben und direkt eine 7,5 ausgeben lassen. Mit dem Formatter wird am Ende nur eine Dezimalzahl mit angehängten Nullen (75,00) dargestellt. Das ist ja nicht das, was ich haben möchte.

Grüße,
Forrest


----------



## Gast2 (28. Apr 2010)

Dann schreib dir ein eigener NumberFormatter.... 

```
NumberFormatter numberFormatter = new NumberFormatter(){
			@Override
			public String valueToString(Object value) throws ParseException {
				// TODO Auto-generated method stub
				return super.valueToString(value);
			}
			@Override
			public Object stringToValue(String text) throws ParseException {
				// TODO Auto-generated method stub
				return super.stringToValue(text);
			}
		};
```


----------



## Gast2 (28. Apr 2010)

Sowas hier... Ist auf die schnelle gemacht kannst ja deinen Bedürfnissen anpassen.


```
DecimalFormat decimalFormat = new DecimalFormat();
		decimalFormat.setMaximumFractionDigits(2);
		NumberFormatter numberFormatter = new NumberFormatter(decimalFormat){
			@Override
			public String valueToString(Object value) throws ParseException {
				if(!getAllowsInvalid() && value != null){
					
					Number number = (Number) value;
					if(number.doubleValue() > 10){
						value = Double.valueOf(number.doubleValue() / 10);
					}
				}
				return super.valueToString(value);
			}
			@Override
			public Object stringToValue(String text) throws ParseException {
				if(text.isEmpty()){
					return null;
				}
				return super.stringToValue(text);
			}
		};
		numberFormatter.setAllowsInvalid(false);
```


----------



## Ebenius (28. Apr 2010)

forrest hat gesagt.:


> mit Deinem Code kann man allerdings auch nicht etwa eine 75 eingeben und direkt eine 7,5 ausgeben lassen.


Da liest man's schon zweimal und versteht die Anforderung trotzdem noch falsch. :-D

Na wenigstens hab ich mal gezeigt, wie die Formatter mit dem JFormattedTextField zusammen hängen, der Rest ist ja schnell selber implementiert.

Ebenius


----------



## forrest (28. Apr 2010)

Ebenius hat gesagt.:


> Na wenigstens hab ich mal gezeigt, wie die Formatter mit dem JFormattedTextField zusammen hängen, der Rest ist ja schnell selber implementiert.



Für Dich ist das vielleicht schnell implementiert, ich hänge leider immer noch in der Luft. An welcher Stelle kann ich jetzt die Eingabe automatisch umwandeln? Also während der Eingabe?


----------



## Gast2 (28. Apr 2010)

Lol hab ich dir doch geschickt naja...


----------



## Ebenius (28. Apr 2010)

Hier mal ein Beispiel basierend auf meinem obigen: 
	
	
	
	





```
/* (@)FormattedTextFieldTestGui.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.awt.BorderLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;

import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;

/**
 * Sample code for formatted text fields with separate display and edit
 * formatters.
 * 
 * @version $Revision$ as of $Date$
 * @author Sebastian Haufe
 * @since Playground-3.8
 */
public class FormattedTextFieldTestGui {

  /** Creates the GUI. Call on EDT, only! */
  static void createAndShowGui() {
    /* create custom number formats */
    final DecimalFormat format = new DecimalFormat("#.0");

    /* create custom formatters */
    final NumberFormatter formatter = new NumberFormatter(format) {

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

      @Override
      public Object stringToValue(String text) throws ParseException {
        final DecimalFormat df = (DecimalFormat) getFormat();
        final DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
        final char decimalSeparator = symbols.getDecimalSeparator();

        /* insert decimal separator if not contained in text */
        if (text.indexOf(decimalSeparator) == -1 && text.length() > 0) {
          text = text.replaceFirst("\\d$", decimalSeparator + "$0");
        }
        return super.stringToValue(text);
      }
    };

    /* create formatted text field with my formatters */
    final JFormattedTextField ftf = new JFormattedTextField();
    ftf.setFormatterFactory(new DefaultFormatterFactory(formatter));

    /* select all on focus gained */
    ftf.addFocusListener(new FocusAdapter() {

      @Override
      public void focusGained(final FocusEvent e) {
        SwingUtilities.invokeLater(new Runnable() {

          public void run() {
            ((JFormattedTextField) e.getComponent()).selectAll();
          }
        });
      }
    });

    /* create and show test frame */
    final JPanel contentPane = new JPanel(new BorderLayout(6, 6));
    contentPane.add(ftf);
    contentPane.add(new JButton("Dummy"), BorderLayout.SOUTH);

    final JFrame f = new JFrame("Test Frame: FormattedTextFieldTestGui");
    f.setContentPane(contentPane);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setVisible(true);
  }

  /** @param args ignored */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

      public void run() {
        createAndShowGui();
      }
    });
  }
}
```
Ebenius


----------

