【问题标题】:How to create a search bar with multiple filters?如何创建具有多个过滤器的搜索栏?
【发布时间】:2019-07-12 16:48:23
【问题描述】:

我希望在 java swing 中创建一个带有多个过滤器的搜索栏。

我想得到下面的结果。

https://image.noelshack.com/fichiers/2019/08/2/1550565354-cj3db.png)

不幸的是,我尝试使用自动完成功能编辑 jcombobox,但我无能为力。

有没有人有过这样的发展,或者他们能引导我前进吗?

提前谢谢你

【问题讨论】:

  • 应该什么时候显示下拉菜单?当用户键入第一个字符时?最简单的可能是创建一个弹出菜单并在用户在文本字段中输入值时显示它。
  • @DakshinamurthyKarra 是的,下拉菜单应该在用户输入第一个字符时显示。

标签: java swing


【解决方案1】:

不是我最好的作品之一。或许你可以以此为起点?

public class JTextFieldWithMenu extends JFrame implements DocumentListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JTextField entry;
    private JLabel jLabel1;
    private JPopupMenu popup;

    public JTextFieldWithMenu() {
        initComponents();

        entry.getDocument().addDocumentListener(this);

    }

    private void initComponents() {
        entry = new JTextField(40);
        entry.addFocusListener(new FocusListener() {
            @Override
            public void focusLost(FocusEvent e) {
            }

            @Override
            public void focusGained(FocusEvent e) {
                entry.setSelectionStart(0);
                entry.setSelectionEnd(0);
                entry.setCaretPosition(entry.getText().length());
            }
        });
        jLabel1 = new JLabel();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setTitle("TextFieldDemo");

        jLabel1.setText("Enter text to search:");
        setLayout(new BorderLayout());
        add(jLabel1, BorderLayout.WEST);
        add(entry, BorderLayout.CENTER);
        pack();
    }

    public void insertUpdate(DocumentEvent ev) {
        showPopup();
    }

    protected void showPopup() {
        if (popup != null)
            popup.setVisible(false);
        popup = null;
        if (entry.getText().length() == 0)
            return;
        popup = new JPopupMenu();
        popup.setRequestFocusEnabled(false);
        if (entry.getText().length() == 0) {
            popup.setVisible(false);
        } else {
            popup.removeAll();
            popup.add(new JMenuItem("Search for '" + entry.getText() + "' in Filter1"));
            popup.add(new JMenuItem("Search for '" + entry.getText() + "' in Filter2"));
            popup.add(new JMenuItem("Search for '" + entry.getText() + "' in Filter3"));
            if (!popup.isShowing())
                popup.show(entry, 0, entry.getHeight());
            else
                popup.revalidate();
            entry.requestFocus();
        }
    }

    public void removeUpdate(DocumentEvent ev) {
        showPopup();
    }

    public void changedUpdate(DocumentEvent ev) {
        showPopup();
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JTextFieldWithMenu().setVisible(true);
            }
        });
    }

}

