Пожалуйста, сначала посмотрите на изображение: это не нормально, что появляются пять последних строк. Это когда я щелкнул по серой пустой области, в которой они появились.JTable: непредвиденное поведение при нажатии последнего элемента
Я создал программу, в которой перечислены продукты.
При запуске программы JTable
отображает всю базу данных, а затем я позволяю пользователю выбирать то, что он хочет видеть.
Здесь, например, я выбрал все продукты, сделанные в «Carrefour», и в списке всего 7 элементов. Он отображается нормально.
Но когда я перехожу в серой области под последним элементом, JTable имеет неожиданное поведение на изображении ниже (он показывает другую дату базы данных, как если бы вся база данных отображалась, как при запуске) , То же самое происходит, когда я изменяю размер кадра или пытаюсь настроить разные столбцы.
Я сделал свое исследование и не могу найти решение этой проблемы.
ПЕРЕД НАЖИМАЯ
ПОСЛЕ НАЖИМАЯ
Вот часть кода о создании 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);
}
}
EDIT 1:
Я пытался поставить JTable непосредственно на JPanel без использования JScrollPane, это не сработало.
Я также пытался не отображать всю базу данных при запуске программы, но когда я делаю первый запрос, проблема такая же. Он либо отображает серые строки, либо отображает данные из последнего запроса, когда я нажимаю случайную строку.
Я знаю, что проблема не связана с запросом, который я использую, потому что нужные данные отображаются правильно.
Я действительно потерялся и не мог себе представить, откуда это могло произойти.
Для справки: Я использую JFrame с разными JPanel на нем. На одном из них я добавил JScrollPane, на котором я разместил свой JTable.
EDIT 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);
}
}
"JTable имеет неожиданное поведение" - и что неожиданное поведение является ...? –
@JonSkeet Я отредактировал его, но в двух словах при нажатии под ним отображаются данные при запуске программы при отображении всей базы данных. Я добавил фотографию к моему объяснению. –
Хорошо, какая диагностика вы использовали до сих пор, чтобы понять, что происходит? Вы поставили точки останова в коде, чтобы посмотреть, какой запрос выполняется? Вы должны уметь существенно сузить этот вопрос и предоставить короткую, но полную * программу, демонстрирующую проблему. (См. Http://stackoverflow.com/help/mcve) –