java 为什么frame.pack()不能与JTable一起工作?

kdfy810k  于 2023-02-14  发布在  Java
关注(0)|答案(2)|浏览(113)

我有一个超级基本的JTable,我把它添加到一个JFrame中,但是由于某种原因frame.pack()不起作用。我把行高设置为列宽,这样表格的单元格就成了正方形,但是当窗口调整大小时,这个方法似乎不起作用。那么,我怎样才能使表格的单元格总是正方形,即使调整大小也是如此呢?并且框架 Package 正确吗?下面是窗口的代码:

package me.an.ar.window;

import java.awt.Container;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

public class DayPlanner
{
    private JFrame frame;

    private void createAndShowGUI()
    {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Container container = frame.getContentPane();

        Object[][] data = new Object[5][7];
        String[] columnNames = { "Day1", "Day2", "Day3", "Day4", "Day5", "Day6", "Day7" };
        JTable table = new JTable(data, columnNames);

        for (int col = 0; col < table.getColumnCount(); col++)
        {
            for (int row = 0; row < table.getRowCount(); row++)
            {
                int colWidth = table.getColumnModel().getColumn(col).getWidth();
                table.setRowHeight(row, colWidth);
            }
        }

        container.add(new JScrollPane(table));

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void show()
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    public DayPlanner()
    {
        show();
    }

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

uxhixvfz1#

您未设置任何LayoutManager。默认值不是FlowLayout,但至少不能为null:

  • 默认内容窗格将设置一个边框布局管理器。*(Java 17 API

这意味着通过调整窗口的大小,你将不得不更多地与滚动窗格的大小作斗争。

container.add(new JScrollPane(table), BorderLayout.CENTER);

这将使滚动窗格随框架增长和收缩,表中的行数/列数可能会发生变化,这也可能会受到JTable.setAutoResizeMode()的影响。

jutyujz0

jutyujz02#

选项1

您还没有真正提到您将如何使用这个表(将保存哪些数据以及用户期望如何与之交互);然而,这听起来像是GridLayout(关于数据单元格)以及GridBagLayout(关于标头单元格)的用例。

public class DayPlanner {
    private JFrame frame;
    Dimension cellSize = new Dimension(75, 75);

    private void createAndShowGUI() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create header cells
        JPanel p1 = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        String[] columnNames = { "Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7" };
        int count = 0;
        for (int i = 0; i < columnNames.length; i++) {
            JLabel l = new JLabel(columnNames[i], SwingConstants.CENTER);
            l.setFont(new Font("Times New Roman", Font.BOLD, 14));
            l.setBackground(new Color(238, 238, 238));
            l.setOpaque(true);
            l.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, new Color(122, 138, 153)));
            c.fill = GridBagConstraints.HORIZONTAL;
            c.ipady = 5; // adjusts cell's height
            c.weightx = 0.5;
            c.gridx = count++;
            c.gridy = 0;
            p1.add(l, c);
        }

        // Create data cells
        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(5, 7));
        for (int i = 0; i < 35; i++) {
            JLabel l = new JLabel("<html> This is some sample text " + i + "</html>"); // html tags allow text-wrapping
            l.setFont(new Font("Times New Roman", Font.PLAIN, 14));
            l.setVerticalAlignment(SwingConstants.TOP);
            l.setHorizontalAlignment(SwingConstants.LEFT);
            l.setPreferredSize(cellSize);
            l.setBackground(Color.WHITE);
            l.setOpaque(true);
            l.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, new Color(122, 138, 153)));
            p2.add(l);
        }

        JScrollPane sp = new JScrollPane(p2);
        sp.getVerticalScrollBar().setUnitIncrement((int) cellSize.getHeight() / 2); // adjusts scrolling speed
        sp.getViewport().setBackground(Color.WHITE);
        Container container = frame.getContentPane();
        container.add(p1, BorderLayout.NORTH);
        container.add(sp, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new DayPlanner().createAndShowGUI();
            }
        });
    }
}

选项2

如果您仍然希望使用问题中给出的JTable,可以在JFrame中添加一个ComponentListener,这样您就可以监听"resize事件",从而允许您重新调整单元格的大小并保留其方形形状。

frame.addComponentListener(new ComponentAdapter() {
    public void componentResized(ComponentEvent evt) {
        for (int row = 0; row < table.getRowCount(); row++) {
            int colWidth = table.getColumnModel().getColumn(0).getWidth();
            table.setRowHeight(row, colWidth);
        }
    }
});

至于pack()的问题,你可以根据表格中的行和列来设置JFrame的初始大小(记住注解掉frame.pack();).下面的代码,虽然它会删除框架底部的空白区域,但是它不会阻止用户重新调整窗口大小并将其恢复。

int colWidth = table.getColumnModel().getColumn(0).getWidth();
frame.setSize(7 * colWidth, 5 * table.getRowHeight(0) + 25);
//frame.pack();

相关问题