java - JScrollPane 中的 IntelliJ JTable

标签 java swing user-interface intellij-idea jtable

我正在使用 IntelliJ GUI Builder 为我的应用程序设计 GUI。其中,JScrollPane 内有一个 JTable 似乎无法正常工作。首先,我无法显示列标题。其次,表格点击不起作用。无论是在默认行选择中还是在我实现的任何 MouseListeners 中,它的作用就好像我单击了实际位置下方的 3 行。最后,如果表格超出了 JScrollPane 的大小,它只会忽略最后 X 行,并且不提供滚动条来查看它们。

我已经重新设计了该项目几次,尝试了 AbstractTableModel 的扩展,然后是 DefaultTableModel,最近我尝试放弃自定义 TableModel code> 完全并且仅使用 DefaultTableModel 构造函数无济于事。这是所有相关代码(其中一些是由 GUI 生成器自动生成的,我无法直接修改它)。

BaldGUI.java(主 GUI)

package client;

import client.DataTypes.Record;
import client.DataTypes.RecordSet;
import client.GuiElements.FileTree;
import client.GuiElements.RecordsTable;
import client.GuiElements.TextConsole;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;

public class BaldGUI extends JFrame {

//Menu
private JMenuBar menuBar = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenuItem newBatchItem = new JMenuItem("New Batch");
private JMenuItem saveBatchItem = new JMenuItem("Save Batch");
private JMenuItem loadBatchItem = new JMenuItem("Load Batch");

private static String rootDir = "C:/Users/wf1946/IdeaProjects/DocumentumLoaderTest01/data";

private JPanel mainPanel;
private JPanel LeftSideBarPanel;
private JTree fileTree;
private JButton AddFileButton;
private JButton ChangeDirectoryButton;
private JButton AddDirectoryButton;
private JCheckBox IncludeSubDirectoriesCheckBox;
private JScrollPane DataTableWrapper;
private JTable DataTable;
private JEditorPane Console;
private JScrollPane ConsoleScroller;

public BaldGUI() {
    $$$setupUI$$$();
    this.loadComponents();

    this.AddFileButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            ((RecordsTable) DataTable).addItem(new Record());
        }
    });

    this.add(this.mainPanel);
}

private void loadComponents() {
    //Menu
    this.setJMenuBar(this.menuBar);
    this.menuBar.add(this.fileMenu);
    this.fileMenu.add(this.newBatchItem);
    this.fileMenu.add(this.saveBatchItem);
    this.fileMenu.add(this.loadBatchItem);

    //Selection handler for the file tree
    this.fileTree.addTreeSelectionListener(new TreeSelectionListener() {
        @Override
        public void valueChanged(TreeSelectionEvent e) {

            TreePath path = e.getPath();

            if (!fileTree.getModel().isLeaf(path.getLastPathComponent())) { //Directory
                AddDirectoryButton.setEnabled(true);
                IncludeSubDirectoriesCheckBox.setEnabled(true);
                AddFileButton.setEnabled(false);
            } else { //File
                AddFileButton.setEnabled(true);
                AddDirectoryButton.setEnabled(false);
                IncludeSubDirectoriesCheckBox.setEnabled(false);
            }

        }
    });
}


//Getters
public JEditorPane getConsole() {
    return Console;
}

public JPanel getMainPanel() {
    return mainPanel;
}

public JTree getFileTree() {
    return fileTree;
}

public JTable getDataTable() {
    return this.DataTable;
}

public JCheckBox getIncludeSubDirectoriesCheckBox() {
    return IncludeSubDirectoriesCheckBox;
}

public JScrollPane getDataTableWrapper() {
    return DataTableWrapper;
}

private void createUIComponents() {
    this.Console = new TextConsole();
    this.fileTree = new FileTree(this, new File(this.rootDir));
    RecordSet rs = new RecordSet();
    for (int i = 0; i < 10; i++) rs.add(new Record());
    this.DataTable = new RecordsTable(new DefaultTableModel(rs.getData(), RecordsTable.colNames), this);
    this.DataTableWrapper = new JScrollPane(this.DataTable);
}

/**
 * Method generated by IntelliJ IDEA GUI Designer
 * >>> IMPORTANT!! <<<
 * DO NOT edit this method OR call it in your code!
 *
 * @noinspection ALL
 */
