鼠标释放时对JTable进行排序 [英] Sort JTable when mouse released

查看:150
本文介绍了鼠标释放时对JTable进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JTable,属性AutoCreateRowSorter设置为true。它的点击工作正常,但是如果我在单击1px时移动鼠标,排序不会出现,这在某些情况下是不舒服的。如何解决这个问题?



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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