【讨论】:

    【解决方案2】:

    谢谢

    https://i.stack.imgur.com/5sqay.png

    JTable_Search.java

    package JAVA_VIDEOS_TUTORIALS;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import javax.swing.table.DefaultTableModel;
    
    import javax.swing.GroupLayout.Alignment;
    import javax.swing.BorderFactory;
    import javax.swing.DefaultListModel;
    import javax.swing.GroupLayout;
    import javax.swing.JList;
    import javax.swing.JMenuItem;
    import javax.swing.JOptionPane;
    import javax.swing.ListSelectionModel;
    import javax.swing.JPopupMenu;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    
    import java.awt.Component;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    
    
    public class JTable_Search extends javax.swing.JFrame implements DocumentListener {
    
        private static final long serialVersionUID = 1L;
        private static Logger logger = Logger.getLogger("fr.pasteque.pos.caching.LocalDB");
        private static Connection conn = null;
        public ArrayList<CustomData> ListArray = new ArrayList<CustomData>();
    
        /**
         * Creates new form JTable_Search
         */
        public JTable_Search() {
            initComponents();
    
            jText_Search.getDocument().addDocumentListener(this);
    
            // call findUsers function
            findUsers();
    
        }
    
    
        // function to connect to mysql database
        private static Connection getConnection() throws SQLException {
            if (conn == null) {
                try {
                    Class.forName("org.h2.Driver");
                    String url = "jdbc:h2:???";
                    conn = DriverManager.getConnection(url, "", "");
                } catch (ClassNotFoundException e) {
                    // Should never happen
                    logger.log(Level.SEVERE,
                            "Unable to run local cache database", e);
                }
            }
            return conn;
        }
    
     // function to return users arraylist with particular data 
        public ArrayList<User> ListUsers(String ValToSearch)
        {
            ArrayList<User> usersList = new ArrayList<User>();
    
            String searchQuery = "SELECT * FROM customers WHERE id like '%%'";
            Statement st;
            ResultSet rs;
    
            try{
    
                if (ValToSearch.length()!=0) {
    
                    String[] items = ValToSearch.split(";");
                    List<String> ValToSearchByCol = Arrays.asList(items);
    
                    for( int i  = 0; i < ValToSearchByCol.size(); i++)
                        {
    
                            if (ValToSearchByCol.get(i).indexOf("firstname") ==  0) { 
    
                                String searchFirstname = ValToSearchByCol.get(i).replace("firstname:", "");
                                System.out.println(searchFirstname);  
                                searchQuery += "AND LOWER(firstname) like LOWER('"+searchFirstname+"%')";
                            }
                            else if (ValToSearchByCol.get(i).indexOf("lastname") == 0) {
    
                                String searchLastname = ValToSearchByCol.get(i).replace("lastname:", "");
                                System.out.println(searchLastname);  
                                searchQuery += "AND LOWER(lastname) like LOWER('"+searchLastname+"%')";
                            }
                            else {
                                System.out.println(ValToSearchByCol.get(i));
                                JOptionPane.showMessageDialog(null, "Veuillez saisir une valeur dans le champ recherche.", "Erreur", JOptionPane.ERROR_MESSAGE);
                                }
                        }
                }
    
                Connection con = getConnection();
                st = con.createStatement();
                rs = st.executeQuery(searchQuery);
    
                User user;
    
                while(rs.next())
                {
                    user = new User(
                                     rs.getString("id"),
                                     rs.getString("firstname"),
                                     rs.getString("lastname"),
                                     rs.getString("name")
                                    );
                    usersList.add(user);
                }
    
            }catch(Exception ex){
                System.out.println(ex.getMessage());
            }
    
            return usersList;
        }
    
        // function to display data in jtable
        public void findUsers()
        {
            ArrayList<User> users = ListUsers(jText_Search.getText());
            DefaultTableModel model = new DefaultTableModel();
            model.setColumnIdentifiers(new Object[]{"ID","Firstname","Lastname","Name"});
            Object[] row = new Object[4];
    
            for(int i = 0; i < users.size(); i++)
            {
                row[0] = users.get(i).getId();
                row[1] = users.get(i).getFirstname();
                row[2] = users.get(i).getLastname();
                row[3] = users.get(i).getName();
                model.addRow(row);
            }
           jTable_Users.setModel(model);
    
        }
    
    
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {
    
            jPanel2 = new javax.swing.JPanel();
            jButton_Search = new javax.swing.JButton();
            jText_Search = new javax.swing.JTextField();
            jScrollPane1 = new javax.swing.JScrollPane();
            jTable_Users = new javax.swing.JTable();
            JList_Search = new javax.swing.JList<CustomData>();
    
            jText_Search.addFocusListener(new FocusListener() {
                @Override
                public void focusLost(FocusEvent e) {
                }
    
                @Override
                public void focusGained(FocusEvent e) {
                    jText_Search.setSelectionStart(0);
                    jText_Search.setSelectionEnd(0);
                    jText_Search.setCaretPosition(jText_Search.getText().length());
                }
            });
    
            jPopupMenu_Search = new javax.swing.JPopupMenu();
            addPopup(jText_Search, jPopupMenu_Search);
    
    
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    
            jButton_Search.setText("Search");
            jButton_Search.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton_SearchActionPerformed(evt);
                }
            });
    
            jText_Search.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
    
            jTable_Users.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
            jTable_Users.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {
                    {null, null, null, null},
                    {null, null, null, null},
                    {null, null, null, null},
                    {null, null, null, null}
                },
                new String [] {
                    "Title 1", "Title 2", "Title 3", "Title 4"
                }
            ));
            jScrollPane1.setViewportView(jTable_Users);
    
            javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
            jPanel2Layout.setHorizontalGroup(
                jPanel2Layout.createParallelGroup(Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(27)
                        .addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING)
                            .addComponent(JList_Search, GroupLayout.PREFERRED_SIZE, 416, GroupLayout.PREFERRED_SIZE)
                            .addGroup(jPanel2Layout.createParallelGroup(Alignment.TRAILING, false)
                                .addGroup(jPanel2Layout.createSequentialGroup()
                                    .addComponent(jText_Search)
                                    .addGap(103)
                                    .addComponent(jButton_Search))
                                .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 584, GroupLayout.PREFERRED_SIZE)))
                        .addContainerGap(30, Short.MAX_VALUE))
            );
            jPanel2Layout.setVerticalGroup(
                jPanel2Layout.createParallelGroup(Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE)
                            .addComponent(jButton_Search)
                            .addComponent(jText_Search, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE))
                        .addGap(47)
                        .addComponent(JList_Search, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
                        .addGap(45)
                        .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addGap(75))
            );
    
    
            jPanel2.setLayout(jPanel2Layout);
    
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            layout.setHorizontalGroup(
                layout.createParallelGroup(Alignment.LEADING)
                    .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, 641, Short.MAX_VALUE)
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, 717, GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            );
            getContentPane().setLayout(layout);
    
            pack();
        }// </editor-fold>  
    
        ////DEBUT #1
        /** PG: Fonction qui crée un PopupMenu en dessous du JTextField avec comme MenuItems 
         * toutes les informations recherchables sur l'utilisateur + le text saisie dans le JTextField
         */
        protected void showPopup() {
            if (jPopupMenu_Search != null)
                jPopupMenu_Search.setVisible(false);
            jPopupMenu_Search = null;
            if (jText_Search.getText().length() == 0)
                return;
            jPopupMenu_Search = new JPopupMenu();
            jPopupMenu_Search.setRequestFocusEnabled(false);
            if (jText_Search.getText().length() == 0) {
                jPopupMenu_Search.setVisible(false);
            } else {
                jPopupMenu_Search.removeAll();
    
                //DEBUT #2
                /** PG: Rempli le PopupMenu avec comme MenuItems toutes les informations recherchables sur l'utilisateur,
                 * en se basant sur la classe Search_User qui contient toutes les informations recherchables sur un utilisateur
                 * et en concaténant dans les MenueItems ces informations + le texte saisi dans le JTextField
                 */
                Search_User seacrch_user = new Search_User(jText_Search.getText());
                for (int i = 0; i < seacrch_user.getInfoUser().size(); i++) {
                    JMenuItem item=new JMenuItem(seacrch_user.getInfoUser().get(i) + seacrch_user.getSerachValue());
    
                    //DEBUT #3
                    /** PG: Action lorsqu'on clique sur un MenuItems, on copie la valeur du MenuItems dans le 
                     * JList et on vide le JTextField
                     */
                    item.addActionListener(new ActionListener() {
                      public void actionPerformed(ActionEvent e) {
                        ListArray.add(new CustomData(item.getText()));
                        DefaultListModel<CustomData> model = new DefaultListModel<CustomData> ();
                        for (int y=0; y<ListArray.size();y++) {
                            model.addElement(ListArray.get(y));
    
                        }
                        JList_Search.setModel(model);
                        JList_Search.setCellRenderer(new CustomListRenderer(JList_Search,ListArray));
                        JList_Search.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
                        JList_Search.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                        JList_Search.setLayoutOrientation(JList.HORIZONTAL_WRAP);
                        JList_Search.setVisibleRowCount(-1);
                        jText_Search.setText("");
                      }
    
                    //FIN #3
    
                  });
                    jPopupMenu_Search.add(item);
                }
                //FIN #2
                if (!jPopupMenu_Search.isShowing())
                    jPopupMenu_Search.show(jText_Search, 0, jText_Search.getHeight());
                else
                    jPopupMenu_Search.revalidate();
                jText_Search.requestFocus();
            }
        }
      //FIN #1
    
        public void insertUpdate(DocumentEvent ev) {
            showPopup();
        }
    
        public void removeUpdate(DocumentEvent ev) {
            showPopup();
        }
    
        public void changedUpdate(DocumentEvent ev) {
            showPopup();
        }
    
    
        // Button Filter/search 
        private void jButton_SearchActionPerformed(java.awt.event.ActionEvent evt) { 
    
            if (jText_Search.getText().length()==0) {
    
                JOptionPane.showMessageDialog(null, "Veuillez saisir une valeur dans le champ recherche.", "Attention", JOptionPane.WARNING_MESSAGE);
            }
            else {
    
                findUsers();
            }
    
        }                                              
    
        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (ClassNotFoundException ex) {
                java.util.logging.Logger.getLogger(JTable_Search.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                java.util.logging.Logger.getLogger(JTable_Search.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                java.util.logging.Logger.getLogger(JTable_Search.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(JTable_Search.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>
    
            /* Create and display the form */
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new JTable_Search().setVisible(true);
                }
            });
        }
    
        // Variables declaration - do not modify                     
        private javax.swing.JButton jButton_Search;
        private javax.swing.JPanel jPanel2;
        private javax.swing.JScrollPane jScrollPane1;
        private javax.swing.JTable jTable_Users;
        private javax.swing.JTextField jText_Search;
        private javax.swing.JList<CustomData> JList_Search;
        private javax.swing.JPopupMenu jPopupMenu_Search;
        private static void addPopup(Component component, final JPopupMenu popup) {
            component.addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    if (e.isPopupTrigger()) {
                        showMenu(e);
                    }
                }
                public void mouseReleased(MouseEvent e) {
                    if (e.isPopupTrigger()) {
                        showMenu(e);
                    }
                }
                private void showMenu(MouseEvent e) {
                    popup.show(e.getComponent(), e.getX(), e.getY());
                }
            });
        }
    }
    

    Search_User.java

    package JAVA_VIDEOS_TUTORIALS;
    
    import java.util.Arrays;
    import java.util.List;
    
    public class Search_User {
    
        private List<String> infoUser;
        private String serachValue;
    
    
        public Search_User(String SerachValue)
        {
            this.infoUser = Arrays.asList("Prénom: ", "Nom: ");
            this.serachValue = SerachValue;
        }
    
    
        public List<String> getInfoUser() {
            return infoUser;
        }
    
    
        public void setInfoUser(List<String> infoUser) {
            this.infoUser = infoUser;
        }
    
    
        public String getSerachValue() {
            return serachValue;
        }
    
    
        public void setSerachValue(String serachValue) {
            this.serachValue = serachValue;
        }
    
    
    }
    

    用户.java

    package JAVA_VIDEOS_TUTORIALS;
    
    public class User {
    
        private String id;
        private String firstname;
        private String lastname;
        private String name;
    
    
        public User(String Id,String Firstname,String Lastname,String Name)
        {
            this.id = Id;
            this.firstname = Firstname;
            this.lastname = Lastname;
            this.name = Name;
        }
    
        public String getId()
        {
            return id;
        }
    
        public String getFirstname()
        {
            return firstname;
        }
    
        public String getLastname()
        {
            return lastname;
        }
    
        public String getName()
        {
            return name;
        }
    }
    

    CustomListRenderer.java

    package JAVA_VIDEOS_TUTORIALS;
    
    
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.util.ArrayList;
    
    import javax.swing.BorderFactory;
    import javax.swing.DefaultListCellRenderer;
    import javax.swing.DefaultListModel;
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.SwingUtilities;
    
    
    /**
     * @author Mikle Garin
     * @see http://stackoverflow.com/a/18589264/909085
     */
    
    public class CustomListRenderer extends DefaultListCellRenderer
    {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private static final ImageIcon crossIcon = new ImageIcon ("src/cross.png");
    
        /**
         * Actual renderer.
         */
        private CustomLabel renderer;
    
        /**
         * Custom renderer constructor.
         * We will use it to create actual renderer component instance.
         * We will also add a custom mouse listener to process close button.
         *
         * @param list our JList instance
         */
        public CustomListRenderer(final JList<CustomData>list, ArrayList<CustomData> listArrayList)
        {
            super();
            renderer = new CustomLabel();
    
            list.addMouseListener(new MouseAdapter()
            {
                @Override
                public void mouseReleased(MouseEvent e)
                {
                    if ( SwingUtilities.isLeftMouseButton(e))
                    {
                        int index = list.locationToIndex(e.getPoint());
                        if (index != -1 && list.isSelectedIndex(index))
                        {
                            Rectangle rect = list.getCellBounds(index, index);
                            Point pointWithinCell = new Point (e.getX() - rect.x, e.getY() - rect.y);
                            Rectangle crossRect = new Rectangle(rect.width-rect.width+5,
                                    rect.height/2-12/2,12, 12);
                            if (crossRect.contains(pointWithinCell))
                            {
                                DefaultListModel<CustomData> model = (DefaultListModel<CustomData>)list.getModel();
                                model.remove(index);
                                listArrayList.remove(index);
                            }
                        }
                    }
                }
            } );
        }
    
        /**
         * Returns custom renderer for each cell of the list.vcbc
         *
         * @param list         list to process
         * @param value        cell value (CustomData object in our case)
         * @param index        cell index
         * @param isSelected   whether cell is selected or not
         * @param cellHasFocus whether cell has focus or not
         * @return custom renderer for each cell of the list
         */
        @Override
        public Component getListCellRendererComponent (JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus)
        {
            renderer.setSelected(isSelected);
            renderer.setData((CustomData)value);
            renderer.setToolTipText(renderer.getText());
            return renderer;
        }
    
        /**
         * Label that has some custom decorations.
         */
        private static class CustomLabel extends JLabel
        {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;
            private boolean selected;
    
            public CustomLabel()
            {
                super();
                setOpaque(false);
                setFont(new Font("Serif", Font.BOLD, 14));
                setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0));
    
            }
    
    
    
            private void setSelected(boolean selected)
            {
                this.selected = selected;
                setForeground(selected ? Color.BLACK : Color.BLACK);
            }
    
            private void setData(CustomData data)
            {
                setText(data.getName());
            }
    
            @Override
            protected void paintComponent (Graphics g)
            {
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
    
                g2d.drawImage(crossIcon.getImage(), 0,
                         0, null);
    
                if (selected)
                {
                    g2d.drawImage(crossIcon.getImage(), 0,
                           0, null);
                }
                super.paintComponent(g);
            }
    
            @Override
            public Dimension getPreferredSize()
            {
                final Dimension ps = super.getPreferredSize();
                ps.height = 36;
                ps.width = 115;
                return ps;
            }
        }
    }
    

    CustomData.java

    package JAVA_VIDEOS_TUTORIALS;
    
    /**
     * Custom data for our list.
     */
    public class CustomData{
    
        private String name;
    
        public CustomData(String name)
        {
            super ();
            this.name = name;
        }
    
    
        public String getName()
        {
            return name;
        }
    
    }
    

    【讨论】:

    • 如何创建泛型类?在这里,我创建了一个“Search_User”类来按姓氏或名字搜索用户。但我想创建通用类,以便我可以将此代码用于其他搜索,例如产品名称及其引用......此外,我想让搜索的元素参数化,因为如果明天我想要为了能够通过他的名字或名字之外的出生日期搜索用户,我必须直接更改 java 代码。
    猜你喜欢
    • 1970-01-01
    • 2019-01-18
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    相关资源
    最近更新 更多