private void $$$setupUI$$$() {
    createUIComponents();
    mainPanel = new JPanel();
    mainPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
    mainPanel.setMinimumSize(new Dimension(1080, 810));
    mainPanel.setPreferredSize(new Dimension(1080, 810));
    LeftSideBarPanel = new JPanel();
    LeftSideBarPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
    LeftSideBarPanel.setMinimumSize(new Dimension(220, 35));
    LeftSideBarPanel.setPreferredSize(new Dimension(220, 600));
    mainPanel.add(LeftSideBarPanel);
    fileTree.setPreferredSize(new Dimension(200, 530));
    fileTree.setShowsRootHandles(true);
    LeftSideBarPanel.add(fileTree);
    AddFileButton = new JButton();
    AddFileButton.setPreferredSize(new Dimension(100, 25));
    AddFileButton.setText("Add File");
    LeftSideBarPanel.add(AddFileButton);
    ChangeDirectoryButton = new JButton();
    ChangeDirectoryButton.setPreferredSize(new Dimension(100, 25));
    ChangeDirectoryButton.setText("Change Root");
    LeftSideBarPanel.add(ChangeDirectoryButton);
    AddDirectoryButton = new JButton();
    AddDirectoryButton.setPreferredSize(new Dimension(100, 25));
    AddDirectoryButton.setText("Add Directory");
    LeftSideBarPanel.add(AddDirectoryButton);
    IncludeSubDirectoriesCheckBox = new JCheckBox();
    IncludeSubDirectoriesCheckBox.setPreferredSize(new Dimension(100, 22));
    IncludeSubDirectoriesCheckBox.setText("Subdirectories");
    LeftSideBarPanel.add(IncludeSubDirectoriesCheckBox);
    DataTableWrapper.setPreferredSize(new Dimension(845, 600));
    mainPanel.add(DataTableWrapper);
    DataTable.setFillsViewportHeight(true);
    DataTableWrapper.setViewportView(DataTable);
    ConsoleScroller = new JScrollPane();
    mainPanel.add(ConsoleScroller);
    Console.setEnabled(false);
    Console.setPreferredSize(new Dimension(1070, 195));
    ConsoleScroller.setViewportView(Console);
}

/**
 * @noinspection ALL
 */
public JComponent $$$getRootComponent$$$() {
    return mainPanel;
}
}

RecordsTable.java

package client.GuiElements;

import client.ActionListeners.RightClickMenuItemClick;
import client.ActionListeners.TableRightClickHandler;
import client.BaldGUI;
import client.DataTypes.Record;
import client.DataTypes.RecordSet;

import javax.swing.*;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.util.ArrayList;

//Table to store the records
public class RecordsTable extends JTable {

//Status codes returned to calling functions to indicate the success or failure of the new record
public static final int APPEND_SUCCESS_CODE = 1;
public static final int APPEND_FAIL_DUPLICATE_CODE = 2;
public static final String[] colNames = {"Status", "File", "Full Path", "Title", "Form Date",
    "Form No.", "Language Code", "Filed", "Approval Date", "Filed Form No."};

private RecordSet data = new RecordSet();

//Parent form
BaldGUI parent;

//Right-click menu for table item
JPopupMenu itemRightClickMenu = new JPopupMenu();
JMenuItem itemEdit = new JMenuItem("Edit Record");
JMenuItem itemDelete = new JMenuItem("Remove Record");

public RecordsTable(DefaultTableModel model, BaldGUI form) {
    super(model);
    this.parent = form;

    this.itemRightClickMenu.add(itemEdit);
    this.itemRightClickMenu.add(itemDelete);
    this.itemEdit.addMouseListener(new RightClickMenuItemClick(this, itemEdit));
    this.itemDelete.addMouseListener(new RightClickMenuItemClick(this, itemDelete));
    this.addMouseListener(new TableRightClickHandler(this));
    this.updateTable();
}

//Attempts to add a new row to the table
//Returns APPEND_FAIL_DUPLICATE_CODE if the selected file is already in the table
//Returns APPEND_SUCCESS_CODE if the record is successfully added
public int addItem(Record newRecord) {
    TextConsole tc = ((TextConsole)this.parent.getConsole());
    if(this.itemInData(newRecord)) {
        tc.addText(
                "File " + newRecord.getFileName() + " already included.\n", TextConsole.redStyle
        );
        return this.APPEND_FAIL_DUPLICATE_CODE;
    }
    this.data.add(newRecord);
    tc.addText("File " + newRecord.getFileName() + " added successfully.\n", TextConsole.greenStyle);

    this.updateTable();


    return this.APPEND_SUCCESS_CODE;
}

//Updates the table to display any new data
public void updateTable() {

}

//Returns true if the record is already in the table
//Record equality is defined based on the full path to the file
public boolean itemInData(Record item) {
    for( Record r : data) {
        if(r.equals(item)) return true;
    }
    return false;
}

public JPopupMenu getItemRightClickMenu() {
    return itemRightClickMenu;
}

public JMenuItem getItemEdit() {
    return itemEdit;
}

public BaldGUI getParent() {
    return parent;
}
}

Record类型只是一个基本的数据容器,而RecordSet只是ArrayList{Record}的扩展,并提供了一个方法将其中的数据放入 DefaultTableModelObject[][] 中。

最佳答案

所以,正如我所料,这是一个非常简单、愚蠢的错误。在我的 RecordsTable 类中,我将父 GUI (BaldGUI) 存储为名为“parent”的变量。然后我有一个方法 getParent() 来获取该父级,但我没有意识到 JTable 附带了一个方法 getParent() 来获取周围的组件。通过重写该方法,整个程序或多或少地崩溃了。我改变了方法,它可以正常工作。

关于java - JScrollPane 中的 IntelliJ JTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24943190/

相关文章:

java - 使用 Jersey 和 Jaxb 自定义 Json 输出

Java/Swing - 工具提示矩形

C# 从多个线程更新 TextBox

java - 带有 Guice 3.0 的 Tomcat8 WebSockets (JSR-356)

java - 解析 WSDL 时出现 Wsimport 错误

java - 如何防止任务栏中的JFrame警报效果

java - 避免 JToolBar 和 JTabbedPane 之间存在空格

javascript - 有没有办法随机化 CSS/JavaScript 中的填充?

security - 怎样才能使 OpenID 成为主流?

java - 如何为方法添加返回语句 - 初学者