Benutzerdefinierte Klasse UserComboBox reagiert nicht wie gewollt

Madebuvie

Mitglied
Hallo zusammen,
ich bin gerade dabei ein eigenes Widget für eine ComboBox zu erstellen, die eine mehrzeilige
Liste enthält.
Es besteht aus einem Label, einem JtextField und einem JButton, der rechts neben dem JTextField ein kleines schwarzes Dreieck enthält.

Die ComboBox sollte sich wie folgt verhalten:

1) Beim Anklicken des Buttons soll sich die Liste öffnen und die Liste soll den Fokus erhalten.
2) Wenn man mit der Maus irgendwo anders hinklickt (ausser in das JTextField), als in der Liste,
so geht der Fokus verloren und die Liste soll sich schließen.
3) Bewegt man sich in der Liste, so soll die Liste geöffnet bleiben.
4) Gibt man in die JtextBox etwas ein, so soll ebenfalls die Liste geöffnet werden und die Eingaben
entgegennehmen (z.B. um Werte für die Autovervollständigung zu realisieren).

Punkt 1 Funktioniert
Punkt 2 Funktioniert generell auch, jedoch schliesst sich die Liste auch wenn ich auf das JtextField klicke um dort Werte einzugeben.
Punkt 3 Funktioniert
Punkt 4 Wenn ich in das JTextField etwas eingebe, dann öffnet sich die Liste und der Wert wird übernommen. Danach hat die Liste den Fokus
und ich kann keine weiteren Zeichen eingeben. Wähle ich das JtextField erneut auwähle, so schließt sich die Liste wieder, da sie den Fokus
wieder verloren hat.

Hat jeman eine Idee, wie ich bei dem Event windowLostFocus(WindowEvent e) beibringe, daß es überall außer bei dem JtextField reagieren
soll?

Hier der Code für das Widget

