Java 使用JTable会导致应用程序的其余部分加载不正确

Java 使用JTable会导致应用程序的其余部分加载不正确,java,swing,jtable,jtabbedpane,Java,Swing,Jtable,Jtabbedpane,首先,这是一个学校项目,所以我不能上传我的完整代码。我们得到了一个空白项目,并要求为其添加功能 我希望能够在不同的表中显示来自服务器的数据,每个表都在单独的选项卡中,每个“页面”都有向表中添加、编辑或删除记录的选项 因为我有很多不同的表,所以我编写了一个父类Page,它将包含一个表和一些jpanel,如果需要的话,我可以向其中添加按钮 然而,每当我尝试向页面添加JTable时,就会导致选项卡之间出现不可预测的行为——请注意,无论我是否使用TableModel,都会发生这种情况 我尝试使用标签来显

首先,这是一个学校项目,所以我不能上传我的完整代码。我们得到了一个空白项目,并要求为其添加功能

我希望能够在不同的表中显示来自服务器的数据,每个表都在单独的选项卡中,每个“页面”都有向表中添加、编辑或删除记录的选项

因为我有很多不同的表,所以我编写了一个父类Page,它将包含一个表和一些jpanel,如果需要的话,我可以向其中添加按钮

然而,每当我尝试向页面添加JTable时,就会导致选项卡之间出现不可预测的行为——请注意,无论我是否使用TableModel,都会发生这种情况

我尝试使用标签来显示组件应该在哪里,这很好,但是使用实际的表会导致占位符标签和顶部的选项卡被隐藏

我没有对线程做任何处理,所以当我尝试添加JTable时,我不知道应用程序会发生什么

这是Page.java的代码:

import java.awt.*;

import javax.swing.*;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class Page extends JPanel {
    private static final long serialVersionUID = -4661566573959270000L;
    protected JTable table;
    protected JPanel addPanel;
    protected JPanel fieldPanel;
    protected JPanel buttonPanel;
    protected TableModel model;
    public Page(String[] names) {
        this.setLayout(new GridLayout(2,1));
        final class MyTableModel implements TableModel{
            private static final long serialVersionUID = -4661566573959270000L;
            private String[] columnNames;
            private Object[][] data;
            public MyTableModel(String[] names) {
                columnNames=names;
                data=new Object[names.length][0];
            }
            @Override
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
                if(isCellEditable(rowIndex, columnIndex)) {
                    data[rowIndex][columnIndex] = aValue;
                }
             }     

             @Override
             public void removeTableModelListener(TableModelListener l) {

             }

             @Override
             public boolean isCellEditable(int rowIndex, int columnIndex) {
                      return false;
             }

             @Override
             public Object getValueAt(int rowIndex, int columnIndex) {
                 return data[rowIndex][columnIndex];
             }

             @Override
             public int getRowCount() {
                 return data.length;
             }

             @Override
             public String getColumnName(int columnIndex) {
                 return columnNames[columnIndex];
             }

             @Override
             public int getColumnCount() {
                 return columnNames.length;
             }

             @Override
             public Class<?> getColumnClass(int columnIndex) {
                 try {
                     return getValueAt(0, columnIndex).getClass();
                 }
                 catch (Exception e) {
                     return null;
                 }
             }

             @Override
             public void addTableModelListener(TableModelListener l) {

             }
         };


         /**
         * creating and adding a table
         * this is the problematic bit
         */
         table = new JTable(new MyTableModel(names));
         this.add(table);
         //this.add(new Label("Table"));



         //panels for layout
         addPanel = new JPanel();
         fieldPanel = new JPanel();
         buttonPanel = new JPanel();
         //assigning positions
         this.add(addPanel);
         addPanel.setLayout(new BorderLayout());
         addPanel.add(fieldPanel, BorderLayout.CENTER);
         addPanel.add(buttonPanel, BorderLayout.SOUTH);
         //placeholder labels
         fieldPanel.add(new JLabel("Insert fields here"));
         buttonPanel.add(new Button("Buttons"));
     }
 }
