使用 JTable 会导致应用程序的其余部分加载不正确
Using a JTable causes rest of the application to load incorrectly
首先,这是一个学校项目,所以我无法上传我的完整代码。我们得到了一个空白项目并要求为其添加功能。
我希望能够在不同的 table 中显示来自服务器的数据,每个都在一个单独的选项卡中,每个 'page' 都可以选择添加、编辑或删除记录到table.
因为我有很多不同的 table,我写了一个父 class 页面,它将包含一个 table 和一些我可以添加按钮的 JPanels需要。
然而,每当我尝试向页面添加 JTable 时,它都会导致选项卡之间出现不可预测的table行为 - 请注意,无论我是否使用 TableModel,都会发生这种情况。
我尝试使用标签来显示组件应该在的位置,效果很好,但是使用实际的 tables 会导致占位符标签和顶部的选项卡被隐藏。
Tab with labels to illustrate where the components SHOULD be
Tab after I try to add a JTable - the rest of the code (including other placeholder labels) is the same
我没有对线程做任何事情,所以当我尝试添加我的 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"));
}
}
我使用以下代码向我的选项卡系统添加新页面:
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"}));
String[] 是我要显示的列的名称 - 请注意,一旦 table 正常工作,这些将被替换为实际有用的名称。
知道我做错了什么吗?我已经尝试使用 ChangeListener 事件重新绘制我的框架,但这似乎没有任何作用。
谢谢!
编辑
包括代码的完整版本。将上面的代码用于 Page,并在 Main class:
中使用它
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);
}
}
我尝试将 table 添加到 ScrollPanel,但只有当您将鼠标悬停在它上面时 table 才可见。选项卡仍未正确显示。
The result of adding the table to a separate ScrollPanel instead of directly to the component.
您的 table 模型 class 与 row/column 排序不一致。
在构造函数中,你写
data=new Object[names.length][0];
表示第一个索引是列号,第二个索引是行号。
但是,当访问数据时(在 getValueAt
、setValueAt
中),您使用相反的方式使用索引:
data[rowIndex][columnIndex]
还有,这个:
public int getRowCount() {
return data.length;
}
returns 列数作为行数,这意味着一旦 JTable 尝试调用 getValueAt(0, 0)
.
,您就会得到一个 ArrayIndexOutOfBoundsException
要解决此问题,您应该在构造函数中初始化数据数组:
data=new Object[0][names.length];
首先,这是一个学校项目,所以我无法上传我的完整代码。我们得到了一个空白项目并要求为其添加功能。
我希望能够在不同的 table 中显示来自服务器的数据,每个都在一个单独的选项卡中,每个 'page' 都可以选择添加、编辑或删除记录到table.
因为我有很多不同的 table,我写了一个父 class 页面,它将包含一个 table 和一些我可以添加按钮的 JPanels需要。
然而,每当我尝试向页面添加 JTable 时,它都会导致选项卡之间出现不可预测的table行为 - 请注意,无论我是否使用 TableModel,都会发生这种情况。
我尝试使用标签来显示组件应该在的位置,效果很好,但是使用实际的 tables 会导致占位符标签和顶部的选项卡被隐藏。
Tab with labels to illustrate where the components SHOULD be
Tab after I try to add a JTable - the rest of the code (including other placeholder labels) is the same
我没有对线程做任何事情,所以当我尝试添加我的 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"));
}
}
我使用以下代码向我的选项卡系统添加新页面:
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"}));
String[] 是我要显示的列的名称 - 请注意,一旦 table 正常工作,这些将被替换为实际有用的名称。
知道我做错了什么吗?我已经尝试使用 ChangeListener 事件重新绘制我的框架,但这似乎没有任何作用。
谢谢!
编辑 包括代码的完整版本。将上面的代码用于 Page,并在 Main class:
中使用它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);
}
}
我尝试将 table 添加到 ScrollPanel,但只有当您将鼠标悬停在它上面时 table 才可见。选项卡仍未正确显示。
The result of adding the table to a separate ScrollPanel instead of directly to the component.
您的 table 模型 class 与 row/column 排序不一致。
在构造函数中,你写
data=new Object[names.length][0];
表示第一个索引是列号,第二个索引是行号。
但是,当访问数据时(在 getValueAt
、setValueAt
中),您使用相反的方式使用索引:
data[rowIndex][columnIndex]
还有,这个:
public int getRowCount() {
return data.length;
}
returns 列数作为行数,这意味着一旦 JTable 尝试调用 getValueAt(0, 0)
.
ArrayIndexOutOfBoundsException
要解决此问题,您应该在构造函数中初始化数据数组:
data=new Object[0][names.length];