Question

j'ai demandé qui était le meilleur composant Swing pour lier à une variable BigDecimal (avec certaines propriétés particulières d'édition). Il se trouve qu'aucun des composants standard Swing me convient tout à fait, ni ne les tiers bibliothèques de composants Swing que j'ai trouvé là-bas. J'ai donc décidé de créer mon propre composant Swing.

Description du composant:

Je veux étendre JTextField ou JFormattedTextField , donc mon nouveau composant peut être facilement lié à une BigDecimal variable.

Le composant sera personnalisable échelle et longueur propriétés.

Comportement:

Lorsque le composant est tracé, il ne montre que la virgule et l'espace pour échelle chiffres à son droit.

Lorsque le composant reçoit le focus du caret doit être placé à gauche à la virgule. Comme le nombre de types d'utilisateurs (tout autre caractère est ignoré), ils apparaissent à gauche du caret, que longueur - échelle chiffres sont acceptés, tout autre numéro tapé est ignora la partie entière est pleine. Chaque fois que le type d'utilisateur le point décimal des Moves carets sur le côté droit de la virgule. Les numéros suivants tapées sont présentés dans la partie décimale, seuls les numéros échelle sont considérés comme un autre numéro tapé est ignoré comme la partie décimale est pleine. De plus, les séparateurs de milliers doivent apparaître comme les numéros de types d'utilisateurs laissés à la virgule.

Je veux aussi être en mesure d'utiliser le composant comme éditeur de cellules dans JTable (sans avoir à coder deux fois).

invocation d'une méthode getValue () sur le composant devrait donner le BigDecimal représentant le nombre vient d'entrer.


Je ne l'ai jamais créé mon propre composant Swing; Je l'ai à peine utilisé les standards. Donc, je vous serais reconnaissant de tout bon tutoriel / info / astuce sur la création du composant décrit. Cette est la seule chose que je « ai jusqu'à présent.

Merci d'avance.

Était-ce utile?

La solution

J'aime Grouchnikov l'article que vous avez cité, mais je ne suis pas sûr que vous voulez changer le délégué de l'interface utilisateur. Comme ce sera une vue d'un objet immuable, je préfère la composition de l'héritage. Je tends à penser du composant que vous décrivez en termes d'être un renderer, comme on le voit dans cette . Vous pouvez ajouter un InputVerifier ou DocumwntListener pour obtenir la validation que vous voulez.

Addendum: Voici un exemple qui utilise JFormattedTextField et MaskFormatter . Vous devrez ajuster le masque de format pour correspondre à votre échelle et la longueur.

public class TableGrid extends JPanel {

    private DecimalFormat df;
    private MaskFormatter mf;
    private JFormattedTextField tf;

    public TableGrid() {
        df = new DecimalFormat("0.00");
        try {
            mf = new MaskFormatter("#.##");
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        tf = new JFormattedTextField(mf);
        TableModel dataModel = new TableModel();
        JTable table = new JTable(dataModel);
        table.setCellSelectionEnabled(true);
        table.setRowHeight(32);
        table.setDefaultRenderer(BigDecimal.class, new DecRenderer(df));
        table.setDefaultEditor(BigDecimal.class, new DecEditor(tf, df));
        this.add(table);
    }

    private static class TableModel extends AbstractTableModel {

        private static final int SIZE = 4;
        private BigDecimal[][] matrix = new BigDecimal[SIZE][SIZE];

        public TableModel() {
            for (Object[] row : matrix) {
                Arrays.fill(row, BigDecimal.valueOf(0));
            }
        }

        @Override
        public int getRowCount() {
            return SIZE;
        }

        @Override
        public int getColumnCount() {
            return SIZE;
        }

        @Override
        public Object getValueAt(int row, int col) {
            return matrix[row][col];
        }

        @Override
        public void setValueAt(Object value, int row, int col) {
            matrix[row][col] = (BigDecimal) value;
        }

        @Override
        public Class<?> getColumnClass(int col) {
            return BigDecimal.class;
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            return true;
        }
    }

    private static class DecRenderer extends DefaultTableCellRenderer {

        DecimalFormat df;

        public DecRenderer(DecimalFormat df) {
            this.df = df;
            this.setHorizontalAlignment(JLabel.CENTER);
            this.setBackground(Color.lightGray);
            this.df.setParseBigDecimal(true);
        }

        @Override
        protected void setValue(Object value) {
            setText((value == null) ? "" : df.format(value));
        }
    }

    private static class DecEditor extends DefaultCellEditor {

        private JFormattedTextField tf;
        private DecimalFormat df;

        public DecEditor(JFormattedTextField tf, DecimalFormat df) {
            super(tf);
            this.tf = tf;
            this.df = df;
            tf.setHorizontalAlignment(JFormattedTextField.CENTER);
        }

        @Override
        public Object getCellEditorValue() {
            try {
                return new BigDecimal(tf.getText());
            } catch (NumberFormatException e) {
                return BigDecimal.valueOf(0);
            }
        }

        @Override
        public Component getTableCellEditorComponent(JTable table,
            Object value, boolean isSelected, int row, int column) {
            tf.setText((value == null) ? "" : df.format((BigDecimal) value));
            if (isSelected) tf.selectAll();
            return tf;
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("TableGrid");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.add(new TableGrid());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

Autres conseils

Utilisez ce composant que vous aimez et enregistrer un KeyListener de rejeter les caractères pour correspondre à votre behaviour.Add un getValue () et setValue pour obtenir / mettre facilement un BiDecimal et d'autres méthodes et toute la peinture sera fournie par toute JTextComponent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top