JTable:在最后一个项目下单击时出现意外行为

时间:2015-09-26 16:29:32

标签: java swing jtable

请先看一下图片:最后五行出现是不正常的。当我点击他们出现的灰色空白区域时。

我制作了一个列出杂货的程序。

在程序启动时,JTable显示整个数据库,然后让用户选择他想要查看的内容。

例如,我选择了所有在" Carrefour"并且列表中共有7个项目。它显示正常。

但是当我点击最后一项下面的灰色区域时,JTable在下面的图像上显示了一个意外的行为(它显示了数据库的其他日期,好像整个数据库一样显示在启动中)。当我调整框架大小或尝试对不同的列进行调整时,会发生同样的情况。

我做了我的研究,找不到解决这个问题的方法。

点击之前

JTableBeforeClicking

点击后

JTable Problem

以下是有关创建JTable的代码部分:

private void tableCreation(String query) {
    // Random database queries I don't display for the sake of clarity

        excel = new JTable(rowData, columnNames);
        excel.setAutoCreateRowSorter(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
    tablePanel.removeAll();
    this.getContentPane().add(new JScrollPane(tablePanel.add(excel)), BorderLayout.CENTER);
    this.revalidate();
}

这是关于研究的代码的一部分,因此修改了JTable:

class SearchListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {

    // Random query construction with the e.getText() method

    if (!column.equals("prix") && !column.equals("num_id")){
            query = "select * from products where " + column + " like '%" + searchText.getText().toUpperCase().trim() + "%'";
        }else{
            query = "select * from products where " + column + " = '" + searchText.getText().toUpperCase().trim() + "'";
        }

    }else{
        query = "select * from products";
    }
        tableCreation(query);
    }
}

编辑1:

我试图在不使用JScrollPane的情况下将JTable直接放在JPanel上,但它没有用完。

我还试图在程序启动时不显示整个数据库,但是当我进行第一次查询时,问题是一样的。它显示灰色行,或者当我单击随机行时显示上一个查询中的数据。

我知道问题并非来自我正在使用的查询,因为正确显示了所需数据。

我真的迷失了,无法想象它会从哪里来。

有关信息:我正在使用具有不同JPanel的JFrame。在其中一个上面,我添加了我放置JTable的JScrollPane。

编辑2:

我将整个代码here发布给想要了解详情的人。它只包含在一个类中,因此很容易阅读。

整个代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;


public class FrameFC extends JFrame{

    public static void main(String[] args) {
        FrameFC fr = new FrameFC();
    }

    /*Main Frame Creation*/

    private JSplitPane split;
    private Font f = new Font("Arial", Font.PLAIN, 15);
    private JScrollPane scroll = new JScrollPane();

    /*Panel Creation*/
    private JPanel mainPanel = new JPanel();

    private JPanel westPanel = new JPanel();
    private JPanel eastPanel = new JPanel();

    private JPanel addPanel = new JPanel();
    private JPanel searchPanel = new JPanel();
    private JPanel removePanel = new JPanel();

    private int screenHeight = (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight());
    private int screenWidth = (int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth());

    private JButton buttonAdd = new JButton("Ajouter"),
                    buttonSearch = new JButton("Rechercher"),
                    buttonRemove = new JButton("Supprimer");

    private JTextField  nomP = new JTextField(),
                        cat = new JTextField(),
                        mag = new JTextField(),
                        prix = new JTextField(),
                        dateAchat = new JTextField(),
                        codemag = new JTextField(),
                        removeText = new JTextField();

    private JTextField searchText = new JTextField();

    private String[] tabCat = {"ID", "Nom Produit", "Categorie", "Magasin", "Prix", "Date (JJ/MM/AAAA)", "Code Magasin"};

    private JComboBox combo = new JComboBox(tabCat);

    /*Table Creation*/
    private JPanel tablePanel = new JPanel();
    private JTable excel = new JTable();
    private String query = "select * from products order by num_id";

    public FrameFC(){
        this.setTitle("Gestionnaire de produits");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        this.setLayout(new BorderLayout());

        panelCreation();
        tableCreation(query);

        this.setVisible(true);
    }

