Прежде всего, это для школьного проекта, поэтому я не могу загрузить свой полный код. Нам дали пустой проект и попросили добавить в него функциональность.
Я хочу иметь возможность отображать данные с сервера в различных таблицах, каждая из которых находится на отдельной вкладке, причем каждая «страница» имеет возможность добавлять, редактировать или удалять записи в таблице.
Поскольку у меня довольно много разных таблиц, я написал родительский класс Page, который будет содержать таблицу и несколько JPanels, к которым я могу добавить кнопки при необходимости.
Однако всякий раз, когда я пытаюсь добавить JTable на страницу, это вызывает непредсказуемое поведение между вкладками - обратите внимание, это происходит независимо от того, использую ли я TableModel или нет.
Я пытался использовать метки для отображения того, где должны быть компоненты, что работает нормально, но использование реальных таблиц приводит к тому, что метки-заполнители и вкладки вверху скрываются.
Вкладка с метками для иллюстрации того, где компоненты ДОЛЖНЫ быть
Вкладка после попытки добавить JTable - остальная часть кода (включая другие метки-заполнители) остается такой же
Я ничего не сделал с многопоточностью, поэтому затрудняюсь понять, что происходит с приложением, когда я пытаюсь добавить свой 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 [], являющимся именами столбцов, которые я хочу отобразить - обратите внимание, что они будут заменены реальными полезными именами, как только таблицы будут работать правильно.
Есть идеи, что я делаю не так? Я пытался перекрасить свой фрейм с помощью события ChangeListener, но это, похоже, ничего не делает.
Спасибо!
EDIT
Включена полная версия кода. Используйте приведенный выше код для Page и используйте его в главном классе:
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);
}
}
Я попытался вместо этого добавить таблицу в ScrollPanel, и таблица станет видимой только при наведении на нее курсора. Вкладки по-прежнему не отображаются правильно.
Результат добавления таблицы в отдельную ScrollPanel, а не непосредственно в компонент.