JTable 已填充但未显示。使用默认表模型
JTable populated but not shown. Using DefaultTableModel
我不明白为什么我的 JTable
没有更新。
下面是我的代码:
package it.franpic.chat.client.prestazioni.view;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import it.franpic.chat.client.prestazioni.model.RecordBean;
public class FinestraPrincipale {
private JFrame frame;
private JTable tabellaDati;
private JScrollPane scrollPaneTabella;
private JSplitPane splitPaneContenuti;
/**
* Launch the application.
*/
public void avvia() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FinestraPrincipale window = new FinestraPrincipale();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public FinestraPrincipale() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel pnlOpzioni = new JPanel();
frame.getContentPane().add(pnlOpzioni, BorderLayout.NORTH);
pnlOpzioni.setBorder(new TitledBorder(new LineBorder(new Color(0, 0, 0)), "Opzioni", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
pnlOpzioni.setLayout(new BorderLayout(0, 0));
JCheckBox chckbxAggiornaAutomaticamente = new JCheckBox("Aggiorna Automaticamente");
chckbxAggiornaAutomaticamente.setEnabled(false);
pnlOpzioni.add(chckbxAggiornaAutomaticamente);
chckbxAggiornaAutomaticamente.setVerticalAlignment(SwingConstants.TOP);
splitPaneContenuti = new JSplitPane();
splitPaneContenuti.setOneTouchExpandable(true);
splitPaneContenuti.setOrientation(JSplitPane.VERTICAL_SPLIT);
frame.getContentPane().add(splitPaneContenuti, BorderLayout.CENTER);
JScrollPane scrollPaneGrafico = new JScrollPane();
splitPaneContenuti.setLeftComponent(scrollPaneGrafico);
scrollPaneTabella = new JScrollPane();
splitPaneContenuti.setRightComponent(scrollPaneTabella);
tabellaDati = new JTable();
tabellaDati.setModel(new DefaultTableModel(
new Object[][] {
},
new String[] {
"ISTANTE", "GESTITE", "DISTRIBUITE", "PIANIFICATO", "SOSTENIBILE", "LOGGATI", "LOGGATI_PIANIFICATO"
}
) {
Class[] columnTypes = new Class[] {
String.class, Integer.class, Integer.class, Integer.class, Integer.class, Integer.class, Integer.class
};
public Class getColumnClass(int columnIndex) {
return columnTypes[columnIndex];
}
});
tabellaDati.getColumnModel().getColumn(3).setPreferredWidth(76);
tabellaDati.getColumnModel().getColumn(6).setPreferredWidth(127);
tabellaDati.setColumnSelectionAllowed(true);
tabellaDati.setCellSelectionEnabled(true);
scrollPaneTabella.setViewportView(tabellaDati);
}
public void aggiornaTabella(List<RecordBean> lista) {
DefaultTableModel model = (DefaultTableModel) tabellaDati.getModel();
model.setRowCount(0);
System.out.println("tabellaDati.getRowCount() = " + tabellaDati.getRowCount());
for (RecordBean record : lista) {
model.addRow(new Object[]{record.getMomento(), record.getGestite(), record.getDistribuite(), record.getSostenibile(), record.getPianificato(), record.getLoggati(), record.getLoggatiPianificato()});
}
System.out.println("tabellaDati.getRowCount() = " + tabellaDati.getRowCount());
}
}
这是调用这些方法的主要 class 代码:
package it.franpic.chat.client.prestazioni.control;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import it.franpic.chat.client.prestazioni.model.RecordBean;
import it.franpic.chat.client.prestazioni.view.FinestraPrincipale;
public class Client {
public static void main(String[] args) {
FinestraPrincipale finestraPrincipale = new FinestraPrincipale();
GestoreDb gestoreDb = new GestoreDb();
String adessoFormatoMySql = LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss"));
List<RecordBean> lista = gestoreDb.getRecordsDaDate("2019-01-26 18:00:00", adessoFormatoMySql);
finestraPrincipale.avvia();
finestraPrincipale.aggiornaTabella(lista);
}
}
从其他讨论和文档来看,我认为我的代码很好,但显然不是。
table 在构造时正确显示,但未通过 aggiornaTabella(List<RecordBean> lista)
方法更新。我不明白为什么。
我在 aggiornaTabella(List<RecordBean> lista)
中尝试过 addRow
周期后:
tabellaDati.setModel(model);
- .invalidate() 方法在 GUI 的每个组件上(即使不推荐)
.repaint()
GUI 的每个组件上的方法
model.fire....()
方法(即使不推荐)
从 aggiornaTabella(List<RecordBean> lista)
方法中的 2 println
我可以看到 JTable
的行已填充但未显示。
这个...
public class Client {
public static void main(String[] args) {
FinestraPrincipale finestraPrincipale = new FinestraPrincipale();
GestoreDb gestoreDb = new GestoreDb();
String adessoFormatoMySql = LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss"));
List<RecordBean> lista = gestoreDb.getRecordsDaDate("2019-01-26 18:00:00", adessoFormatoMySql);
finestraPrincipale.avvia();
finestraPrincipale.aggiornaTabella(lista);
}
}
解释了很多。
首先,您创建 FinestraPrincipale
的实例,加载一些数据并调用 finestraPrincipale.avvia
,但是 avvia
正在创建 FinestraPrincipale
[=18= 的新实例]
public void avvia() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
// Hello new instance...
FinestraPrincipale window = new FinestraPrincipale();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
显示在屏幕上,与您最初创建(正在更新)的实例无关
avvia
不应该创建一个新实例,它应该简单地使用它自己和之前在构造时初始化的状态...
public void avvia() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
仅此一项就可以解决您的问题
我不明白为什么我的 JTable
没有更新。
下面是我的代码:
package it.franpic.chat.client.prestazioni.view;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import it.franpic.chat.client.prestazioni.model.RecordBean;
public class FinestraPrincipale {
private JFrame frame;
private JTable tabellaDati;
private JScrollPane scrollPaneTabella;
private JSplitPane splitPaneContenuti;
/**
* Launch the application.
*/
public void avvia() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FinestraPrincipale window = new FinestraPrincipale();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public FinestraPrincipale() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel pnlOpzioni = new JPanel();
frame.getContentPane().add(pnlOpzioni, BorderLayout.NORTH);
pnlOpzioni.setBorder(new TitledBorder(new LineBorder(new Color(0, 0, 0)), "Opzioni", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
pnlOpzioni.setLayout(new BorderLayout(0, 0));
JCheckBox chckbxAggiornaAutomaticamente = new JCheckBox("Aggiorna Automaticamente");
chckbxAggiornaAutomaticamente.setEnabled(false);
pnlOpzioni.add(chckbxAggiornaAutomaticamente);
chckbxAggiornaAutomaticamente.setVerticalAlignment(SwingConstants.TOP);
splitPaneContenuti = new JSplitPane();
splitPaneContenuti.setOneTouchExpandable(true);
splitPaneContenuti.setOrientation(JSplitPane.VERTICAL_SPLIT);
frame.getContentPane().add(splitPaneContenuti, BorderLayout.CENTER);
JScrollPane scrollPaneGrafico = new JScrollPane();
splitPaneContenuti.setLeftComponent(scrollPaneGrafico);
scrollPaneTabella = new JScrollPane();
splitPaneContenuti.setRightComponent(scrollPaneTabella);
tabellaDati = new JTable();
tabellaDati.setModel(new DefaultTableModel(
new Object[][] {
},
new String[] {
"ISTANTE", "GESTITE", "DISTRIBUITE", "PIANIFICATO", "SOSTENIBILE", "LOGGATI", "LOGGATI_PIANIFICATO"
}
) {
Class[] columnTypes = new Class[] {
String.class, Integer.class, Integer.class, Integer.class, Integer.class, Integer.class, Integer.class
};
public Class getColumnClass(int columnIndex) {
return columnTypes[columnIndex];
}
});
tabellaDati.getColumnModel().getColumn(3).setPreferredWidth(76);
tabellaDati.getColumnModel().getColumn(6).setPreferredWidth(127);
tabellaDati.setColumnSelectionAllowed(true);
tabellaDati.setCellSelectionEnabled(true);
scrollPaneTabella.setViewportView(tabellaDati);
}
public void aggiornaTabella(List<RecordBean> lista) {
DefaultTableModel model = (DefaultTableModel) tabellaDati.getModel();
model.setRowCount(0);
System.out.println("tabellaDati.getRowCount() = " + tabellaDati.getRowCount());
for (RecordBean record : lista) {
model.addRow(new Object[]{record.getMomento(), record.getGestite(), record.getDistribuite(), record.getSostenibile(), record.getPianificato(), record.getLoggati(), record.getLoggatiPianificato()});
}
System.out.println("tabellaDati.getRowCount() = " + tabellaDati.getRowCount());
}
}
这是调用这些方法的主要 class 代码:
package it.franpic.chat.client.prestazioni.control;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import it.franpic.chat.client.prestazioni.model.RecordBean;
import it.franpic.chat.client.prestazioni.view.FinestraPrincipale;
public class Client {
public static void main(String[] args) {
FinestraPrincipale finestraPrincipale = new FinestraPrincipale();
GestoreDb gestoreDb = new GestoreDb();
String adessoFormatoMySql = LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss"));
List<RecordBean> lista = gestoreDb.getRecordsDaDate("2019-01-26 18:00:00", adessoFormatoMySql);
finestraPrincipale.avvia();
finestraPrincipale.aggiornaTabella(lista);
}
}
从其他讨论和文档来看,我认为我的代码很好,但显然不是。
table 在构造时正确显示,但未通过 aggiornaTabella(List<RecordBean> lista)
方法更新。我不明白为什么。
我在 aggiornaTabella(List<RecordBean> lista)
中尝试过 addRow
周期后:
tabellaDati.setModel(model);
- .invalidate() 方法在 GUI 的每个组件上(即使不推荐)
.repaint()
GUI 的每个组件上的方法model.fire....()
方法(即使不推荐)
从 aggiornaTabella(List<RecordBean> lista)
方法中的 2 println
我可以看到 JTable
的行已填充但未显示。
这个...
public class Client {
public static void main(String[] args) {
FinestraPrincipale finestraPrincipale = new FinestraPrincipale();
GestoreDb gestoreDb = new GestoreDb();
String adessoFormatoMySql = LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss"));
List<RecordBean> lista = gestoreDb.getRecordsDaDate("2019-01-26 18:00:00", adessoFormatoMySql);
finestraPrincipale.avvia();
finestraPrincipale.aggiornaTabella(lista);
}
}
解释了很多。
首先,您创建 FinestraPrincipale
的实例,加载一些数据并调用 finestraPrincipale.avvia
,但是 avvia
正在创建 FinestraPrincipale
[=18= 的新实例]
public void avvia() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
// Hello new instance...
FinestraPrincipale window = new FinestraPrincipale();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
显示在屏幕上,与您最初创建(正在更新)的实例无关
avvia
不应该创建一个新实例,它应该简单地使用它自己和之前在构造时初始化的状态...
public void avvia() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
仅此一项就可以解决您的问题