鼠标释放时对JTable进行排序 [英] Sort JTable when mouse released
问题描述
UPD我只想在鼠标释放时出现排序。
如果你不是绝对绝望,并且确切地知道你在做什么,那么一个脏的(请看: )方法是钩住由uiDelegate安装的MouseListener,并移动将触发器排序到释放的方法中。这涉及
- 一个自定义的MouseListener,它将除了点击的所有事件委托给最初安装和排序的所有事件,然后传递发布的
- 用原来的定制
- 更换原稿,只要更改LAF(因为原稿由ui控制)。这需要JTableHeader的子类化,并在updateUI中执行接线
自定义侦听器
public static class EventHook实现MouseListener {
private JTableHeader header;
private MouseListener delegate;
public EventHook(JTableHeader header){
this.header = header;
installHook();
}
protected void installHook(){
MouseListener [] listeners = header.getMouseListeners(); (int i = 0; i< listeners.length; i ++){
MouseListener l = listeners [i];
if(l.getClass()。getName()。contains(TableHeaderUI)){
this.delegate = l;
listeners [i] = this;
}
header.removeMouseListener(l);
}
(MouseListener l:listeners){
header.addMouseListener(l);
}
}
public void uninstallHook(){
MouseListener [] listeners = header.getMouseListeners(); (int i = 0; i< listeners.length; i ++){
MouseListener l = listeners [i];
if(l == this){
listeners [i] = delegate;
}
header.removeMouseListener(l);
}
(MouseListener l:listeners){
header.addMouseListener(l);
}
}
@Override
public void mouseReleased(MouseEvent e){
//在调用super
之前排序sort(e) ;
delegate.mouseReleased(e);
}
private void sort(MouseEvent e){
if(!header.isEnabled()){
return;
}
//如果拖动
if(header.getDraggedDistance()!= 0){
return;
}
if(e.getClickCount()%2 == 1&&
SwingUtilities.isLeftMouseButton(e)){
JTable table = header.getTable();
RowSorter分拣机
if(table!= null&&((sorter = table.getRowSorter())!= null){
int columnIndex = header.columnAtPoint(e.getPoint());
if(columnIndex!= -1){
columnIndex = table.convertColumnIndexToModel(
columnIndex);
sorter.toggleSortOrder(columnIndex);
}
}
}
}
@Override
public void mouseClicked(MouseEvent e){
//吞下点击 - 要触发排序发布
}
@Override
public void mousePressed(MouseEvent e){
delegate.mousePressed(e);
}
@Override
public void mouseEntered(MouseEvent e){
delegate.mouseEntered(e);
}
@Override
public void mouseExited(MouseEvent e){
delegate.mouseExited(e);
}
}
子类JTableHeader
public static class MyTableHeader extends JTableHeader {
private EventHook hook;
public MyTableHeader(TableColumnModel model){
super(model);
}
@Override
public void updateUI(){
if(hook!= null){
hook.uninstallHook();
hook = null;
}
super.updateUI();
hook = new EventHook(this);
}
}
用法,是子类JTable和覆盖createDefaultTableHeader或手动设置标题:
//子类
JTable table = new JTable(new AncientSwingTeam()) {
@Override
protected JTableHeader createDefaultTableHeader(){
return new MyTableHeader(getColumnModel());
}
};
table.setAutoCreateRowSorter(true);
I have a JTable with property AutoCreateRowSorter set to true. It works fine on click, but if I move mouse during click just for 1px, sorting does not appear, which is uncomfortable in some situations. How to fix this?
UPD I just want sorting to appear when mouse released.
A dirty (read: don't if you aren't absolutely desperate and know exactly what you doing!) approach is to hook into the MouseListener installed by the uiDelegate and move the sort trigger into the released method. This involves
- a custom MouseListener which delegates all events except the clicked to the originally installed and sorts before passing on the released
- replace the original with the custom
- update the replacement whenever the LAF is changed (because the original is controlled by the ui). This requires subclassing of JTableHeader and do the wiring in updateUI
The custom listener:
public static class EventHook implements MouseListener {
private JTableHeader header;
private MouseListener delegate;
public EventHook(JTableHeader header) {
this.header = header;
installHook();
}
protected void installHook() {
MouseListener[] listeners = header.getMouseListeners();
for (int i = 0; i < listeners.length; i++) {
MouseListener l = listeners[i];
if (l.getClass().getName().contains("TableHeaderUI")) {
this.delegate = l;
listeners[i] = this;
}
header.removeMouseListener(l);
}
for (MouseListener l : listeners) {
header.addMouseListener(l);
}
}
public void uninstallHook() {
MouseListener[] listeners = header.getMouseListeners();
for (int i = 0; i < listeners.length; i++) {
MouseListener l = listeners[i];
if (l == this) {
listeners[i] = delegate;
}
header.removeMouseListener(l);
}
for (MouseListener l : listeners) {
header.addMouseListener(l);
}
}
@Override
public void mouseReleased(MouseEvent e) {
// sort before calling super
sort(e);
delegate.mouseReleased(e);
}
private void sort(MouseEvent e) {
if (!header.isEnabled()) {
return;
}
// do nothing if dragged
if (header.getDraggedDistance() != 0) {
return;
}
if (e.getClickCount() % 2 == 1 &&
SwingUtilities.isLeftMouseButton(e)) {
JTable table = header.getTable();
RowSorter sorter;
if (table != null && (sorter = table.getRowSorter()) != null) {
int columnIndex = header.columnAtPoint(e.getPoint());
if (columnIndex != -1) {
columnIndex = table.convertColumnIndexToModel(
columnIndex);
sorter.toggleSortOrder(columnIndex);
}
}
}
}
@Override
public void mouseClicked(MouseEvent e) {
// swallow the clicked - want to trigger sort on released
}
@Override
public void mousePressed(MouseEvent e) {
delegate.mousePressed(e);
}
@Override
public void mouseEntered(MouseEvent e) {
delegate.mouseEntered(e);
}
@Override
public void mouseExited(MouseEvent e) {
delegate.mouseExited(e);
}
}
The subclassed JTableHeader
public static class MyTableHeader extends JTableHeader {
private EventHook hook;
public MyTableHeader(TableColumnModel model) {
super(model);
}
@Override
public void updateUI() {
if (hook != null) {
hook.uninstallHook();
hook = null;
}
super.updateUI();
hook = new EventHook(this);
}
}
Usage, either subclass JTable and override createDefaultTableHeader or manually set the header:
// either subclass
JTable table = new JTable(new AncientSwingTeam()) {
@Override
protected JTableHeader createDefaultTableHeader() {
return new MyTableHeader(getColumnModel());
}
};
table.setAutoCreateRowSorter(true);
这篇关于鼠标释放时对JTable进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!