这是Java swing awt相关的问题。 我正在使用JXTable(JTable的扩展)。该表有3个固定(始终显示)列。让我们打电话给他们" OK-COLS"因为它们是按要求显示的。 OK-COL的标题有两个组件= JLabel(表示列名)和JButton(用于排序该列) 该表可以有一个或多个" NOT-OK-COLS"在运行时。 NOT-OK-COLS的标题包含3个组件: - JLabel(表示列名),组合框(用于过滤表)和排序按钮。
问题: - 如果单击NOT-OK-COL进行排序,然后调整列宽,则该列的标题不会立即调整为新的列宽。 调整NOT-OK-COL的大小后,如果单击其他列标题,则NOT-OK-COL标题会根据列宽正确调整大小。
需要帮助才能找到问题发生的原因以及解决方法。 该表使用自己的自定义渲染器。
附上一些截图供参考: -
3)当NOT-OK-COL调整大小时(不进行排序......左侧宽度的第1列增加)
4)当NOT-OK-COL被分类并调整大小时(LHS'宽度的第一列减少)
从上一张图片可以看出,"价值2"列标题与第1列的标题重叠,它没有重新调整为实际的新宽度。
现在,如果我点击任何其他标题,第1列的标题将根据需要自动调整大小(类似于图像#2)
以下是示例的类。
DemoClass.java(public static void main)
EditableHeaderRenderer.java
~~~~~~~~~~~~~~~~~~~~~
package com.tejpal.finalHeader.two;
import javax.swing.*;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import java.awt.*;
public class DemoClass extends JFrame {
/**
* Main class that will fire up the UI on the screen
*
*/
private static final long serialVersionUID = 1L;
public DemoClass() {
super("Main Frame");
JPanel cPane = (JPanel) getContentPane();
cPane.setLayout(new BorderLayout());
// List of values for the combo box
String[] list = {"tejpal","singh","chouhanfromkhnadwa"};
DefaultTableColumnModel tableModel = new DefaultTableColumnModel();
TableColumn col = null;
JPanel firstpanel = new JPanel(new BorderLayout());
/**
* This subpanel holds the three components.
* Label, combobox, Sort Button
*/
JPanel subPanel = new JPanel(new BorderLayout());
//Add Label to the header panel
subPanel.add( new JLabel("Label"), BorderLayout.WEST);
//Add combo box to the header panel
subPanel.add( new JComboBox<String>(list));
// Add sort button to the header panel
JButton sortWidget = new JButton();
sortWidget.setOpaque(false);
sortWidget.setContentAreaFilled(false);
sortWidget.setBorderPainted(false);
sortWidget.setHorizontalAlignment(SwingConstants.LEFT);
sortWidget.setIcon(UIManager.getIcon("Table.ascendingSortIcon") );
subPanel.add( sortWidget,BorderLayout.EAST);
//adding subpanel to firstPanel
firstpanel.add(subPanel);
firstpanel.setSize(10, 100);
firstpanel.setVisible(true);
col = new TableColumn(0);
col.setPreferredWidth( 100 );
col.setMinWidth( 100 );
//EditableHeaderRenderer implements TableCellRenderer and rendered column as header of table with panel
col.setHeaderRenderer(new EditableHeaderRenderer(firstpanel));
tableModel.addColumn(col);
JPanel secondPanel = new JPanel(new BorderLayout());
// second panel with label and button
JPanel subPanelSecond = new JPanel(new BorderLayout());
//Add Label to the header panel
subPanelSecond.add( new JLabel("Label"));
// Add sort button to the header panel
JButton sortWidgetSecond = new JButton();
sortWidgetSecond.setOpaque(false);
sortWidgetSecond.setContentAreaFilled(false);
sortWidgetSecond.setBorderPainted(false);
sortWidgetSecond.setHorizontalAlignment(SwingConstants.LEFT);
subPanelSecond.add( sortWidgetSecond,BorderLayout.EAST);
sortWidgetSecond.setIcon(UIManager.getIcon("Table.ascendingSortIcon") );
// adding subPanelSecond on secondPanel
secondPanel.add(subPanelSecond);
secondPanel.setSize(10, 100);
secondPanel.setVisible(true);
col = new TableColumn(1);
col.setPreferredWidth( 100 );
col.setMinWidth( 100 );
//EditableHeaderRenderer implements TableCellRenderer and rendered column as header of table with panel
col.setHeaderRenderer(new EditableHeaderRenderer(secondPanel));
tableModel.addColumn(col);
col = new TableColumn(2);
col.setPreferredWidth( 100 );
col.setMinWidth( 100 );
//EditableHeaderRenderer implements TableCellRenderer and rendered column as header of table with panel
col.setHeaderRenderer(new EditableHeaderRenderer(secondPanel));
tableModel.addColumn(col);
col = new TableColumn(3);
col.setPreferredWidth( 100 );
col.setMinWidth( 100 );
//EditableHeaderRenderer implements TableCellRenderer and rendered column as header of table with panel
col.setHeaderRenderer(new EditableHeaderRenderer(secondPanel));
tableModel.addColumn(col);
JTable table = new JTable(new DefaultTableModel(), tableModel);
// code for insert row data in table
DefaultTableModel model = new DefaultTableModel();
for(int i=0;i<table.getColumnCount();i++){
model.addColumn(table.getColumnModel().getColumn(i));
}
Object[] rowDate0 = new Object[]{new Integer(21), "b", "c","d"};
Object[] rowDate1 = new Object[]{new Integer(11), "11","chouhan","khandwa"};
Object[] rowDate2 = new Object[]{new Integer(27),"11","abc", "test"};
Object[] rowDate3 = new Object[]{new Integer(2),"a", "b", "3"};
model.addRow(rowDate0);
model.addRow(rowDate1);
model.addRow(rowDate2);
model.addRow(rowDate3);
table.setModel(model);
table.setAutoCreateRowSorter(true);
JScrollPane scrollPane = new JScrollPane(table);
cPane.add(scrollPane, BorderLayout.PAGE_START);
setSize(800, 200);
setResizable(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String... args) {
// main class
new DemoClass();
}
}
~~~~~~~~~~~~~~~~~~~~~
package com.tejpal.finalHeader.two;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
/**
* EditableHeaderRenderer implements TableCellRenderer and rendered column as header of table with panel
*
*/
class EditableHeaderRenderer extends JPanel implements TableCellRenderer {
private static final long serialVersionUID = 1L;
private static JTable table = null;
private MouseEventReposter reporter = null;
private JComponent editor;
// passed jbomponent will be displayed on header of table
EditableHeaderRenderer(JComponent editor) {
this.editor = editor;
this.editor.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
if (table != null && EditableHeaderRenderer.table != table) {
table.setAutoCreateRowSorter(false);
EditableHeaderRenderer.table = table;
final JTableHeader header = table.getTableHeader();
if (header != null) {
header.setSize(new Dimension(150,80));
System.out.println(header.getDefaultRenderer()+ " :::::::: ");
this.editor.setForeground(header.getForeground());
this.editor.setBackground(header.getBackground());
this.editor.setFont(header.getFont());
// calling mouse event.
reporter = new MouseEventReposter(header, col, this.editor);
header.addMouseListener(reporter);
}
}
return this.editor;
}
/**
* EditableHeaderRenderer extends MouseAdapter to perform any mouse action like click,pressed,release ....etc
*
*/
static public class MouseEventReposter extends MouseAdapter {
private Component dispatchComponent;
private JTableHeader header;
private int column = -1;
private Component editor;
public MouseEventReposter(JTableHeader header, int column, Component editor) {
this.header = header;
this.column = column;
this.editor = editor;
}
public MouseEventReposter() {
// TODO Auto-generated constructor stub
}
public void setColumn(int column) {
this.column = column;
}
private void setDispatchComponent(MouseEvent e) {
int col = header.getTable().columnAtPoint(e.getPoint());
if (col != column || col == -1) return;
Point p = e.getPoint();
Point p2 = SwingUtilities.convertPoint(header, p, editor);
dispatchComponent = SwingUtilities.getDeepestComponentAt(editor, p2.x, p2.y);
}
private boolean repostEvent(MouseEvent e) {
if (dispatchComponent == null) {
return false;
}
MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e, dispatchComponent);
dispatchComponent.dispatchEvent(e2);
return true;
}
@Override
public void mouseReleased(MouseEvent e) {
dispatchComponent = null;
header.remove(editor);
repostEvent(e);
}
@Override
public void mouseClicked(MouseEvent event) {
String[] list = {"tejpal","singh","chouhan"};
int col1 = table.columnAtPoint(event.getPoint());
String name = table.getColumnName(col1);
System.out.println("Column index selected " + col1 + " " + name);
// on mouse click changing the image of button for sorting.selecting column index and changing sort image of particular column.
if(col1==0){
if (header.getResizingColumn() == null) {
Point p = event.getPoint();
int col = header.getTable().columnAtPoint(p);
if (col != column || col == -1) return;
int index = header.getColumnModel().getColumnIndexAtX(p.x);
if (index == -1) return;
editor.setBounds(header.getHeaderRect(index));
header.add(editor);
editor.validate();
setDispatchComponent(event);
repostEvent(event);
}
TableColumn column = table.getColumnModel().getColumn(0);
//JPanelMainClass m = new JPanelMainClass(list, 1+"");
//EditableHeaderRenderer implements TableCellRenderer and rendered column as header of table with panel
JPanel firstpane = new JPanel(new BorderLayout());
JPanel subPanel = new JPanel(new BorderLayout());
//Add Label to the header panel
JLabel label = new JLabel("Label");
subPanel.add(label, BorderLayout.WEST);
//Add combo box to the header panel
subPanel.add( new JComboBox<String>(list));
// Add sort button to the header panel
final JButton sortWidget = new JButton();
sortWidget.setOpaque(false);
sortWidget.setContentAreaFilled(false);
sortWidget.setBorderPainted(false);
sortWidget.setHorizontalAlignment(SwingConstants.LEFT);
sortWidget.setIcon(UIManager.getIcon("Table.ascendingSortIcon") );
subPanel.add( sortWidget,BorderLayout.EAST);
//adding a label,combobox and button on panel and button has image icon. that can be ascending or descending
firstpane.add(subPanel);
firstpane.setSize(10, 100);
firstpane.setVisible(true);
column.setHeaderRenderer(new EditableHeaderRenderer(firstpane));
// table.setAutoCreateRowSorter(true);
}
}}
}
~~~~~~~~~~~~~~~~~~~~~