Java:
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class UserComboBox extends JComponent {

    private static final long serialVersionUID = 1L;
    private JTextField fldEingabe;
    private JPanel comboPanel;
    private JLabel lblEingabe;
    private String strCombo;
    private JButton btnShowList;
    private JDialog popUp;

    final static boolean shouldFill = true;
    final static boolean shouldWeightX = true;
    final static boolean RIGHT_TO_LEFT = false;

    private GridBagConstraints c;
    private GridBagConstraints lblEingabeC;
    private GridBagConstraints fldEingabeC;
    private GridBagConstraints btnShowListC;

    private JTable tblDatenHerkunft;
    private TableColumnModel tableColumnModel;
    private JScrollPane scrollPane;
    private JButton f;
    private Point point;
    private DefaultTableModel defaultTableModel;
    private int listenhoehe;

    public UserComboBox(String strCombo, DefaultTableModel defaultTableModel) {
        super();
        this.setStrCombo(strCombo);
        this.setDefaultTableModel(defaultTableModel);
        this.setListenhoehe(listenhoehe);
        createWidgets();
        addWidgets();
        setupInteractions();

    }

    private void createWidgets() {

        if (tblDatenHerkunft == null) {
            tblDatenHerkunft = new JTable();
        }

        tblDatenHerkunft.setModel(defaultTableModel);
        if (tableColumnModel == null) {
            tableColumnModel = tblDatenHerkunft.getColumnModel();
        }

        if (scrollPane == null) {
            scrollPane = new JScrollPane(tblDatenHerkunft);
        }

        this.setLblEingabe(new JLabel(strCombo));
        this.getLblEingabe().setFont(this.getLblEingabe().getFont().deriveFont(Font.BOLD, 16));
        this.getLblEingabe().setMinimumSize(new Dimension(50, 20));
        this.getLblEingabe().setPreferredSize(new Dimension(80, 20));

        this.setLblEingabeC(new GridBagConstraints());
        this.getLblEingabeC().fill = GridBagConstraints.HORIZONTAL;

        this.setFldEingabe(new JTextField());

        this.getFldEingabe().setMinimumSize(new Dimension(100, 20));
        this.getFldEingabe().setPreferredSize(new Dimension(380, 20));

        this.getFldEingabe().setBackground(Color.ORANGE);
        this.setFldEingabeC(new GridBagConstraints());
        this.getFldEingabeC().fill = GridBagConstraints.HORIZONTAL;

        this.setBtnShowList(new JButton());

        Image img = null;
        try {
            img = ImageIO.read(getClass().getResource("/pfeilNachUnten.png"));
        } catch (IOException e) {
        }
        Image newimg = img.getScaledInstance(10, 10, java.awt.Image.SCALE_SMOOTH);
        ImageIcon icon = new ImageIcon(newimg);
        this.getBtnShowList().setIcon(icon);

        this.getBtnShowList().setEnabled(true);
        this.getBtnShowList().setMinimumSize(new Dimension(20, 20));
        this.getBtnShowList().setPreferredSize(new Dimension(20, 20));

        this.setBtnShowListC(new GridBagConstraints());
        this.getBtnShowListC().fill = GridBagConstraints.HORIZONTAL;

        this.setListenhoehe(110);

        this.setLayout(new GridBagLayout());
        c = new GridBagConstraints();

        if (popUp == null) {
            popUp = new JDialog();
        }

        popUp.setUndecorated(true);
        popUp.setSize(new Dimension(380, this.getListenhoehe()));
        popUp.setLayout(new GridLayout(1, 1));
        popUp.add(scrollPane);

        popUp.setVisible(false);
        popUp.setModal(false);
        popUp.setAlwaysOnTop(false);

        popUp.addWindowFocusListener(new WindowFocusListener() {

            public void windowGainedFocus(WindowEvent e) {
                // mache nichts!
            }

            public void windowLostFocus(WindowEvent e) {
                popUp.setModal(false);
                popUp.setAlwaysOnTop(false);
                popUp.setVisible(false);

            }

        });
    }

    private void addWidgets() {

        this.getLblEingabeC().gridx = 0;
        this.getLblEingabeC().gridy = 0;
        this.add(this.getLblEingabe(), this.getLblEingabeC());

        this.getFldEingabeC().gridx = 0;
        this.getFldEingabeC().gridy = 1;
        this.add(this.getFldEingabe(), this.getFldEingabeC());

        this.getBtnShowListC().gridx = 1;
        this.getBtnShowListC().gridy = 1;
        this.add(this.getBtnShowList(), this.getBtnShowListC());

    }

    private void setupInteractions() {
        this.getBtnShowList().addActionListener(new ActionCombo(this.getFldEingabe()));
        this.getFldEingabe().getDocument().addDocumentListener(new ActionComboEntry(this.getFldEingabe()));
    }

// Getter & Setter
    public JTextField getFldEingabe() {
        return fldEingabe;
    }

    public void setFldEingabe(JTextField fldEingabe) {
        this.fldEingabe = fldEingabe;
    }

    public JPanel getComboPanel() {
        return comboPanel;
    }

    public void setComboPanel(JPanel comboPanel) {
        this.comboPanel = comboPanel;
    }

    public JLabel getLblEingabe() {
        return lblEingabe;
    }

    public void setLblEingabe(JLabel lblEingabe) {
        this.lblEingabe = lblEingabe;
    }

    public String getStrCombo() {
        return strCombo;
    }

    public void setStrCombo(String strCombo) {
        this.strCombo = strCombo;
    }

    public JButton getBtnShowList() {
        return btnShowList;
    }

    public void setBtnShowList(JButton btnShowList) {
        this.btnShowList = btnShowList;
    }

    public GridBagConstraints getLblEingabeC() {
        return lblEingabeC;
    }

    public void setLblEingabeC(GridBagConstraints lblEingabeC) {
        this.lblEingabeC = lblEingabeC;
    }

    public GridBagConstraints getFldEingabeC() {
        return fldEingabeC;
    }

    public void setFldEingabeC(GridBagConstraints fldEingabeC) {
        this.fldEingabeC = fldEingabeC;
    }

    public GridBagConstraints getBtnShowListC() {
        return btnShowListC;
    }

    public void setBtnShowListC(GridBagConstraints btnShowListC) {
        this.btnShowListC = btnShowListC;
    }

    public JTable getTblDatenHerkunft() {
        return tblDatenHerkunft;
    }

    public void setTblDatenHerkunft(JTable tblDatenHerkunft) {
        this.tblDatenHerkunft = tblDatenHerkunft;
    }

    public TableColumnModel getTableColumnModel() {
        return tableColumnModel;
    }

    public void setTableColumnModel(TableColumnModel tableColumnModel) {
        this.tableColumnModel = tableColumnModel;
    }

    public DefaultTableModel getDefaultTableModel() {
        return defaultTableModel;
    }

    public void setDefaultTableModel(DefaultTableModel defaultTableModel) {
        this.defaultTableModel = defaultTableModel;
    }

    public int getListenhoehe() {
        return listenhoehe;
    }

    public void setListenhoehe(int listenhoehe) {
        this.listenhoehe = listenhoehe;
    }

    private class ActionComboEntry implements DocumentListener {

        private JTextField fldEingabe;

        private ActionComboEntry(JTextField fldEingabe) {
            super();
            this.fldEingabe = fldEingabe;

        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            System.out.println("ActionComboInsert");
            point = this.fldEingabe.getLocationOnScreen();
            popUp.setLocation(point.x, point.y + this.fldEingabe.getHeight());
            popUp.setVisible(true);
            this.fldEingabe.requestFocus();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            // TODO Auto-generated method stub

        }

    }

    public class ActionCombo implements ActionListener {

        private JTextField fldEingabe;

        public ActionCombo(JTextField fldEingabe) {
            super();
            this.fldEingabe = fldEingabe;
        }

        public void actionPerformed(ActionEvent e) {
            System.out.println("ActionCombo");
            point = this.fldEingabe.getLocationOnScreen();
            popUp.setLocation(point.x, point.y + this.fldEingabe.getHeight());
            popUp.setVisible(true);
            popUp.setModal(true);
            popUp.setAlwaysOnTop(true);
        }

    }

    public JDialog getPopUp() {
        return popUp;
    }

    public void setPopUp(JDialog popUp) {
        this.popUp = popUp;
    }

}

