- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试创建一个“分段”表格,它实际上是通过 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
一切似乎都按预期工作,直到我尝试调整任一表中没有值的任意列的大小 - 如果表至少有一行,它按预期工作。我考虑过在表中有“空”行,但这会干扰过滤、排序等。所以我更改了代码以包含一个“模糊”的假表,这意味着通过始终有一行来保持标题的良好行为。
但这不起作用。一旦其中一个表为空并尝试调整列大小,表头就会损坏(其中一个列缩小)。
为什么会发生这种情况,我该怎么办?
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/
我有 0 小时、3 小时、12 小时、24 小时、48 小时的数据组……我想绘制这些数据的图表,以便保留时间的比例。 runs <- c(1:25) hours <- as.factor(c(0, 3
例如,如果我选择了时间:下午 3 点和小时数:5 小时,则得到 (8pm) 作为答案“ 最佳答案 let calendar = Calendar.current let date = calendar
我有一个包含两个日期时间字段的表单。用户输入日期 (yyyy-mm-dd) 和时间(3 个框;小时、分钟、上午/下午)。 出于某种原因,第一个没有保存为 24 小时制。 以下数据为输入结果: 2011
我一直在尝试使用导出单位进行计算,但到目前为止我还没有取得任何成果。 我已经尝试过mathjs ,但如果我输入 1 小时 * 1 英里/小时,我会得到 UnsupportedTypeError: Fu
我有两组要运行的 cronjob。第一个应该每 3 小时运行一次,第二个也应该每 3 小时运行一次,但比第一组晚一个小时。什么是正确的语法? // every 3 hours 17 */3 * *
我知道 AWS 中的预留实例更多的是计费而不是实际实例——它们没有附加到实际实例——我想知道: 如果我在特定区域和可用区中购买特定时间的预留实例 - 如果我每天 24 小时使用单个实例与运行 24 个
我试过: seq( from=as.POSIXct("2012-1-1 0", tz="UTC"), to=as.POSIXct("2012-1-3 23", tz="UTC"),
我有一个带有“日期”列的表。我想按小时分组指定日期。 最佳答案 Select TO_CHAR(date,'HH24') from table where date = TO_DATE('2011022
我知道如何在 SQL (SQL Server) 中获取当前日期,但要获取当天的开始时间: select dateadd(DAY, datediff(day, 0, getdate()),0) (res
我正在尝试在游戏之间创建一个计时器,以便用户在失去生命后必须等待 5 分钟才能再次玩游戏。但是我不确定最好的方法是什么。 我还需要它来防止用户在“设置”中编辑他们的时间。 实现这一目标的最佳方法是什么
我的查询有误。该错误显示预期的已知函数,得到“HOUR”。如果我删除这部分,查询将正常工作 (AND HOUR({$nowDate}) = 11) SELECT c FROM ProConvocati
var d1 = new Date(); var d2 = new Date(); d2.setHours(d1.getHours() +01); alert(d2); 这部分没问题。现在我试图在 (
我正在构建一个用于练习的基本时钟应用程序,但出于某种原因,时间不会自动更改为最新的分钟或小时。例如,当前时间是 17:56,但它显示的是 17:54,这是我打开应用程序的最后时间。 NSDate *n
我创建了一张图片,我想将其用作页面的 hr。当它被上传时,它一直向左对齐。我希望它居中,在标题下。这是我的 CSS 代码: .section-underline { height: 35px
这个问题已经有答案了: Getting difference in seconds from two dates in JavaScript (2 个回答) 已关闭 4 年前。 我想计算两个具有不同格
我需要计算到某个日期/时间的剩余时间(天/小时)。 但是,我没有使用静态日期。 假设我在 每个星期日 的 17:00 有一个事件。我需要显示到下一个事件的剩余时间,即即将到来的星期日 17:00。 我
我正在执行这个脚本: SELECT EXTRACT(HOUR FROM TIMEDIFF('2009-12-12 13:13:13', NOW())); 我得到:-838。这是提取时 MySQL 可以
复制代码 代码如下: /** * 小时:分钟的正则表达式检查<br> * <br> * @param pInput 要检查的字符串 * @return boolean 返
连wifi5元/小时 独领风骚 朕好帅 今晚你是我的人 十里桃花 高端定制厕所VP专用 一只老母猪 在家好无聊 你爹的wifi 密码是叫爸爸全拼 关晓彤和鹿晗分手了吗 蹭了我的
我有以下数据框列: 我需要将 csv 列中的对象字符串数据转换为总秒数。 示例:10m -> 600s 我试过这段代码: df.duration = str(datetime.timedelta(df
我是一名优秀的程序员,十分优秀!