Walidacja JComboBox

0

Znalazłem na forum poniższą formę walidacji JTextFielda:

class NumberDocument extends PlainDocument{
        private static final long serialVersionUID = 1L;

        public void insertString(int position, String string, AttributeSet a) throws BadLocationException{
                if(string == null) return;
                if(isValid(string))
                        super.insertString(position, string, a);
        }

        public static boolean isValid(String string){
                try{
                        Integer.parseInt(string);
                        return true;}
                catch(NumberFormatException e){
                        return false;}
        }
}

class NumberField extends JTextField{
        private static final long serialVersionUID = 1L;
       
        public NumberField(int defaultValue){
                super(String.valueOf(defaultValue));}
       
        protected Document createDefaultModel(){
                return new NumberDocument();}
}

Działa ona na zasadzie widok -> sterownik -> model. Każdy komponent ma swój sterownik i zanim modyfikacje wykonane w modelu pojawią się w widoku można je wychwycić w sterowniku (tu PlainDocument). Jak to jednak zrobić w JComboBoxie ? Nie chce tego robić w tak naciągany sposób jak jest to proponowane przy użyciu InputVerifiera. Chciałbym w edytowalnym JComboBoxie zrobić taką walidację, która zwyczajnie uniemożliwia stworzenie błędnego łańcucha już w trakcie próby jego napisania.

0

możesz zrobić coś takiego

JComboBox box = new JComboBox();
box.setEditor(new NumberComboBoxEditor());
box.setEditable(true);
class NumberComboBoxEditor extends MetalComboBoxEditor {

    public NumberComboBoxEditor() {
        editor.setDocument(new NumberDocument());
    }
}

albo w ogóle wyłączyć edycje w ComboBox

box.setEditable(false);
0

Właśnie o setDocument mi chodziło, ale o ile pamiętam nie znalazłem metody, która odpowiadałaby za tworzenie defaultowego documentu. No tak, można sobie ustawić ręcznie:

((JTextComponent)validateComboBox.getEditor().getEditorComponent()).setDocument(new NumberDocument());
0

Zrobiłem tą walidację na powyższej zasadzie. Ale inny rodzaj wzorca. Do JComboBoxa ładuje nazwy dwuczłonowe jak np. "Jeden Dwa", "Pierwszy Drugi", itd. Więc w danej chwili naturalne działanie ComboBoxa polega na tym, że w momencie wyboru jakiegokolwiek elementu nie pojawia się nic, bo wzorzec nie akceptuje białych znaków, więc "Jeden Dwa" nie przejdzie. ComboBox pojawia się w 2óch miejscach - bezpośrednio na JPanelu i w innym miejscu jako komórki jednej z kolumn w JTable. Dwa człony każdego z elementów w JComboBox niezbędne są jako informacja, ale podczas wyboru chcę, żeby pojawiał się tylko ten drugi - dodałem więc ActionListenera:

validateComboBox.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				String name = (String)((JComboBox)e.getSource()).getSelectedItem();
				((JComboBox)e.getSource()).setSelectedItem( name.substring(name.indexOf(" ") + 1, name.length()) );
			}
		});

Kod wewnątrz działa tak, że podczas wyboru elementu jest on przechwytywany (co następuje zanim przejdzie walidacja i pojawi się jako element wybrany) i wycinany jest pierwszy człon - więc przy wyborzu elementu "Jeden Dwa" wyświetlony zostanie element "Dwa". I tak to działa w ComboBoxie w JPanlu, ale w JTable już nie. W momencie wyboru elementu pobierając go ze źródła (e.getSource()) dostaje element "". Zmieniłem elementy na jednoczłonowe i jest ok. Wychodzi więc na to, że walidacja przechodzi przed wyborem elementu - wygląda to tak, jak by był wstawiany element przed jego wyborem. Bo w menu kontekstowym każdego JComboBoxa w JTable elementy się pojawiają, ale już przy wyborze nie. Jak w takim razie umożliwić takie działanie JComboBoxa w JTable jakie jest na JPanelu ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1