java - JTable 构造函数的替代方案

标签 java swing jtable

在花费了无数时间使用 Swing 并尽力学习之后,我遇到了这个问题。在讨论具体问题之前,我想简要介绍一下情况。如果您立即发现问题,请随意跳过此部分。

过去 3 天我一直在使用 JTables(或者至少尝试这样做)。。我在使用 JTable 构造函数时遇到了一些问题:

JTable(Object[][] rowData, Object[] columnNames)

阅读并重读后oracle documentation我偶然发现了一组有关 JTable 构造函数的要点(使用它的缺点):

  • 它们会自动使每个单元格都可编辑。

  • 它们对所有数据类型都一视同仁(作为字符串)。例如,如果表列包含 boolean 数据,则表可以在复选框中显示数据。但是,如果您使用前面列出的两个 JTable 构造函数中的任何一个,则 boolean 数据将显示为字符串。您可以在上图的素食列中看到这种差异。

  • 它们要求您将表的所有数据放入数组或 vector 中,这可能不适合某些数据。例如,如果您要从数据库实例化一组对象,您可能希望直接查询对象的值,而不是将它们的所有值复制到数组或 vector 中。
<小时/>

第一点和第三点都给我带来了问题,所以我想问几个问题:

  1. 如何使各个列宽度静态,现在,所有列宽度都是均匀的,并且在调整大小时均匀缩放。这是一个问题,因为“ID”列显然不需要与“电子邮件”列一样多的空间

  2. 由于某些奇怪的原因,我在显示列名称时也遇到了问题,将我的 String[] columnNames 传递到构造函数中,但框架上没有显示任何内容。

<小时/>

JTable代码:

private JTable addStudentsJTable(){
    String[] columnNames = {
            "Teacher ID",
            "Student ID",
            "Name",
            "Surname",
            "E-mail",
            "Date of Birth",
            "Telephone",
            "Course",
            "OOP",
            "Year of Membership",
            "Consent"};

    Object[][] data = {
            {1, 1, "Random", "Student", "Student@email.com", "1/1/1970", 9999999, "MC", true, 2014, true},
            {2, 2, "Student", "Surname", "RandomStudent@email.com", "1/1/1970", 11111111, "AIO", true, 2000, true}
    };
    studentsJTable = new JTable(data, columnNames);

    studentsJTable.setPreferredScrollableViewportSize(new Dimension(850,200));
    studentsJTable.setFillsViewportHeight(true);

    JScrollPane scrollPane = new JScrollPane(studentsJTable);
    add(scrollPane);
    return studentsJTable;
}
<小时/>

整个 JFrame 类:

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableModel;
import java.awt.*;

public class JDatabaseMainFrame extends JFrame {
    private JTable studentsJTable;
    private JPanel contentPane;

public JDatabaseMainFrame(){
    JFrame frame = new JFrame("JDatabase");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    setTitle("JDatabase");
    setResizable(true);
    setMinimumSize(new Dimension(850,350));

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(new CardLayout(0, 0));

    //Adding tabs
    JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.LEFT);
    contentPane.add(tabbedPane, "Tabs");

    //Adding Student's panel
    JPanel studentsPanel = new JPanel();
    tabbedPane.addTab("Students", null, studentsPanel, null);
    studentsPanel.setLayout(new BorderLayout(0, 0));

    //Adding JTable to Student's panel
    JTable studentsJTable = addStudentsJTable();
    studentsPanel.add(studentsJTable, BorderLayout.CENTER);

    //Adding Teacher's panel
    JPanel teachersPanel = new JPanel();
    tabbedPane.addTab("Teachers", null, teachersPanel, null);

    //Adding Outing's panel
    JPanel outingsPanel = new JPanel();
    tabbedPane.addTab("Outings", null, outingsPanel, null);

    setBounds(200,200,650,650);
    pack();
    setVisible(true);
}

private void printData(JTable jTable){
    int numberOfRows = jTable.getRowCount();
    int numberOfColumns = jTable.getColumnCount();

    TableModel model = jTable.getModel();

    for(int i = 0; i < numberOfRows; i++){
        System.out.println("Row: " + i + ":");
        for(int j = 0; j < numberOfColumns; j++){
            System.out.println("  " + model.getValueAt(i, j));
        }
        System.out.println();
    }
    System.out.println("-------------------------------");
}

private JTable addStudentsJTable(){
    String[] columnNames = {
            "Teacher ID",
            "Student ID",
            "Name",
            "Surname",
            "E-mail",
            "Date of Birth",
            "Telephone",
            "Course",
            "OOP",
            "Year of Membership",
            "Consent"};

    Object[][] data = {
            {1, 1, "Random", "Student", "Student@email.com", "1/1/1970", 9999999, "MC", true, 2014, true},
            {2, 2, "Student", "Surname", "RandomStudent@email.com", "1/1/1970", 11111111, "AIO", true, 2000, true}
    };
    studentsJTable = new JTable(data, columnNames);

    studentsJTable.setPreferredScrollableViewportSize(new Dimension(850,200));
    studentsJTable.setFillsViewportHeight(true);

    JScrollPane scrollPane = new JScrollPane(studentsJTable);
    add(scrollPane);
    return studentsJTable;
}
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JDatabaseMainFrame frame = new JDatabaseMainFrame();
            frame.setVisible(true);
        }
    });
}
}
<小时/>

请随意编译它以查看当前结果!

最佳答案

您应该设置一个自定义 TableModel,这样您就可以使用任何您想要的数据结构而不是数组:http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data

这还允许您指定哪些单元格是可编辑的。

只需调用 TableColumn 类中的相应方法即可设置 JTable 列的宽度。更多信息请点击:http://docs.oracle.com/javase/8/docs/api/javax/swing/table/TableColumn.html

JTable 标题仅在 JScrollPane 中时才会自动显示。您确实将 JTable 添加到 JScrollPane,但随后您不对该 JScrollPane 执行任何操作。 JScrollPane 本身必须位于 JFrame 中的某个位置。

关于java - JTable 构造函数的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25290493/

相关文章:

java - 按钮按下事件

java - SwingWorker + JTable : how to change the code so that there was no error?

java - jspinner 的 jtable 值未显示

java - 在 Java 中解析日期时间字符串是否需要 `Locale`?

java - Applet 可以打开新的 HTML 窗口*并*绕过弹出窗口阻止程序吗?

java - 在 Java 中对 TXT 文件进行排序

java - JTable 最小化时更新时 CPU 使用率高

java - java-service-wrapper 如何决定是使用 32 位还是 64 位 VM?

用于构建 GUI 面板的 Java 函数

java - java中的jtextfield只允许数字和一位小数