请先看一下图片:最后五行出现是不正常的。当我点击他们出现的灰色空白区域时。
我制作了一个列出杂货的程序。
在程序启动时,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);
}
}
编辑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);
}
}
答案 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();
}
});
}
}