Über Eure Hilfe würde ich mich sehr freuen.

Viele Grüße
MaDeBuVie
 

Madebuvie

Mitglied
Hallo zusammen,
ich habe nochmal etwas ausprobiert. Mit Hilfe eines zusätzlichen JTextFields habe ich eine funktionierende Lösung hinbekommen.
Vielleicht hat jemand noch eine elegantere Lösung.
Java:
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class UserComboBox extends JComponent {

    private static final long serialVersionUID = 1L;
    private JTextField fldEingabe;
    private JTextField fldFilterFeld;
    private JPanel comboPanel;
    private JLabel lblEingabe;
    private String strCombo;
    private JButton btnShowList;
    private JDialog popUp;

    final static boolean shouldFill = true;
    final static boolean shouldWeightX = true;
    final static boolean RIGHT_TO_LEFT = false;

    private GridBagConstraints c;
    private GridBagConstraints d;
    private GridBagConstraints lblEingabeC;
    private GridBagConstraints fldEingabeC;
    private GridBagConstraints btnShowListC;

    private JTable tblDatenHerkunft;
    private TableColumnModel tableColumnModel;
    private JScrollPane scrollPane;
    private JButton f;
    private Point point;
    private DefaultTableModel defaultTableModel;
    private int listenhoehe;

    public UserComboBox(String strCombo, DefaultTableModel defaultTableModel) {
        super();
        this.setStrCombo(strCombo);
        this.setDefaultTableModel(defaultTableModel);
        this.setListenhoehe(listenhoehe);
        createWidgets();
        addWidgets();
        setupInteractions();

    }

    private void createWidgets() {

        if (tblDatenHerkunft == null) {
            tblDatenHerkunft = new JTable();
        }

        tblDatenHerkunft.setModel(defaultTableModel);
        if (tableColumnModel == null) {
            tableColumnModel = tblDatenHerkunft.getColumnModel();
        }

        if (scrollPane == null) {
            scrollPane = new JScrollPane(tblDatenHerkunft);
        }

        this.setLblEingabe(new JLabel(strCombo));
        this.getLblEingabe().setFont(this.getLblEingabe().getFont().deriveFont(Font.BOLD, 16));
        this.getLblEingabe().setMinimumSize(new Dimension(50, 20));
        this.getLblEingabe().setPreferredSize(new Dimension(80, 20));

        this.setLblEingabeC(new GridBagConstraints());
        this.getLblEingabeC().fill = GridBagConstraints.HORIZONTAL;

        this.setFldEingabe(new JTextField());

        this.getFldEingabe().setMinimumSize(new Dimension(100, 20));
        this.getFldEingabe().setPreferredSize(new Dimension(380, 20));

        this.getFldEingabe().setBackground(Color.ORANGE);
        this.setFldEingabeC(new GridBagConstraints());
        this.getFldEingabeC().fill = GridBagConstraints.HORIZONTAL;

        this.setBtnShowList(new JButton());

        Image img = null;
        try {
            img = ImageIO.read(getClass().getResource("/pfeilNachUnten.png"));
        } catch (IOException e) {
        }
        Image newimg = img.getScaledInstance(10, 10, java.awt.Image.SCALE_SMOOTH);
        ImageIcon icon = new ImageIcon(newimg);
        this.getBtnShowList().setIcon(icon);

        this.getBtnShowList().setEnabled(true);
        this.getBtnShowList().setMinimumSize(new Dimension(20, 20));
        this.getBtnShowList().setPreferredSize(new Dimension(20, 20));

        this.setBtnShowListC(new GridBagConstraints());
        this.getBtnShowListC().fill = GridBagConstraints.HORIZONTAL;

        this.setListenhoehe(110);

        this.setLayout(new GridBagLayout());
        c = new GridBagConstraints();

        if (popUp == null) {
            popUp = new JDialog();
        }

        this.setFldFilterFeld(new JTextField());
        this.getFldFilterFeld().setMinimumSize(new Dimension(100, 20));
        this.getFldFilterFeld().setPreferredSize(new Dimension(380, 20));
        this.getFldFilterFeld().setBackground(Color.GREEN);
                
        popUp.setUndecorated(true);
        popUp.setSize(new Dimension(380, this.getListenhoehe()));
        
        popUp.setLayout(new GridBagLayout());
        d = new GridBagConstraints();

        d.gridx = 0;
        d.gridy = 0;
        d.weightx=1.0;
        d.weighty=0;
        d.fill = GridBagConstraints.HORIZONTAL;
        popUp.add(fldFilterFeld, d);

        d.gridx = 0;
        d.gridy = 1;
        d.ipady=110;
        d.weighty=1.0;
        d.gridheight=200;
        d.insets = new Insets(0,0,0,0);
        d.fill = GridBagConstraints.HORIZONTAL;
        popUp.add(scrollPane, d);
        
        
        
        
        popUp.setVisible(false);
        popUp.setModal(false);
        popUp.setAlwaysOnTop(false);
        
        
        popUp.addWindowFocusListener(new WindowFocusListener() {

            public void windowGainedFocus(WindowEvent e) {
                // mache nichts!
            }

            public void windowLostFocus(WindowEvent e) {
                popUp.setModal(false);
                popUp.setAlwaysOnTop(false);
                popUp.setVisible(false);
            }

        });
    }

    private void addWidgets() {

        this.getLblEingabeC().gridx = 0;
        this.getLblEingabeC().gridy = 0;
        this.getLblEingabeC().weighty=1.0;
        this.add(this.getLblEingabe(), this.getLblEingabeC());

        this.getFldEingabeC().gridx = 0;
        this.getFldEingabeC().gridy = 1;
        this.getFldEingabeC().weighty=0.5;
        this.add(this.getFldEingabe(), this.getFldEingabeC());

        this.getBtnShowListC().gridx = 1;
        this.getBtnShowListC().gridy = 1;
        this.add(this.getBtnShowList(), this.getBtnShowListC());

    }

    private void setupInteractions() {
        this.getBtnShowList().addActionListener(new ActionCombo(this.getFldEingabe(),getFldFilterFeld()));
        this.getFldFilterFeld().getDocument().addDocumentListener(new ActionComboEntry(this.getFldEingabe(),getFldFilterFeld()));
    }

// Getter & Setter
    public JTextField getFldEingabe() {
        return fldEingabe;
    }

    public void setFldEingabe(JTextField fldEingabe) {
        this.fldEingabe = fldEingabe;
    }

    public JPanel getComboPanel() {
        return comboPanel;
    }

    public void setComboPanel(JPanel comboPanel) {
        this.comboPanel = comboPanel;
    }

    public JLabel getLblEingabe() {
        return lblEingabe;
    }

    public void setLblEingabe(JLabel lblEingabe) {
        this.lblEingabe = lblEingabe;
    }

    public String getStrCombo() {
        return strCombo;
    }

    public void setStrCombo(String strCombo) {
        this.strCombo = strCombo;
    }

    public JButton getBtnShowList() {
        return btnShowList;
    }

    public void setBtnShowList(JButton btnShowList) {
        this.btnShowList = btnShowList;
    }

    public GridBagConstraints getLblEingabeC() {
        return lblEingabeC;
    }

    public void setLblEingabeC(GridBagConstraints lblEingabeC) {
        this.lblEingabeC = lblEingabeC;
    }

    public GridBagConstraints getFldEingabeC() {
        return fldEingabeC;
    }

    public void setFldEingabeC(GridBagConstraints fldEingabeC) {
        this.fldEingabeC = fldEingabeC;
    }

    public GridBagConstraints getBtnShowListC() {
        return btnShowListC;
    }

    public void setBtnShowListC(GridBagConstraints btnShowListC) {
        this.btnShowListC = btnShowListC;
    }

    public JTable getTblDatenHerkunft() {
        return tblDatenHerkunft;
    }

    public void setTblDatenHerkunft(JTable tblDatenHerkunft) {
        this.tblDatenHerkunft = tblDatenHerkunft;
    }

    public TableColumnModel getTableColumnModel() {
        return tableColumnModel;
    }

    public void setTableColumnModel(TableColumnModel tableColumnModel) {
        this.tableColumnModel = tableColumnModel;
    }

    public DefaultTableModel getDefaultTableModel() {
        return defaultTableModel;
    }

    public void setDefaultTableModel(DefaultTableModel defaultTableModel) {
        this.defaultTableModel = defaultTableModel;
    }

    public int getListenhoehe() {
        return listenhoehe;
    }

    public void setListenhoehe(int listenhoehe) {
        this.listenhoehe = listenhoehe;
    }

    
    
    
    public JTextField getFldFilterFeld() {
        return fldFilterFeld;
    }

    public void setFldFilterFeld(JTextField fldFilterFeld) {
        this.fldFilterFeld = fldFilterFeld;
    }




    private class ActionComboEntry implements DocumentListener {

        private JTextField fldEingabe;
        private JTextField fldFilterFeld;

        private ActionComboEntry(JTextField fldEingabe, JTextField fldFilterFeld) {
            super();
            this.fldEingabe = fldEingabe;
            this.fldFilterFeld=fldFilterFeld;

        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            System.out.println("ActionComboInsert");
            this.fldEingabe.setText(fldFilterFeld.getText());   
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            System.out.println("ActionComboRemove");
            this.fldEingabe.setText(fldFilterFeld.getText());   
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            System.out.println("ActionComboUpdate");
            this.fldEingabe.setText(fldFilterFeld.getText());   
        }

    }

    public class ActionCombo implements ActionListener {

        private JTextField fldEingabe;
        private JTextField fldFilterFeld;

        public ActionCombo(JTextField fldEingabe, JTextField fldFilterFeld) {
            super();
            this.fldEingabe = fldEingabe;
            this.fldFilterFeld=fldFilterFeld;

        }

        public void actionPerformed(ActionEvent e) {
            System.out.println("ActionCombo");
            this.fldFilterFeld.setText(fldEingabe.getText());
            point = this.fldEingabe.getLocationOnScreen();
            popUp.setLocation(point.x, point.y);
            popUp.setVisible(true);
            popUp.setModal(true);
            popUp.setAlwaysOnTop(true);
        }

    }

    public JDialog getPopUp() {
        return popUp;
    }

    public void setPopUp(JDialog popUp) {
        this.popUp = popUp;
    }

}

Viele Grüße
MaDeBuVie