Dezimal- und InputVerifier/FocusListener Probleme

charcoal

Neues Mitglied
Hallo zusammen!
Ich habe ein, vermutlich eigtl. leicht zu behebendes, Problem bei dem ich einfach nicht auf den Fehler komme.
In 2 Textfelder sollen Zahlen eingeben werden können (Dezimalstellen mit "."), die dann mit einer 3. Zahl aus einer JComboBox verrechnet werden.
Beide Textfelder dienen sowohl zur Eingabe als auch Ergebnislieferung.

Problem:
Geht ein eingegebener Wert in einem der Textfelder > 100.00 kommt ein solches Ergebnis heraus:

6.41.71

anstatt

641.71
Java:
        double unteresTextField= (number3 * 100 / number1);
        // Hier wird das Ergebnis gekürzt auf 2 Nachkommastellen
        DecimalFormat df = new DecimalFormat("##,##");
        String ausgabeKurz = df.format(ausgabePreis);

        this.oberesTextField.setText(" " + ausgabeKurz);

        if (achtungLabel != null) {
            this.achtungLabel.setText("");
        }
Problem 2:
Ein Textfeld soll mit einem InputVerifier die richtige Eingabe der Zahl prüfen.
Aber eingetippte, syntaktisch richtige Werte (10, 10.00 etc) werden nicht angenommen. Es erscheint nur die Fehlermeldung.
Java:
private void preisFlascheInputVerifier(java.awt.event.FocusEvent evt) {                                           
    InputVerifier verifier = new InputVerifier() {

        public boolean verify(JComponent number2) {
            final JTextComponent source = (JTextComponent) number2;
            String preisFlascheText = source.getText();
            if ((preisFlascheText.length() != 0) && !(preisFlascheText.equals(source))) {
                JOptionPane.showMessageDialog(null,
                        "Bitte im Feld Flaschenpreis eine (zweistellige) Dezimalzahl eintragen.",
                        "Fehler", JOptionPane.ERROR_MESSAGE);
                ((JTextComponent) number2).requestFocusInWindow();
                return false;
            } else {
                return true;
            }
        }
    };
    preisFlascheText.setInputVerifier(verifier);
}
Problem 3:
Das zweite Textfeld soll hingegen mit einem FocusListener auf richtige Eingabe geprüft werden. Bei ungültiger Eingabe erzeugt sich die Fehlermeldung aber 3x.
Java:
private void preisLiterFocusLost(java.awt.event.FocusEvent evt) {                                     
   
    ausgabeText.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
            }
        });
        if (!(ausgabeText instanceof JTextComponent)) {
            return;
        }
        double number3 = new Double(0.0);
        String inhalt = ((JTextComponent) ausgabeText).getText();
        try {
            number3 = (Double.parseDouble(inhalt));
        } 
 catch (Exception e) {
            if (inhalt.equals(ausgabeText))  {
            return;
        }else
      //     if (ausgabeText.getText().length() > 0)

           {
            JOptionPane.showMessageDialog(null,
                    "Bitte im Literpreis eine (zweistellige) Dezimalzahl eingeben.",
                    "Fehler", JOptionPane.ERROR_MESSAGE);
            ((JTextComponent) ausgabeText).requestFocusInWindow();
   }}
}

Vielen Dank im Voraus für Anregungen und Hilfe.
 
1.
versuche ###,##
2.
sieht ziemlich passend zum Quellcode aus, der unter anderem einen Aufruf String.equals(JTextArea) enthält?
was soll der Code denn machen?, also Zeile für Zeile, nicht nur im Endergebnis 'soll funktionieren'

3.
was macht
Java:
   ausgabeText.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
            }
        });
denn?
kann bei solchen Code angenommen werden, dass wer immer preisLiterFocusLost() aufruft vielleicht auch fälschlicherweise
3x als Listener geadded ist? ein vollständiges Testprogramm wäre da angebracht
 
