Kay407
Kay407

Reputation: 13

How to make a jtextfield type from right to left

first time posting here, i hope i didnt violate any rules.. ok here goes the question.

Question: I want to make a jtextfield that writes from right to left with the default value of "0.00", when user input a number from keyboard it will change the value from the right, if the user input another number, it will push the previous input to the left and place the new input the to right side of the previous input. For example if a user types "1" on the keyboard, the jtextfield should display as "0.01", then if the user types "5", the jtextfield should display as "0.15", then if the user types "0", the jtextfield should display as "1.50" and so on..

Problem statement: The problem is my code only can input the first number, and will keep changing the 2nd decimal place number if i input more numbers. Im using Eclipse IDE and also new to Java and i apologize in advance for my lack of knowledge. Anyway, heres my code snippet.

        txtp = new JTextField();
        txtp.setText("0.00");
        String gp = txtp.getText();
        txtp.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                String[] sn1 = {"1", "2", "3", "4", "5", "6", "7", "8", "9","0"};
                //String sn1 = String.valueOf(e);
                char C = e.getKeyChar();
                    if(Character.isDigit(C) ||Character.isISOControl(C)) {
                        txtp.setText("0.0");
                    }else {
                            txtp.setEditable(false);
                        }
                    /*if((gp=="0.0"+sn1&&(Character.isDigit(C) ||Character.isISOControl(C)))){
                        txtp.setText("0."+sn1);
                        //String gp = txtp.getText();
                    }else {
                        txtp.setEditable(false);
                    }
                    else if((gp=="0.0"+sn1) && (Character.isDigit(C) ||Character.isISOControl(C))) {
                        txtp.setText("0."+sn1);
                        if(Character.isDigit(C) ||Character.isISOControl(C)) {
                        txtp.setEditable(true);
                        }else{
                        txtp.setEditable(false);
                        }
                    }
                        else{
                        txtp.setEditable(false);
                        }   
                    switch (gp) {
                    case "":
                        txtp.setText("0.0");
                        if(Character.isDigit(C) ||Character.isISOControl(C)) {
                            txtp.setText("0.0");
                        }else{
                            txtp.setEditable(false);
                        }
                        break;
                    case "0.01":
                        txtp.setText("0.1");
                        if(Character.isDigit(C) ||Character.isISOControl(C)) {
                            txtp.setText("0.1");
                        }else{
                            txtp.setEditable(false);
                        }
                        break;
                        
                    }*/
                            
            }
        });

Upvotes: 1

Views: 203

Answers (1)

matt
matt

Reputation: 12346

I did it using a DocumentFilter as suggested. I had to make it only take in or remove one character at a time.

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

public class TextFielding{

    static class EndFilter extends DocumentFilter{
      
        @Override
        public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException{
            replace(fb, offset, 0, string, attr);
        }
        public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException{
            if(length > 1) return;
            
            Document d = fb.getDocument();
            int docLength = d.getLength();
            
            String left = docLength == 4 ? "0" : d.getText(0, docLength - 4);
            String shiftl = d.getText(docLength -4, 1);
            String shiftr = d.getText(docLength - 2, 1);
            String result = left + "." + shiftl + shiftr;
            super.replace(fb, 0, docLength, result, null);
            
        }
        
        @Override
        public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException{
            if(length > 0 || text.length() != 1 || !Character.isDigit( text.charAt(0) ) ){
                return;
            }
            
            Document d = fb.getDocument();
            int docLength = d.getLength();
            
            //build the string.
            String left = d.getText( 0, docLength - 3);
            if( left.equals("0") ) left = "";
            String crossing = d.getText( docLength - 2, 1);
            String shift = d.getText( docLength -1, 1);
            String result = left + crossing + "." + shift + text;
            super.replace(fb, 0, docLength, result, attrs);
        }
    
    }

    public static void main(String[] args){
        JFrame frame = new JFrame("text field");
        JTextField field = new JTextField(10);
        
        field.setHorizontalAlignment( JTextField.RIGHT );
        field.setText("0.00");
        ((AbstractDocument)field.getDocument()).setDocumentFilter(new EndFilter());
        
        frame.add(field);
        
        
        
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

I assumed that if more than 3 numbers are entered, then it should always keep 2 decimal places.

When a character is removed it shifts all of the characters to the right across the decimal point. If the last character on the left is empty, it a 0 is shifted in.

When a character is typed it needs to be one character, and it cannot be replacing any characters, and it needs to be a digit. Then it is appended on the right shifting all of the characters to the left across the decimal point.

This should serve as a template because if it doesn't correcting guess the format, it shows how to receive the input, modify it and modify the corresponding document.

Upvotes: 1

Related Questions