首页 > 解决方案 > 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);
    }
}

标签: javaswing

解决方案


以下是我将在您的代码中更改的一些内容。(仅考虑有关您的对话的部分)

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 JDialogJDialog在您的情况下,使用 normal并简单地添加它可能就足够了JTable


推荐阅读