1. versuche ###,##
Das habe ich bereits. Leider völlig ohne Erfolg. Überschreitet das Ergebnis die Größe von ##,## wird es als #.##.## geschrieben.
ein vollständiges Testprogramm wäre da angebracht
Ich werde es mal vollständig einfügen. Ich bin sicher, es sind furchtbar plumpe Fehler, aber irgendwann sieht man den Wald vor lauter Bäumen nicht mehr.
Java:
import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.text.DecimalFormat;
import java.util.regex.Pattern;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;

public class Preisumrechner extends javax.swing.JFrame {

    /** Creates new form Preisumrechner */
    public Preisumrechner() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        preisFlascheText = new javax.swing.JTextField();
        groeßeBox = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        ausgabeText = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        literButton = new javax.swing.JButton();
        preisButton = new javax.swing.JButton();
        achtungLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Preisumrechner");

        preisFlascheText.setToolTipText("Geben Sie den Flaschenpreis ein");
        preisFlascheText.setNextFocusableComponent(literButton);
        preisFlascheText.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                preisFlascheTextFocusGained(evt);
                preisFlascheInputVerifier(evt);
            }
        });
        preisFlascheText.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                preisFlascheTextKeyTyped(evt);
            }
        });

        groeßeBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0.187", "0.25", "0.375", "0.5", "0.62", "0.7", "0.75", "0.8", "1.0", "1.5" }));
        groeßeBox.setToolTipText("Wählen Sie die Flaschengröße");
        groeßeBox.setActionCommand("groeßeBoxFilled");
        groeßeBox.setNextFocusableComponent(preisFlascheText);
        groeßeBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                FlaschenGroeßeChangedHandler(evt);
            }
        });

        jLabel1.setText("Flaschengröße");

        jLabel2.setText("Flaschenpreis");

        jLabel3.setText("€");

        jLabel4.setText("Preis pro l");

        jLabel5.setText("€");

        ausgabeText.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                PreisProLiterHandler(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                preisLiterFocusLost(evt);
            }
        });
        ausgabeText.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                PreisProLiterTyped(evt);
            }
        });

        jLabel6.setText("in l");

        literButton.setText("v");
        literButton.setToolTipText("Literpreis ausgeben");
        literButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                literButtonActionPerformed(evt);
            }
        });

        preisButton.setText("^");
        preisButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                preisButtonActionPerformed(evt);
            }
        });

        achtungLabel.setFont(new java.awt.Font("Tahoma", 2, 11));
        achtungLabel.setForeground(new java.awt.Color(102, 153, 255));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(60, 60, 60)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(jLabel4)
                                .addComponent(jLabel2)))
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(77, 77, 77)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(preisFlascheText, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 83, Short.MAX_VALUE)
                                    .addComponent(groeßeBox, 0, 83, Short.MAX_VALUE)))
                            .addGroup(layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(ausgabeText, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 126, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(literButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(22, 22, 22)
                        .addComponent(preisButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel6)
                        .addGap(38, 38, 38))
                    .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addContainerGap(45, javax.swing.GroupLayout.PREFERRED_SIZE))))
            .addGroup(layout.createSequentialGroup()
                .addGap(26, 26, 26)
                .addComponent(achtungLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE)
                .addGap(185, 185, 185))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(38, 38, 38)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(groeßeBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(preisFlascheText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(literButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(preisButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(jLabel5)
                    .addComponent(ausgabeText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(achtungLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void literButtonActionPerformed(java.awt.event.ActionEvent evt) {                                            
        double number1;
        double number2;

        try {
            number1 = Double.parseDouble(this.groeßeBox.getSelectedItem().toString());
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Bitte wählen Sie eine Flaschengröße.", "Fehlerhafte Eingabe", JOptionPane.ERROR_MESSAGE);
            return;
        }
        try {
            number2 = Double.parseDouble(
                    this.preisFlascheText.getText());
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Bitte geben Sie den Flaschenpreis ein.", "Fehlerhafte Eingabe", JOptionPane.ERROR_MESSAGE);
            //preisFlascheText.setCaretPosition( preisFlascheText.getText().length());
            //preisFlascheText.selectAll();

            return;
        }
        double ausgabe = (number2 * 100 / number1);
        // Hier wird das Ergebnis gekürzt auf 2 Nachkommastellen  
        DecimalFormat df = new DecimalFormat("##,##");
        String ausgabeKurz = df.format(ausgabe);
        this.ausgabeText.setText(" " + ausgabeKurz);

        if (achtungLabel != null) {
            this.achtungLabel.setText("");
        }

    }                                           

    private void preisFlascheTextFocusGained(java.awt.event.FocusEvent evt) {                                             
        if (preisFlascheText != null) {
            preisFlascheText.setBackground(Color.WHITE);
        }
        preisFlascheText = (JTextField) evt.getSource();
        preisFlascheText.setSelectionStart(0);
        preisFlascheText.setSelectionEnd(preisFlascheText.getText().length());

    }                                            

    private void preisButtonActionPerformed(java.awt.event.ActionEvent evt) {                                            
        double number1;
        double number3;

        try {
            number1 = Double.parseDouble(this.groeßeBox.getSelectedItem().toString());
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Bitte geben Sie einen Flaschenpreis ein.", "Fehlerhafte Eingabe", JOptionPane.ERROR_MESSAGE);
            return;
        }
        try {
            number3 = Double.parseDouble(this.ausgabeText.getText());
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Bitte geben Sie den Literpreis ein.", "Fehlerhafte Eingabe", JOptionPane.ERROR_MESSAGE);
            //ausgabeText.setCaretPosition( ausgabeText.getText().length() );
            return;
        }
        double ausgabePreis = (number3 * 100 / number1);
        // Hier wird das Ergebnis gekürzt auf 2 Nachkommastellen
        DecimalFormat df = new DecimalFormat("##,##");
        String ausgabeKurzPreis = df.format(ausgabePreis);

        this.preisFlascheText.setText(" " + ausgabeKurzPreis);

        if (achtungLabel != null) {
            this.achtungLabel.setText("");
        }
    }                                           

    private void PreisProLiterTyped(java.awt.event.KeyEvent evt) {                                    

        preisFlascheText.setText(" ");
        Character number3 = evt.getKeyChar();
        if (!((Character.isDigit(number3)
                || (number3 == KeyEvent.VK_BACK_SPACE)
                || (number3 == KeyEvent.VK_PERIOD)
                || (number3 == KeyEvent.VK_COMMA)
                || (number3 == KeyEvent.VK_DELETE)))) {
            getToolkit().beep();
            evt.consume();
        }
    }                                   

    private void preisFlascheTextKeyTyped(java.awt.event.KeyEvent evt) {                                          

        ausgabeText.setText(" ");
        Character number2 = evt.getKeyChar();
        if (!((Character.isDigit(number2)
                || (number2 == KeyEvent.VK_BACK_SPACE)
                || (number2 == KeyEvent.VK_PERIOD)
                || (number2 == KeyEvent.VK_COMMA)
                || (number2 == KeyEvent.VK_DELETE)))) {
            getToolkit().beep();
            evt.consume();
        }
    }                                         

    private void PreisProLiterHandler(java.awt.event.FocusEvent evt) {                                      
        if (ausgabeText != null) {
            ausgabeText.setBackground(Color.WHITE);
        }
        ausgabeText = (JTextField) evt.getSource();
        ausgabeText.setSelectionStart(0);
        ausgabeText.setSelectionEnd(preisFlascheText.getText().length());
    }                                     

    private void FlaschenGroeßeChangedHandler(java.awt.event.ItemEvent evt) {                                              
        if (preisFlascheText != null) {
            groeßeBox.getAction();
        }
        this.achtungLabel.setText("Achtung: Neuberechnung nötig!");

        if (ausgabeText != null) {
            groeßeBox.getAction();
        }
        achtungLabel.setText("Achtung: Neuberechnung nötig!");
    }                                             

private void preisFlascheInputVerifier(java.awt.event.FocusEvent evt) {                                           

        InputVerifier verifier = new InputVerifier() {
        public boolean verify(JComponent number2) {
            final JTextComponent source = (JTextComponent) number2;
            String preisFlascheText = source.getText();
            if ((preisFlascheText.length() != 0) && !(preisFlascheText.equals(source))) {
                JOptionPane.showMessageDialog(null,
                        "Bitte im Feld Flaschenpreis eine (zweistellige) Dezimalzahl eintragen.",
                        "Fehler", JOptionPane.ERROR_MESSAGE);
                ((JTextComponent) number2).requestFocusInWindow();
                return false;
            } else {
                return true;
            }
        }
    };
    preisFlascheText.setInputVerifier(verifier);
}                                          

private void preisLiterFocusLost(java.awt.event.FocusEvent evt) {                                     
  
    ausgabeText.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
            }
        });
        if (!(ausgabeText instanceof JTextComponent)) {
            return;
        }
        double number3 = new Double(0.0);
        String inhalt = ((JTextComponent) ausgabeText).getText();
        try {
            number3 = (Double.parseDouble(inhalt));
        } 
 catch (Exception e) {
            if (inhalt.equals(ausgabeText))  {
            return;
        }else
      //     if (ausgabeText.getText().length() > 0)
           {
            JOptionPane.showMessageDialog(null,
                    "Bitte im Literpreis eine (zweistellige) Dezimalzahl eingeben.",
                    "Fehler", JOptionPane.ERROR_MESSAGE);
            ((JTextComponent) ausgabeText).requestFocusInWindow();
   }}
}                                    
public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Preisumrechner().setVisible(true);
} 
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JLabel achtungLabel;
    private javax.swing.JTextField ausgabeText;
    private javax.swing.JComboBox groeßeBox;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JButton literButton;
    private javax.swing.JButton preisButton;
    private javax.swing.JTextField preisFlascheText;
    // End of variables declaration                   
}
 
wann lernt nur die Menschheit, dass 500.000 Zeilen Code a la
Java:
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(77, 77, 77)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(preisFlascheText, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 83, Short.MAX_VALUE)
                                    .addComponent(groeßeBox, 0, 83, Short.MAX_VALUE)))
                            .addGroup(layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(ausgabeText, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 126, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(literButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(22, 22, 22)
                        .addComponent(preisButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
NICHT sinnvoll sind..,

unendlich unlesbar und vor allem in Java 1.5 nicht kompilierbar..
Java:
        setLayout(new FlowLayout());
        add(preisFlascheText);
        add(groeßeBox);
        add(jLabel1);
        add(jLabel2);
        add(jLabel3);
        add(jLabel4);
        add(jLabel5);
        add(ausgabeText);
        add(jLabel6);
        add(literButton);
        add(preisButton);
        add(achtungLabel);
tut es doch auch, wenn mann noch den Textfeldern eine Mindestbreite gibt (Parameter im Konstruktor),
welch im Vergleich einfacher Code..

-----

###.##
ist das Pattern,
ob deutsche oder englische Dezimaltrenner entscheiden andere Dinge wie Locale, falls noch wichtig

-----

bei 3. wird im FocusLost-Listener nochmal den Focus für dieselbe Komponente angefordert?
> ((JTextComponent) ausgabeText).requestFocusInWindow();
einerseits verständliches Feature, aber auf diese Weise in die Blackbox Swing einzugreifen kann eben zu Fehlern führen,
noch fällt mit dazu nichts ein um den Focus zurückzuerlangen ohne weitere Fehlermeldungen,
evtl. denke ich darüber nach
 

Zurück
Oben