- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
JTable 不支持显示包含每列聚合数据的页脚。受建议解决方案的启发 Oracle/Suns bug database这看起来很有希望,我开始采用在滚动 Pane 的边框上绘制页脚的方法。
现在一开始我只想要一个“概念证明”,看起来我快到了,每列都有一个页脚,宽度是同步的。等等 所以它似乎工作得很好,除了一件事,没有文字被绘制!我希望从 getFooterValueAt
返回的虚拟值绘制在每个“页脚单元格”上,但它们都是空白的,只绘制了背景(仅用于测试)。
为什么没有绘制任何文字?我在 paintFooter
中的位置/大小计算有问题吗?
import static java.awt.BorderLayout.CENTER;
import static java.awt.Color.BLUE;
import static java.awt.Color.CYAN;
import static java.awt.Color.GREEN;
import static java.awt.Color.LIGHT_GRAY;
import static java.awt.Color.MAGENTA;
import static java.awt.Color.ORANGE;
import static java.awt.Color.PINK;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
import static java.awt.Color.YELLOW;
import static javax.swing.JTable.AUTO_RESIZE_OFF;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.swing.CellRendererPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
/**
* Demo application for JTable with footer.
*
* @author Martin Uhlén
*/
public class TableFooterBorderDemo extends JFrame
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new TableFooterBorderDemo().setVisible(true);
}
});
}
private TableFooterBorderDemo()
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
JTable table = createTable();
JScrollPane scroll = new JScrollPane(table);
add(scroll, CENTER);
TableFooter.install(scroll, table);
pack();
positionAtMiddleOfScreen();
}
private void positionAtMiddleOfScreen()
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((int) ((screenSize.getWidth() / 2) - (getWidth() / 2)),
(int) ((screenSize.getHeight() / 2) - (getHeight() / 2)));
}
private JTable createTable()
{
Object[][] data = new Object[][]
{
{ "A", "*", "*", "*", "*", "*" },
{ "*", "B", "*", "*", "*", "*" },
{ "*", "*", "C", "*", "*", "*" },
{ "*", "*", "*", "D", "*", "*" },
{ "*", "*", "*", "*", "E", "*" },
{ "*", "*", "*", "*", "*", "F" }
};
Object[] columns = new Object[] { "A", "B", "C", "D", "E", "F" };
DefaultTableModel model = new DefaultTableModel(data, columns);
JTable table = new JTable(model);
table.setAutoResizeMode(AUTO_RESIZE_OFF);
return table;
}
/**
* A Border for JScrollPane that paints a footer for JTable.
*/
private static class TableFooter implements Border
{
private static final Color[] COLORS = {RED, GREEN, BLUE, YELLOW, PINK, CYAN, LIGHT_GRAY, MAGENTA, ORANGE, WHITE};
private final JScrollPane scroll;
private final JTable table;
private final CellRendererPane cellRendererPane;
TableFooter(JScrollPane scroll, JTable table)
{
this.scroll = scroll;
this.table = table;
cellRendererPane = new CellRendererPane();
}
public static TableFooter install(JScrollPane scroll, JTable table)
{
verify(scroll, table);
TableFooter footer = new TableFooter(scroll, table);
RepaintListener repainter = new RepaintListener(scroll);
scroll.getViewport().addChangeListener(repainter);
scroll.getHorizontalScrollBar().addAdjustmentListener(repainter);
table.getColumnModel().addColumnModelListener(repainter);
scroll.setViewportBorder(footer);
return footer;
}
private static void verify(JScrollPane scroll, JTable table)
{
if (scroll.getViewport().getView() != table)
{
throw new IllegalArgumentException("Given table must be inside given scroll pane");
}
}
/**
* @see javax.swing.border.Border#paintBorder(java.awt.Component, java.awt.Graphics, int, int, int, int)
*/
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
{
System.out.println("x: " + x + ", y: " + y + ", width: " + width + ", height: " + height);
System.out.println("viewRect: " + scroll.getViewport().getViewRect());
paintFooter(g, x, y, width, height);
}
private void paintFooter(Graphics g, int x, int y, int width, int height)
{
Color oldColor = null;
Component cellRendererComponent = null;
int columnWidths = x - scroll.getViewport().getViewRect().x;
for (int column = 0; column < table.getColumnCount(); column++)
{
TableCellRenderer cellRenderer = table.getCellRenderer(0, column);
cellRendererComponent = cellRenderer.getTableCellRendererComponent(table, getFooterValueAt(column), false, false, 0, column);
if (oldColor == null)
{
oldColor = cellRendererComponent.getBackground();
}
int columnWidth = table.getColumnModel().getColumn(column).getWidth();
cellRendererComponent.setBackground(COLORS[column % COLORS.length]);
cellRendererPane.paintComponent(g, cellRendererComponent, scroll, columnWidths, y, columnWidth, height);
columnWidths += columnWidth;
}
if (cellRendererComponent != null)
{
cellRendererComponent.setBackground(oldColor);
}
}
private Object getFooterValueAt(int viewColumn)
{
return "Column " + viewColumn;
}
@Override
public Insets getBorderInsets(Component c)
{
return new Insets(0, 0, table.getRowHeight(), 0);
}
@Override
public boolean isBorderOpaque()
{
return true;
}
}
/**
* Repaints JScrollPane when needed.
*/
private static class RepaintListener implements ChangeListener, AdjustmentListener, TableColumnModelListener
{
private final JScrollPane scroll;
RepaintListener(JScrollPane scroll)
{
this.scroll = scroll;
}
@Override
public void columnAdded(TableColumnModelEvent e)
{
repaint();
}
@Override
public void columnRemoved(TableColumnModelEvent e)
{
repaint();
}
@Override
public void columnMoved(TableColumnModelEvent e)
{
repaint();
}
@Override
public void columnMarginChanged(ChangeEvent e)
{
repaint();
}
@Override
public void columnSelectionChanged(ListSelectionEvent e)
{
repaint();
}
@Override
public void adjustmentValueChanged(AdjustmentEvent e)
{
repaint();
}
@Override
public void stateChanged(ChangeEvent e)
{
repaint();
}
private void repaint()
{
scroll.repaint();
}
}
}
最佳答案
问题是 rendererPane 的位置:您的代码中发生的是标签位于 x/y,即靠近具有视口(viewport)矩形完整高度的上边界线,然后文本被绘制在某处视口(viewport)的中间,后来被视口(viewport)覆盖。要查看效果,请使用零行 tableModel 并使视口(viewport)不透明。
相反,您必须将它定位在边框的底部。一个非常脏(没有做任何事情来使其像素正确,在周末运行时:) 片段
g.setColor(Color.RED);
int scrollBottom = scroll.getInsets().bottom;
int lowerBorderTop = height - scrollBottom;
g.drawLine(x, height - scrollBottom - 1, width - 10, height - scrollBottom - 1);
g.drawRect(x + 1, height - scrollBottom, width - 10, 10);
Color oldColor = null;
Component cellRendererComponent = null;
int columnWidths = x ;//- scroll.getViewport().getViewRect().x;
for (int column = 0; column < table.getColumnCount(); column++)
{
TableCellRenderer cellRenderer = table.getCellRenderer(0, column);
cellRendererComponent = cellRenderer.getTableCellRendererComponent(table,
getFooterValueAt(column), false, false, 0, column);
if (oldColor == null)
{
oldColor = cellRendererComponent.getBackground();
}
int columnWidth = table.getColumnModel().getColumn(column).getWidth();
cellRendererComponent.setForeground(Color.BLACK);
cellRendererComponent.setBackground(COLORS[column % COLORS.length]);
cellRendererPane.paintComponent(g, cellRendererComponent, scroll, columnWidths,
lowerBorderTop , columnWidth, table.getRowHeight(), false);
columnWidths += columnWidth;
}
if (cellRendererComponent != null)
{
cellRendererComponent.setBackground(oldColor);
}
额外的线和矩形只是为了看看我们在哪里。顺便说一句,不错的方法:-)
关于java - JTable 的页脚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9131355/
我已经多次看到我的问题被问到,但我从未看到我期望的答案。我已经在 JTable 中输入了数据库的元素,并且我希望能够通过一些 JButtons 删除/添加元素。问题是当我添加/删除时,修改在数据库
我正在使用 JTable 做一个项目,我想让我的表格单元格可编辑。我用过, public boolean isCellEditable(int row, int column) {
我正在编写一个应用程序包,其中包含一个主类,其中主方法与GUI类分开,GUI类包含一个带有jtabbedpane的jframe,它有两个选项卡,第一个选项卡包含一个jtable,称为jtable1,第
我制作了一个表格来将 Arraylist 中的数据加粗,但如果我删除该数据,我会希望该表格更新并取消对 Arraylist 中加粗的单元格的粗体显示。我该怎么做呢?或从另一个类关闭该类的实例 最佳答案
如果我的 JTable 的列未按字母顺序排列,我可以使用 getSelectedRows() 并毫无问题地获取它们的行的值。但是,如果用户单击列名并且行在该列中按字母顺序排列,则 getSelecte
我有一个 JTable,用户可以在其中在单元格中输入数据。然后有一个“保存”按钮,用于收集表格数据,将其格式化为 csv,并将其保存到文件中。 但是,如果用户将最后编辑的单元格保留在选定状态,并单击“
我编写了下面的代码,以便在当前 JTable 上进行选择时创建一个新的 JTable: makeTbale.addActionListener(new ActionListener() { pub
我正在使用 Swing 编写 Java 应用程序。我有两个表,我必须将内容从一个表复制到另一个表(复制)。问题是,如果我清除目标表行,那么我的源表行也会被删除。 如果我按 CopyAll,那么我会将
我一直致力于JTable,我的项目: 从数据库读取数据(我完成了这个任务并能够在JTable中显示)。 然后将数据按子组显示并保存到文件(文本/Excel)中。 我有 JTable 的基本知识,并且使
我有以下类(class): public class customer_master extends javax.swing.JInternalFrame { Connection con =
您好,我是 JAVA 的新手,在学习时正在开发 GUI。我创建了一个带有 ScrollPane 和 JTable 的 JFrame。当我增加 2 列以上时,第一行下方的数据不会显示。 此外,当我的 J
我正在进行项目的最后一部分,这是我遇到的最后问题之一。这部分用于编辑预订,即更改为特定预订预订的房间。我有 2 个 JTable,其中一个有可用房间,另一个有已预订的房间。两者都有单独的 Defaul
我有 2 个 JTable,我需要从表 2 中复制特定列(包括该列中的所有数据)并将其添加到表 1 中的下一个空闲列中。有人知道执行此操作的最佳方法吗? 谢谢 最佳答案 DefaultTableMod
美好的一天!我在 Jtable 方面遇到了困难。我已经阅读和浏览了各种教程,但我不太明白它的要点。我的问题是,我必须从 jtable (jTable1) 中选择包含 (ClientID、LastNam
我的 SERVER 表单上有一个 JTable,它是从 MySQL 数据库填充的,在构造函数中编码: String sql = "SELECT * from fiekorari"; t
我在我的项目上工作,我需要将一行从 JTable 复制到另一个 JTable,第二个 JTable 应该只是单行表。我为第一个 JTable 创建了 mouselistener,双击它应该复制行并将其
我有这段代码可以完全按预期工作 package com.grantbroadwater.signInAssistant.view; import java.awt.BorderLayout; impo
我有一个列表人员(在 jTable 中)并想将其导出到 excel 文件我需要每个人转到单独的工作表所以我需要拆分原始 jTable,但我不知道如何? 这就是我想做的? public void exp
我有一个包含 7 列和 2 行的 JTable。在我的 JTable 下方,我有一个 JTextField。当我在 JTextField 中输入内容时,我可以很容易地得到我输入的内容:String l
我正在尝试将一个 JTable 嵌套在另一个 JTable 的列中(使用 CellRenderer)。 示例(错误)输出: 为什么下面的例子没有输出表中表? import java.awt.Compo
我是一名优秀的程序员,十分优秀!