gpt4 book ai didi

java - 可滚动 (GridBagLayout) 面板内的空 JTables - 标题在列调整大小时折叠

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:41 25 4
gpt4 key购买 nike

我正在尝试创建一个“分段”表格,它实际上是通过 GridBagLayout 在“可滚动”JPanel 中布置的多个表格。这些表共享相同的表模型(类)、表头和列模型,JTableHeader 被设置为包含所有内容的 JScrollPane 的列标题 View 。只有一个 JScrollPane

frame (BorderLayout)
|- JScrollPane
|- JPanel (GridBagLayout)
|- Section title panel
|- JTable 1
|- Section title panel
|- JTable 2
|- JTable (fake)
|- vertical filler

一切似乎都按预期工作,直到我尝试调整任一表中没有值的任意列的大小 - 如果表至少有一行,它按预期工作。我考虑过在表中有“空”行,但这会干扰过滤、排序等。所以我更改了代码以包含一个“模糊”的假表,这意味着通过始终有一行来保持标题的良好行为。

但这不起作用。一旦其中一个表为空并尝试调整列大小,表头就会损坏(其中一个列缩小)。

enter image description here

为什么会发生这种情况,我该怎么办?

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

public class SectionTables extends JFrame {

public SectionTables() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());

GridBagConstraints gbc;

JPanel tables = new ScrollableJPanel(new GridBagLayout());
JScrollPane scrollPane = new JScrollPane(tables);

JPanel section1Title = new JPanel(new BorderLayout());
section1Title.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, UIManager.getColor("controlShadow")));
JLabel section1 = new JLabel("Section One", null, JLabel.CENTER);
section1Title.add(section1);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0d;
gbc.fill = GridBagConstraints.HORIZONTAL;
tables.add(section1Title, gbc);

MyTableModel model1 = new MyTableModel();
JTable table1 = new MyTable(model1);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 1.0d;
gbc.fill = GridBagConstraints.HORIZONTAL;
tables.add(table1, gbc);

JPanel section2Title = new JPanel(new BorderLayout());
section2Title.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, UIManager.getColor("controlShadow")));
JLabel section2 = new JLabel("Section Two", null, JLabel.CENTER);
section2Title.add(section2);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 1.0d;
gbc.fill = GridBagConstraints.HORIZONTAL;
tables.add(section2Title, gbc);

MyTableModel model2 = new MyTableModel();
JTable table2 = new MyTable(model2);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 3;
gbc.weightx = 1.0d;
gbc.fill = GridBagConstraints.HORIZONTAL;
tables.add(table2, gbc);

MyTableModel modelFake = new MyTableModel();
modelFake.addRow(new String[] {"", "", ""});
JTable tableFake = new MyObscuredTable();
tableFake.setModel(modelFake);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 4;
gbc.weightx = 1.0d;
gbc.fill = GridBagConstraints.HORIZONTAL;
tables.add(tableFake, gbc);

Box.Filler filler1 = new Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(0, 32767));
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 5;
gbc.weighty = 1.0d;
gbc.fill = GridBagConstraints.VERTICAL;
tables.add(filler1, gbc);

add(scrollPane);

TableColumnModel columnModel = table1.getColumnModel();
table2.setColumnModel(columnModel);
tableFake.setColumnModel(columnModel);

JTableHeader tableHeader = new JTableHeader(columnModel);
scrollPane.setColumnHeaderView(tableHeader);
table1.setTableHeader(tableHeader);
table2.setTableHeader(tableHeader);
tableFake.setTableHeader(tableHeader);


// if tables are filled, the issue does not occur
// model1.addRow(new String[] {"", "", ""});
// model2.addRow(new String[] {"", "", ""});

pack();
setLocationRelativeTo(null);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SectionTables().setVisible(true);
}
});
}

private class MyTableModel extends DefaultTableModel {
private String[] columnNames = new String[] {"First", "Second", "Third"};
private Class[] columnClasses = new Class[] {String.class, String.class, String.class};

@Override
public int getColumnCount() {
return columnNames.length;
}

@Override
public String getColumnName(int column) {
return columnNames[column];
}

@Override
public Class<?> getColumnClass(int columnIndex) {
return columnClasses[columnIndex];
}

@Override
public boolean isCellEditable(int row, int column) {
return false;
}

}

private class ScrollableJPanel extends JPanel implements Scrollable {

public ScrollableJPanel(LayoutManager layout) {
super(layout);
}

public ScrollableJPanel() {
super();
}

@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;
}

@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;
}

@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}

@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}

}

private class MyObscuredTable extends JTable {

@Override
public Dimension getPreferredSize() {
int height;
height = 1; // obscure null row
Container ancestorOfClass = SwingUtilities.getAncestorOfClass(JPanel.class, this);
int width = ancestorOfClass.getWidth();
return new Dimension(width, height);
}

}

private class MyTable extends JTable {

public MyTable(TableModel model) {
super(model);
}

@Override
public Dimension getPreferredSize() {
int height;
height = getRowHeight() * getRowCount();
Container ancestorOfClass = SwingUtilities.getAncestorOfClass(JPanel.class, this);
int width = ancestorOfClass.getWidth();
return new Dimension(width, height);
}

}
}

最佳答案

也许您可以修改这种使用 TableColumnModelListener 的方法,以便在使用多个表时保持列宽同步:

import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableColumnsShared implements Runnable
{
JTable table1, table2;
TableColumnModelListener columnListener1, columnListener2;
Map<JTable, TableColumnModelListener> map;

public static void main(String[] args)
{
SwingUtilities.invokeLater(new TableColumnsShared());
}

public void run()
{
Vector<String> names = new Vector<String>();
names.add("One");
names.add("Two");
names.add("Three");

table1 = new JTable(null, names);
table2 = new JTable(null, names);

columnListener1 = new ColumnChangeListener(table1, table2);
columnListener2 = new ColumnChangeListener(table2, table1);

table1.getColumnModel().addColumnModelListener(columnListener1);
table2.getColumnModel().addColumnModelListener(columnListener2);

map = new HashMap<JTable, TableColumnModelListener>();
map.put(table1, columnListener1);
map.put(table2, columnListener2);

JPanel p = new JPanel(new GridLayout(2,1));
p.add(new JScrollPane(table1));
p.add(new JScrollPane(table2));

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(p);
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

class ColumnChangeListener implements TableColumnModelListener
{
JTable sourceTable;
JTable targetTable;

public ColumnChangeListener(JTable source, JTable target)
{
this.sourceTable = source;
this.targetTable = target;
}

public void columnAdded(TableColumnModelEvent e) {}
public void columnSelectionChanged(ListSelectionEvent e) {}
public void columnRemoved(TableColumnModelEvent e) {}
public void columnMoved(TableColumnModelEvent e) {}

public void columnMarginChanged(ChangeEvent e)
{
TableColumnModel sourceModel = sourceTable.getColumnModel();
TableColumnModel targetModel = targetTable.getColumnModel();
TableColumnModelListener listener = map.get(targetTable);

targetModel.removeColumnModelListener(listener);

for (int i = 0; i < sourceModel.getColumnCount(); i++)
{
targetModel.getColumn(i).setPreferredWidth(sourceModel.getColumn(i).getWidth());
}

targetModel.addColumnModelListener(listener);
}
}
}

关于java - 可滚动 (GridBagLayout) 面板内的空 JTables - 标题在列调整大小时折叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37990390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com