java - JDialog 中的 JTable 不出现
问题描述
我想在一个新的 JDialog 中设置一个 ArrayList 内容的 JTable。我调试了代码,表模型设置了列和行,但 JDialog 没有显示任何内容。我检查了类似的问题,他们都指出setVisible(true)
应该在最后。就我而言,它已经是。如何在该 JDialog 中显示 JTable(包括来自 ArrayList 的数据 - 该部分应该已经在工作),基本上它目前是空的,根本没有表。
public class Main {
public static void main(String[] args) {
MainWindow wnd = new MainWindow();
}
}
public class MainWindow extends JFrame implements ActionListener {
private List<Movie> movies = new ArrayList<Movie>();
// Създаване на променливи за отделните контроли
private JLabel label1;
private JTextField tf1;
private JLabel label2;
private JTextField tf2;
private JLabel label3;
private JTextField tf3;
private JLabel label4;
private JComboBox combo1;
private JLabel label5;
private JTextField tf5;
private JButton btn1;
private JButton btn2;
public MainWindow() {
setSize(500, 300);
// при натискане на Х на проореца, да се затвори приложението
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout(new GridLayout(0, 2, 10, 10));
// Добавяме инв. номер в контейнера
label1 = new JLabel("Инвертарен номер");
tf1 = new JTextField();
window.add(label1);
window.add(tf1);
// Добавяме заглавие в контейнера
label2 = new JLabel("Заглавие");
tf2 = new JTextField();
window.add(label2);
window.add(tf2);
// Добавяме режисьор в контейнера
label3 = new JLabel("Режисьор");
tf3 = new JTextField();
window.add(label3);
window.add(tf3);
// Добавяме жанр в контейнера
label4 = new JLabel("Жанр");
String[] items = { "Комедия", "Екшън", "Драма" };
combo1 = new JComboBox(items);
window.add(label4);
window.add(combo1);
// Добавяме година на излизане в контейнера
label5 = new JLabel("Година на излизане");
tf5 = new JTextField();
window.add(label5);
window.add(tf5);
// Добавяме бутоните в контейнера
btn1 = new JButton("Справка");
btn2 = new JButton("Добави");
window.add(btn1);
window.add(btn2);
// При кликването върху бутоните, добавя евент, който се хендълва по-долу
btn1.addActionListener(this);
btn2.addActionListener(this);
setVisible(true);
}
// Извиква се при натискане на бутон, регистриран с addActionListener(this)
public void actionPerformed(ActionEvent e) {
// Извиква се, когато се кликне на бутон `Справки`.
if (e.getSource() == btn1)
{
// Показване на диалогов прозорец
new Dialog(movies);
}
// Извиква се, когато се кликне на бутон `Добавяне`.
else if (e.getSource() == btn2)
{
// Запазване на въведените данни в динамичния масив `movies`.
String id = tf1.getText();
String title = tf2.getText();
String director = tf3.getText();
String genre = tf5.getText();
String year = combo1.getSelectedItem().toString();
System.out.println("Инвертарен номер: " + id);
System.out.println("Заглавие: " + title);
System.out.println("Режисьор: " + director);
System.out.println("Жанр: " + genre);
System.out.println("Година на излизане: " + year);
Movie movie = new Movie();
movie.setId(id);
movie.setTitle(title);
movie.setDirector(director);
movie.setGenre(genre);
movie.setYear(year);
movies.add(movie);
System.out.println("Успешно добавен!");
}
}
}
public class Movie {
private String id;
private String title;
private String director;
private String genre;
private String year;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
}
public class Dialog extends JDialog {
private JTable table1;
public Dialog(List<Movie> movies) {
setTitle("Справка");
setSize(500, 300);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Container window = getContentPane();
window.setLayout(null);
String[] col = new String[] { "Инв. номер", "Заглавие", "Режисьор", "Жанр", "Година на излизане" };
DefaultTableModel tableModel = new DefaultTableModel(col, 0);
for (int i = 0; i < movies.size(); i++) {
String id = movies.get(i).getId();
String title = movies.get(i).getTitle();
String director = movies.get(i).getDirector();
String genre = movies.get(i).getGenre();
String year = movies.get(i).getYear();
Object[] data = { id, title, director, genre, year };
tableModel.addRow(data);
}
//TableModel tableModel = new DefaultTableModel(movies.toArray(new Object[][] {}), columns.toArray());
table1 = new JTable(tableModel);
window.add(table1);
setVisible(true);
}
}
解决方案
以下是我将在您的代码中更改的一些内容。(仅考虑有关您的对话的部分)
window.setLayout(null); // (1)
不要使用null
布局。学习使用适当的布局管理器,因为 swing 被设计为与这些结合使用。在您的情况下,您可以简单地保留 使用的默认布局,因为无论如何JDialog
您只有显示的。JTable
window.add(table1); // (2)
JTables
最好与 a 结合使用JScrollPane
,因为这将自动显示表格标题,而无需您担心。此外,请考虑 Oracle Swing 教程的如何使用表部分,以获取有关JTable
使用的更多信息。
此外 (3),Java Swing 应用程序应该在 Event Dispatch Thread 上运行(请参阅Swing 中的并发)。
Container window = getContentPane();
在您的情况下,无需从对话框中显式检索内容窗格。这只是不必要的开销,您不必担心。在这种情况下,调用add()
对话框就足以添加组件,而无需处理内容窗格。
我采用了您代码的“对话框”部分,包括您的Movie
课程的摘录,并创建了一个小的工作示例(同时尽量不更改过多的原始代码):
import java.util.Arrays;
import java.util.List;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> { // (3) - run on EDT
Test t = new Test();
List<Movie> movies = Arrays.asList(t.new Movie("Movie1", "Title1"), t.new Movie("Movie2", "Title2"));
MyDialog dialog = t.new MyDialog(movies);
});
}
public class MyDialog extends JDialog {
public MyDialog(List<Movie> movies) {
setTitle("Title");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
String[] col = new String[] { "ID", "Title" };
DefaultTableModel tableModel = new DefaultTableModel(col, 0);
for (int i = 0; i < movies.size(); i++) {
String id = movies.get(i).getId();
String title = movies.get(i).getTitle();
Object[] data = { id, title };
tableModel.addRow(data);
}
JTable table = new JTable(tableModel);
add(new JScrollPane(table)); // (2) - use a JScrollPane to display the table
pack(); // pack the dialog, components are sized according to their preferred size
setVisible(true);
}
}
class Movie {
private String id;
private String title;
public Movie(String id, String title) {
this.id = id;
this.title = title;
}
public String getId() {
return id;
}
public String getTitle() {
return title;
}
}
}
结果:
考虑到这些更改,您应该能够更新代码以正确显示JTable
.JDialog
旁注:
我也觉得这里没有必要extends JDialog
。JDialog
在您的情况下,使用 normal并简单地添加它可能就足够了JTable
。
推荐阅读
- javascript - JavaScript 循环和数组
- python - 检查字典键Python 2.7之间的部分匹配
- php - json_decode 的结果有效但 PHP 中的个别字段为空?
- go - 在 Go 中对结构切片进行排序的灵活而优雅的方法
- powershell-2.0 - 什么是 Powershell V2 中的 split cmdlet 的等价物?
- php - Laravel:缓存存储 [predis] 未在 Illuminate\Cache\CacheManager.php 中定义
- c# - ViewModel ArgumentOutOfRangeException 中的 Navigation.PopModalAsync()
- angular - angular 6模块延迟加载路由器路径混乱
- c++ - C++ 查找已排序字符串中的重复字符
- python - 访问基类变量