我发现this code要在JTable
上创建标题组件,但我无法为默认标头提供相同的边框。以下是代码的屏幕截图:
此处全选复选框与第1列和第2列的边框不同,因此它看起来不同。而且与列中的向上相比,它的水平有点低。
源代码如下: -
package com.test.check.table;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
public class SelectAllHeaderTest {
private static final int BOOLEAN_COL = 2;
private static final Object colNames[] = {"Column 1", "Column 2", ""};
private DefaultTableModel model = new DefaultTableModel(null, colNames) {
@Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == BOOLEAN_COL) {
return Boolean.class;
} else {
return String.class;
}
}
};
private JTable table = new JTable(model);
public void create() {
for (int x = 1; x < 6; x++) {
model.addRow(new Object[]{
"Row " + x + ", Col 1", "Row " + x + ", Col 2", false
});
}
table.setAutoCreateRowSorter(true);
table.setPreferredScrollableViewportSize(new Dimension(320, 160));
TableColumn tc = table.getColumnModel().getColumn(BOOLEAN_COL);
tc.setHeaderRenderer(new SelectAllHeader(table, BOOLEAN_COL));
String newLookAndFeel = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
try {
UIManager.setLookAndFeel(newLookAndFeel);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JFrame f = new JFrame();
f.add(new JScrollPane(table));
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SelectAllHeaderTest().create();
}
});
}
}
/**
* A TableCellRenderer that selects all or none of a Boolean column.
*
* @param targetColumn the Boolean column to manage
*/
class SelectAllHeader extends JCheckBox implements TableCellRenderer {
private static final String ALL = "Select all";
private static final String NONE = "Select none";
private JTable table;
private TableModel tableModel;
private JTableHeader header;
private TableColumnModel tcm;
private int targetColumn;
private int viewColumn;
public SelectAllHeader(JTable table, int targetColumn) {
super(ALL);
this.table = table;
this.tableModel = table.getModel();
if (tableModel.getColumnClass(targetColumn) != Boolean.class) {
throw new IllegalArgumentException("Boolean column required.");
}
this.targetColumn = targetColumn;
this.header = table.getTableHeader();
this.tcm = table.getColumnModel();
this.applyUI();
this.addItemListener(new ItemHandler());
header.addMouseListener(new MouseHandler());
tableModel.addTableModelListener(new ModelHandler());
}
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
return this;
}
private class ItemHandler implements ItemListener {
@Override
public void itemStateChanged(ItemEvent e) {
boolean state = e.getStateChange() == ItemEvent.SELECTED;
setText((state) ? NONE : ALL);
for (int r = 0; r < table.getRowCount(); r++) {
table.setValueAt(state, r, viewColumn);
}
}
}
@Override
public void updateUI() {
super.updateUI();
applyUI();
}
private void applyUI() {
this.setFont(UIManager.getFont("TableHeader.font"));
this.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
this.setBackground(UIManager.getColor("TableHeader.background"));
this.setForeground(UIManager.getColor("TableHeader.foreground"));
}
private class MouseHandler extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
viewColumn = header.columnAtPoint(e.getPoint());
int modelColumn = tcm.getColumn(viewColumn).getModelIndex();
if (modelColumn == targetColumn) {
doClick();
}
}
}
private class ModelHandler implements TableModelListener {
@Override
public void tableChanged(TableModelEvent e) {
if (needsToggle()) {
doClick();
header.repaint();
}
}
}
// Return true if this toggle needs to match the model.
private boolean needsToggle() {
boolean allTrue = true;
boolean allFalse = true;
for (int r = 0; r < tableModel.getRowCount(); r++) {
boolean b = (Boolean) tableModel.getValueAt(r, targetColumn);
allTrue &= b;
allFalse &= !b;
}
return allTrue && !isSelected() || allFalse && isSelected();
}
}
package com.test.check.table;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
public class SelectAllHeaderTest {
private static final int BOOLEAN_COL = 2;
private static final Object colNames[] = {"Column 1", "Column 2", ""};
private DefaultTableModel model = new DefaultTableModel(null, colNames) {
@Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == BOOLEAN_COL) {
return Boolean.class;
} else {
return String.class;
}
}
};
private JTable table = new JTable(model);
public void create() {
for (int x = 1; x < 6; x++) {
model.addRow(new Object[]{
"Row " + x + ", Col 1", "Row " + x + ", Col 2", false
});
}
table.setAutoCreateRowSorter(true);
table.setPreferredScrollableViewportSize(new Dimension(320, 160));
TableColumn tc = table.getColumnModel().getColumn(BOOLEAN_COL);
tc.setHeaderRenderer(new SelectAllHeader(table, BOOLEAN_COL));
String newLookAndFeel = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
try {
UIManager.setLookAndFeel(newLookAndFeel);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JFrame f = new JFrame();
f.add(new JScrollPane(table));
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SelectAllHeaderTest().create();
}
});
}
}
/**
* A TableCellRenderer that selects all or none of a Boolean column.
*
* @param targetColumn the Boolean column to manage
*/
class SelectAllHeader extends JCheckBox implements TableCellRenderer {
private static final String ALL = "Select all";
private static final String NONE = "Select none";
private JTable table;
private TableModel tableModel;
private JTableHeader header;
private TableColumnModel tcm;
private int targetColumn;
private int viewColumn;
public SelectAllHeader(JTable table, int targetColumn) {
super(ALL);
this.table = table;
this.tableModel = table.getModel();
if (tableModel.getColumnClass(targetColumn) != Boolean.class) {
throw new IllegalArgumentException("Boolean column required.");
}
this.targetColumn = targetColumn;
this.header = table.getTableHeader();
this.tcm = table.getColumnModel();
this.applyUI();
this.addItemListener(new ItemHandler());
header.addMouseListener(new MouseHandler());
tableModel.addTableModelListener(new ModelHandler());
}
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
return this;
}
private class ItemHandler implements ItemListener {
@Override
public void itemStateChanged(ItemEvent e) {
boolean state = e.getStateChange() == ItemEvent.SELECTED;
setText((state) ? NONE : ALL);
for (int r = 0; r < table.getRowCount(); r++) {
table.setValueAt(state, r, viewColumn);
}
}
}
@Override
public void updateUI() {
super.updateUI();
applyUI();
}
private void applyUI() {
this.setFont(UIManager.getFont("TableHeader.font"));
this.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
this.setBackground(UIManager.getColor("TableHeader.background"));
this.setForeground(UIManager.getColor("TableHeader.foreground"));
}
private class MouseHandler extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
viewColumn = header.columnAtPoint(e.getPoint());
int modelColumn = tcm.getColumn(viewColumn).getModelIndex();
if (modelColumn == targetColumn) {
doClick();
}
}
}
private class ModelHandler implements TableModelListener {
@Override
public void tableChanged(TableModelEvent e) {
if (needsToggle()) {
doClick();
header.repaint();
}
}
}
// Return true if this toggle needs to match the model.
private boolean needsToggle() {
boolean allTrue = true;
boolean allFalse = true;
for (int r = 0; r < tableModel.getRowCount(); r++) {
boolean b = (Boolean) tableModel.getValueAt(r, targetColumn);
allTrue &= b;
allFalse &= !b;
}
return allTrue && !isSelected() || allFalse && isSelected();
}
}
从上面的代码我试图给复选框标题边框,但它看起来不像预期(上部和宝石边框)。
任何有关制作鞋面的建议都将受到高度赞赏。
由于
答案 0 :(得分:1)
你改变了,在运行时设置了L&amp; F,创建了Swing对象的一部分但是没有使用新的L&amp; F(Metal to Windows)刷新RootPane
从
开始在代码行public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
然后您(代码在谈论)与JToggleButton
中的JTableHeader
保持一致
a)leave that, will be better and nicer
b)删除JToggleButton
的背景信息或设置opacity
,更改Borders
为未修饰的JToggleButton
(模仿JTableHeader
中的单元格)
original code posted and screenshot by @trashgod is from Mac OSX and there is used own L&F
答案 1 :(得分:0)
根据建议,我设置了标题的边框,如
在复选框渲染器中。我修改它如下: -
header.setBorder(BorderFactory.createRaisedBevelBorder());
在runnable之前,还将我的L&amp; F代码放在静态main方法中。
它以正确的方式显示边框,我的复选框看起来很好。
非常感谢您的代码!最后它工作正常。