    class AjouterListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            if (nomP.getText().equals("") ||
                    cat.getText().equals("") ||
                    mag.getText().equals("") ||
                    prix.getText().equals("") ||
                    dateAchat.getText().equals("")){

            }else{
                String nomps, cats, mags, prixs, dates;
                nomps = nomP.getText();
                cats = cat.getText();
                mags = mag.getText();
                prixs = prix.getText();
                dates = dateAchat.getText();

                query = "insert into products "
                        + "(nom_produit, cat, mag, prix, date_achat, code_magasin)"
                        + " values ("
                        + "'" + nomps + "', '" + cats
                        + "', '" + mags + "', " + prixs
                        + ", '" + dates + "', '" + codemag.getText() + "');";

                Statement state;
                ResultSet res;
                try {
                    state = ConnectPostGRESql.getInstance("postgres").createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                    res = state.executeQuery(query);
                } catch (SQLException e1) {
                    System.out.println(nomps + " ajouté avec succès.");
                }

                query = "select * from products";
                tableCreation(query);
                nomP.setText("");
                cat.setText("");
                prix.setText("");

            }
        }
    }

    class SearchListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            String column;

            if (!searchText.getText().equals("")){

            switch (String.valueOf(combo.getSelectedItem()))
            {
            case "ID":
                column = "num_id";
                break;
            case "Nom Produit":
                column = "nom_produit";
                break;
            case "Categorie":
                column = "cat";
                break;
            case "Magasin":
                column = "mag";
                break;
            case "Prix":
                column = "prix";
                break;
            case "Code Magasin":
                column = "code_magasin";
                break;
            default:
                column = "date_achat";
                break;
            }
            if (!column.equals("prix") && !column.equals("num_id")){
                query = "select * from products where " + column + " like '%" + searchText.getText().toUpperCase().trim() + "%'";
            }else{
                query = "select * from products where " + column + " = '" + searchText.getText().toUpperCase().trim() + "'";
            }

        }else{
            query = "select * from products";
        }
            tableCreation(query);
        }
    }

    class RemoveListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            if (!removeText.getText().equals("")){
                Statement state;
                ResultSet res;
                try {
                    state = ConnectPostGRESql.getInstance("postgres").createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                    res = state.executeQuery("delete from products where num_id = " + removeText.getText());
                } catch (SQLException e1) {
                    System.out.println("Entrée supprimée avec succès.");
                }
            }
            tableCreation("select * from products");

        }
    }

    private void tableCreation(String query) {
        // TODO Auto-generated method stub
        try {
            Statement state = ConnectPostGRESql.getInstance("postgres").createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet res = state.executeQuery(query);

            ResultSetMetaData meta = res.getMetaData();

            Object[] columnNames = new Object[meta.getColumnCount()];

            for (int i = 1; i<=meta.getColumnCount();i++){
                columnNames[i-1] = meta.getColumnName(i);
            }

            res.last();

            Object[][] rowData = new Object[res.getRow()][meta.getColumnCount()];

            res.beforeFirst();

            int j = 1;

            while (res.next()){
                for (int i = 1; i <= meta.getColumnCount(); i++){
                    if (i == 1){
                        int nombredez = 4 - String.valueOf(res.getInt(i)).length();
                        String nombredezString = "";
                        for (int n = 0; n < nombredez;n++){
                            nombredezString += "0";
                        }
                        rowData[j-1][i-1] = nombredezString + String.valueOf(res.getObject(i));
                    }
                    else{
                        rowData[j-1][i-1] = res.getObject(i);
                    }
                }
                j++;
            }

            res.close();
            state.close();

            excel = new JTable(rowData, columnNames);
            excel.setAutoCreateRowSorter(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        tablePanel.removeAll();
        this.getContentPane().add(new JScrollPane(tablePanel.add(excel)), BorderLayout.CENTER);
        this.revalidate();
    }

    private void panelCreation() {
        // TODO Auto-generated method stub

        /*Panel Add (West)*/
        addPanel.setLayout(new GridLayout(7,2));

        addPanel.add(new JLabel("Entrez le nom du produit :"));
        addPanel.add(nomP);
        addPanel.add(new JLabel("Entrez la catégorie :"));
        addPanel.add(cat);
        addPanel.add(new JLabel("Entrez le magasin :"));
        addPanel.add(mag);
        addPanel.add(new JLabel("Entrez le prix :"));
        addPanel.add(prix);
        addPanel.add(new JLabel("Entrez la date :"));
        addPanel.add(dateAchat);
        addPanel.add(new JLabel("Entrez le code magasin"));
        addPanel.add(codemag);
        addPanel.add(new JLabel());

        buttonAdd.addActionListener(new AjouterListener());
        addPanel.add(buttonAdd);

        addPanel.setBorder(BorderFactory.createTitledBorder("Ajouter"));
        addPanel.setPreferredSize(new Dimension(949, 360));

        /*Panel Search (North-East)*/
        searchPanel.setLayout(new GridLayout(2,2));

        searchPanel.add(combo);
        searchPanel.add(searchText);
        searchPanel.add(new JLabel());

        buttonSearch.addActionListener(new SearchListener());
        searchPanel.add(buttonSearch);

        searchPanel.setBorder(BorderFactory.createTitledBorder("Rechercher"));
        searchPanel.setPreferredSize(new Dimension(949, 180));

        /*Panel Remove (South-East)*/
        removePanel.setLayout(new GridLayout(2,2));

        removePanel.add(new JLabel("Entrez le numero d'identifiant : "));
        removePanel.add(removeText);
        removePanel.add(new JLabel());

        buttonRemove.addActionListener(new RemoveListener());
        removePanel.add(buttonRemove);

        removePanel.setBorder(BorderFactory.createTitledBorder("Supprimer"));
        removePanel.setPreferredSize(new Dimension(949, 180));

        /*MainPanel on Frame*/
        westPanel.setBorder(BorderFactory.createLineBorder(Color.black, 2));
        westPanel.add(addPanel);

        eastPanel.setLayout(new BorderLayout());
        eastPanel.setBorder(BorderFactory.createLineBorder(Color.black, 2));

        eastPanel.add(searchPanel, BorderLayout.NORTH);
        eastPanel.add(removePanel, BorderLayout.SOUTH);

        mainPanel.setLayout(new BorderLayout());

        mainPanel.add(westPanel, BorderLayout.WEST);
        mainPanel.add(eastPanel, BorderLayout.EAST);

        this.getContentPane().add(new JScrollPane(mainPanel), BorderLayout.NORTH);
    }

}

1 个答案:

答案 0 :(得分:2)

您的问题似乎是由于在没有删除先前的JScrollPane的情况下添加带有JTable的新JScrollPane引起的。

例如,尝试运行下面的代码

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

@SuppressWarnings("serial")
public class FrameFC extends JFrame {

    public static void main(String[] args) {
        new FrameFC();
    }

    private Random random = new Random();    
    private JPanel northPanel = new JPanel();

    private JTable excel = new JTable();
    private JScrollPane currentScrollPane = null;

    public FrameFC() {
        this.setTitle("Gestionnaire de produits");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        northPanel.add(new JButton(new AbstractAction("Change Table") {

            @Override
            public void actionPerformed(ActionEvent evt) {
                tableCreation();
            }
        }));

        add(northPanel, BorderLayout.PAGE_START);
        tableCreation();
        pack();
        setLocationRelativeTo(null);

        this.setVisible(true);
    }

    private void tableCreation() {
        String[] columnNames = {"A", "B", "C"};

        int rowCount = random.nextInt(10) +3;
        Object[][] rowData = new Object[rowCount][columnNames.length];
        for (int i = 0; i < rowData.length; i++) {
            for (int j = 0; j < rowData[i].length; j++) {
                rowData[i][j] = "" + random.nextInt(100) + 50;
            }
        }

        excel = new JTable(rowData, columnNames);
        excel.setAutoCreateRowSorter(true);

        if (currentScrollPane != null) {
            // remove(currentScrollPane);   // ******* here ******
        }
        currentScrollPane = new JScrollPane(excel);

        add(currentScrollPane);
        this.revalidate();
        repaint();
    }

}

有和没有这一行注释:

// remove(currentScrollPane);   // ******* here ******

如果它不到位,您可能会看到保留的JScrollPane的副作用。

然而,正如我在评论中提到的那样,更好的解决方案是:不要交换组件,而是在JTable中交换模型。创建一个包含所需数据的DefaultTableModel,并通过调用它上面的setModel(...)来设置您的JTable模型。这更清洁,更安全。

另请注意我上面尝试获取代码并删除与您的问题无关的所有位,包括任何和所有SQL代码以及与问题无关的组件和侦听器。请考虑在您尝试调试和本网站上的问题时自己这样做。

如,

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

@SuppressWarnings("serial")
public class PanelFC extends JPanel {
    private static final String[] COLUMN_NAMES = {"A", "B", "C"};
    private Random random = new Random();    
    private JPanel northPanel = new JPanel();    
    private JTable excel = new JTable(modelCreation());

    public PanelFC() {
        northPanel.add(new JButton(new CreateModelAction("Create Model")));

        setLayout(new BorderLayout());

        add(northPanel, BorderLayout.PAGE_START);
        add(new JScrollPane(excel), BorderLayout.CENTER);
    }

    private TableModel modelCreation() {
        // your code will take some parameter, and using database query 
        // result, create the table model
        // Also, all database code should be called in a background thread
        int rowCount = random.nextInt(10) +3;
        Object[][] rowData = new Object[rowCount][COLUMN_NAMES.length];
        for (int i = 0; i < rowData.length; i++) {
            for (int j = 0; j < rowData[i].length; j++) {
                rowData[i][j] = "" + random.nextInt(100) + 50;
            }
        }        
        DefaultTableModel model = new DefaultTableModel(rowData, COLUMN_NAMES);
        return model;
    }

    private class CreateModelAction extends AbstractAction {
        public CreateModelAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            excel.setModel(modelCreation());
        }
    }

    private static void createAndShowGui() {
        PanelFC mainPanel = new PanelFC();

        JFrame frame = new JFrame("PanelFC");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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