将 CSV 文件加载到 JTable 中

Load CSV File into JTable

我的代码:

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import javax.swing.JTable;
import java.io.*;
import java.util.*;
import java.awt.Color;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Font;
import java.io.*;

import java.util.*;
import java.awt.Color;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.Font;
public class students extends JFrame {

    private JPanel contentPane;
    private JTable table;
    private DefaultTableModel m;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    students frame = new students();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public students() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 1280, 740);
        contentPane = new JPanel();
        contentPane.setBackground(new Color(24,24,24));
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        studentTable();
        System.out.println("students();");

    }
    
    public void studentTable() {
        try {
            System.out.println("studentTable();");
            String datafile = "data.txt";
            FileReader fin = new FileReader(datafile);
            DefaultTableModel m = createTableModel(fin, null);
            
            JPanel panel = new JPanel();
            panel.setBackground(new Color(35,35,35));
            panel.setBounds(240, 163, 800, 360);
            contentPane.add(panel);
            panel.setLayout(null);
            table = new JTable(m);
            table.setBounds(0, 0, 800, 360);
            table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
            table.getTableHeader().setOpaque(false);
            table.setBackground(new Color(35, 35, 35));
            table.getTableHeader().setBackground(new Color(35,35,35));
            table.setForeground(new Color(255,255,255));
            table.getTableHeader().setForeground(new Color(255,255,255));
            table.setRowHeight(25);
            table.setFocusable(false);
            table.setIntercellSpacing(new java.awt.Dimension(0, 0));
            table.setRowHeight(25);
            table.setSelectionBackground(new Color(32, 32, 32));
            table.setShowVerticalLines(false);
            table.getTableHeader().setReorderingAllowed(false);
            
            


            FileWriter out = new FileWriter("data.csv");
            defaultTableModelToStream(m, out);
            out.close();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void defaultTableModelToStream(DefaultTableModel dtm,
            Writer out) throws IOException {
            System.out.println("defaultTableModelToStream();");
            final String LINE_SEP = System.getProperty("line.separator");
            int numCols = dtm.getColumnCount();
            int numRows = dtm.getRowCount();

            // Write headers
            String sep = "";

            for (int i = 0; i < numCols; i++) {
                out.write(sep);
                out.write(dtm.getColumnName(i));
                sep = ",";
            }

            out.write(LINE_SEP);

            for (int r = 0; r < numRows; r++) {
                sep = "";

                for (int c = 0; c < numCols; c++) {
                    out.write(sep);
                    out.write(dtm.getValueAt(r, c).toString());
                    sep = ",";
                }

                out.write(LINE_SEP);
            }
        }
    
    public static DefaultTableModel createTableModel(Reader in,
            Vector<Object> headers) {
        System.out.println("DefaultTableModel();");

            DefaultTableModel model = null;
            Scanner s = null;

            try {
                Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
                s = new Scanner(in);

                while (s.hasNextLine()) {
                    rows.add(new Vector<Object>(Arrays.asList(s.nextLine()
                                                               .split("\s*,\s*",
                                    -1))));
                }

                if (headers == null) {
                    headers = rows.remove(0);
                    model = new DefaultTableModel(rows, headers);
                } else {
                    model = new DefaultTableModel(rows, headers);
                }

                return model;
            } finally {
                s.close();
            }
        }
}

发生了什么: table 不加载也不加载 'data.txt'。 执行顺序是: 并且控制台中没有显示崩溃或错误。 找到文本文件。

应该发生什么 JTable 应该位于 JPanel 上,数据从文本文件中提取并加载。

我尝试自己修复它,但没有成功。也许有人会有解决方案。谢谢!

简短的回答是,你永远不会将 JTable 添加到任何东西中

长答案,好吧,要复杂得多。

null 布局(像素完美布局)在现代 UI 开发中是一种幻觉,许多因素决定和维护组件的大小和关系,让您浪费时间重新发明什么已经很容易地供您使用。

相反,花时间阅读和学习 how to use layout managers

你的studentsclass做的工作太多了(而且读起来也很费劲),应该专注于做好一件事情,即展示table 的数据。也没有理由从 JFrame 扩展,您没有向 class 添加任何新功能,只是让它比需要的更复杂。相反,从一个简单的容器 class 开始,例如 JPanel,例如...

public class StudentsPane extends JPanel {

    private JTable table;
    private DefaultTableModel m;

    public StudentsPane(TableModel model) {
        setLayout(new BorderLayout());
        setBackground(new Color(24, 24, 24));
        setBorder(new EmptyBorder(50, 50, 50, 50));

        table = new JTable(model);
        table.setFillsViewportHeight(true);
        table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
        table.getTableHeader().setOpaque(false);
        table.setBackground(new Color(35, 35, 35));
        table.getTableHeader().setBackground(new Color(35, 35, 35));
        table.setForeground(new Color(255, 255, 255));
        table.getTableHeader().setForeground(new Color(255, 255, 255));
        table.setFocusable(false);
        table.setIntercellSpacing(new java.awt.Dimension(0, 0));
        table.setRowHeight(25);
        table.setSelectionBackground(new Color(32, 32, 32));
        table.setShowVerticalLines(false);
        table.getTableHeader().setReorderingAllowed(false);
        add(new JScrollPane(table));
    }
}

现在,面板不关心数据来自哪里,只关心显示提供的模型。

将数据的 loading/saving 与它自己的 class 分开(查看 Single Responsibility Principle for the reasons why) and make sure that you are managing your resources correctly, see The try-with-resources Statement 以了解有关如何实现的更多详细信息,例如...

public class StudentsManager {
    public static TableModel loadFrom(File file) throws IOException {
        return loadFrom(file, null);
    }

    public static TableModel loadFrom(File file, Vector<Object> headers) throws IOException {
        try (Reader is = new FileReader(file)) {
            return loadFrom(is, headers);
        }
    }

    public static TableModel loadFrom(Reader is) {
        return loadFrom(is, null);
    }

    public static TableModel loadFrom(Reader reader, Vector<Object> headers) {
        DefaultTableModel model = null;
        Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
        Scanner s = new Scanner(reader);
        while (s.hasNextLine()) {
            rows.add(new Vector<Object>(Arrays.asList(s.nextLine().split("\s*,\s*"))));
        }

        if (headers == null) {
            headers = rows.remove(0);
        }
        model = new DefaultTableModel(rows, headers);
        return model;
    }

    public static void writeTo(DefaultTableModel dtm, File file) throws IOException {
        try (Writer writer = new FileWriter(file)) {
            writeTo(dtm, writer);
        }
    }

    public static void writeTo(DefaultTableModel dtm, Writer out) throws IOException {
        final String LINE_SEP = System.getProperty("line.separator");
        int numCols = dtm.getColumnCount();
        int numRows = dtm.getRowCount();

        StringJoiner joiner = new StringJoiner(",");
        for (int i = 0; i < numCols; i++) {
            joiner.add(dtm.getColumnName(i));
        }
        out.write(joiner.toString());

        out.write(LINE_SEP);

        for (int r = 0; r < numRows; r++) {
            joiner = new StringJoiner(",");
            for (int c = 0; c < numCols; c++) {
                joiner.add(dtm.getValueAt(r, c).toString());
            }
            out.write(joiner.toString());
            out.write(LINE_SEP);
        }
    }
}

准备就绪后,只需加载数据并显示面板...

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        try {
            TableModel model = StudentsManager.loadFrom(new File("data.txt"));
            JFrame frame = new JFrame();
            frame.add(new StudentsPane(model));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
});

可运行示例...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import javax.swing.JPanel;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    TableModel model = StudentsManager.loadFrom(new File("data.txt"));
                    JFrame frame = new JFrame();
                    frame.add(new StudentsPane(model));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class StudentsManager {
        public static TableModel loadFrom(File file) throws IOException {
            return loadFrom(file, null);
        }

        public static TableModel loadFrom(File file, Vector<Object> headers) throws IOException {
            try (Reader is = new FileReader(file)) {
                return loadFrom(is, headers);
            }
        }

        public static TableModel loadFrom(Reader is) {
            return loadFrom(is, null);
        }

        public static TableModel loadFrom(Reader reader, Vector<Object> headers) {
            DefaultTableModel model = null;
            Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
            Scanner s = new Scanner(reader);
            while (s.hasNextLine()) {
                rows.add(new Vector<Object>(Arrays.asList(s.nextLine().split("\s*,\s*"))));
            }

            if (headers == null) {
                headers = rows.remove(0);
            }
            model = new DefaultTableModel(rows, headers);
            return model;
        }

        public static void writeTo(DefaultTableModel dtm, File file) throws IOException {
            try (Writer writer = new FileWriter(file)) {
                writeTo(dtm, writer);
            }
        }

        public static void writeTo(DefaultTableModel dtm, Writer out) throws IOException {
            final String LINE_SEP = System.getProperty("line.separator");
            int numCols = dtm.getColumnCount();
            int numRows = dtm.getRowCount();

            StringJoiner joiner = new StringJoiner(",");
            for (int i = 0; i < numCols; i++) {
                joiner.add(dtm.getColumnName(i));
            }
            out.write(joiner.toString());

            out.write(LINE_SEP);

            for (int r = 0; r < numRows; r++) {
                joiner = new StringJoiner(",");
                for (int c = 0; c < numCols; c++) {
                    joiner.add(dtm.getValueAt(r, c).toString());
                }
                out.write(joiner.toString());
                out.write(LINE_SEP);
            }
        }
    }

    public class StudentsPane extends JPanel {

        private JTable table;
        private DefaultTableModel m;

        public StudentsPane(TableModel model) {
            setLayout(new BorderLayout());
            setBackground(new Color(24, 24, 24));
            setBorder(new EmptyBorder(50, 50, 50, 50));

            table = new JTable(model);
            table.setFillsViewportHeight(true);
            table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
            table.getTableHeader().setOpaque(false);
            table.setBackground(new Color(35, 35, 35));
            table.getTableHeader().setBackground(new Color(35, 35, 35));
            table.setForeground(new Color(255, 255, 255));
            table.getTableHeader().setForeground(new Color(255, 255, 255));
            table.setFocusable(false);
            table.setIntercellSpacing(new java.awt.Dimension(0, 0));
            table.setRowHeight(25);
            table.setSelectionBackground(new Color(32, 32, 32));
            table.setShowVerticalLines(false);
            table.getTableHeader().setReorderingAllowed(false);
            add(new JScrollPane(table));
        }
    }
}