字符串[]是我要显示的列的名称-注意,一旦表正常工作,这些列将被实际的有用名称替换

知道我做错了什么吗?我尝试用ChangeListener事件重新绘制框架,但这似乎没有任何作用

谢谢大家!

编辑 其中包括代码的完整版本。将上述代码用于页面,并在主类中使用:

import java.awt.*;
import javax.swing.*;
public class Main {
    public static void main(String[] args) {
        JFrame window = new JFrame("Components and Containers");
        window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE) ;
        window.setSize(800,600);

        Container pane = window.getContentPane();
        JTabbedPane tabs = new JTabbedPane();
        tabs.add("A", new Page(new String[]{"A"}));
        tabs.add("B", new Page(new String[]{"B"}));
        tabs.add("C", new Page(new String[]{"C"}));
        tabs.add("D", new Page(new String[]{"D"}));
        pane.add(tabs);
        window.setVisible(true);
    }
}
我尝试将该表添加到滚动面板,而该表只有在您将鼠标悬停在其上时才可见。选项卡仍无法正确显示


您的表模型类与行/列顺序不一致

在构造函数中,您可以编写

data=new Object[names.length][0];
这意味着第一个索引是列号,第二个索引是行号

但是,在访问数据时(在
getValueAt
setValueAt
中),您可以反过来使用索引:

data[rowIndex][columnIndex]
此外,这:

public int getRowCount() {
    return data.length;
}
将列计数返回为行计数,这意味着一旦JTable尝试调用
getValueAt(0,0)
,您就会得到一个
ArrayIndexOutOfBoundsException


要解决此问题,应使用以下命令初始化构造函数中的数据数组:

data=new Object[0][names.length];

表模型类与行/列顺序不一致

在构造函数中,您可以编写

data=new Object[names.length][0];
这意味着第一个索引是列号,第二个索引是行号

但是,在访问数据时(在
getValueAt
setValueAt
中),您可以反过来使用索引:

data[rowIndex][columnIndex]
此外,这:

public int getRowCount() {
    return data.length;
}
将列计数返回为行计数,这意味着一旦JTable尝试调用
getValueAt(0,0)
,您就会得到一个
ArrayIndexOutOfBoundsException


要解决此问题,应使用以下命令初始化构造函数中的数据数组:

data=new Object[0][names.length];

你好,bSmtih。这是一个好主意,创建一个包含在你的问题。这是帮助我们帮助您的最佳方式。有关如何将表添加到容器,请参阅。可能还有其他问题,但语句
this.add(addPanel);addPanel=newjpanel()显然是顺序错误的(在尝试将其添加到页面之前,您需要创建
addPanel
。@ThomasKläger我更改了编写代码的顺序,以便在询问问题时更好地格式化代码,所以这不是问题-尽管是个好地方!使用给定的代码很难判断,但是这些行:public MyTableModel(String[]names){columnNames=names;data=new Object[names.length][0];}似乎与tabs冲突;如果页面构造函数调用MyTableModel构造函数,因为所有对象数组都将具有相同的长度,因此具有相同的index.Hi bSmtih。这是一个好主意,创建一个包含在你的问题。这是帮助我们帮助您的最佳方式。有关如何将表添加到容器,请参阅。可能还有其他问题,但语句
this.add(addPanel);addPanel=newjpanel()显然是顺序错误的(在尝试将其添加到页面之前,您需要创建
addPanel
。@ThomasKläger我更改了编写代码的顺序,以便在询问问题时更好地格式化代码,所以这不是问题-尽管是个好地方!使用给定的代码很难判断,但是这些行:public MyTableModel(String[]names){columnNames=names;data=new Object[names.length][0];}似乎与tabs冲突;如果页面构造函数调用MyTableModel构造函数,因为所有对象数组都将具有相同的长度,从而具有相同的索引。@b如果此答案解决了您的问题,请抽出时间使用旁边的复选标记标记答案。请在此处阅读更多有关此礼仪的信息:@bSmith如果此答案解决了您的问题,请抽出时间使用旁边的复选标记标记答案。请在此处阅读有关此礼仪的更多信息: