触发setCursor方法后,光标图标不会更改 [英] Cursor icon does not change after triggering setCursor method

查看:152
本文介绍了触发setCursor方法后,光标图标不会更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一个 JTable ,带有可调整大小的标题列。通常当我将光标移到表头以进行调整大小时,光标图标会更改为调整大小箭头,例如< - >。

There is a JTable in my application with resizable header columns. Normally when I move the cursor over table header for resizing, the cursor icon changes to resize arrow, like <-->.

但是在以下场景中情况有所不同。

But things are different in the following scenario.

在同一个 Frame 中有一个按钮动作,并且在执行动作期间,我将光标设置为忙碌图标,并在操作完成后将其更改回默认光标,使用 Container.setCurosr(光标光标)方法。

There is a button action in the same Frame, and during action performed, I am setting the cursor to busy icon and change it back to default cursor once the action is completed, using Container.setCurosr(Cursor cursor) method.

有时如果我将光标移到调整大小的表头上,在按钮操作后,光标图标不会更改为调整大小箭头,光标根本不会改变。

Sometimes if I move the cursor over table header of resizing, after a button action, the cursor icon does not change to resize arrow, cursor does not change at all.

这可以被视为Java Swing中的一个错误,还是有解决此问题的方法?

Can this be considered as a bug in Java Swing or is there a solution for this issue?

更新:附加示例代码

import java.util.*;  
import java.awt.*;  
import javax.swing.*;  
import java.awt.event.*;

public class ColumnResizeIconTest extends JFrame {

JScrollPane scrollPane;
JTable table;
JButton button;

public ColumnResizeIconTest() {
    setLayout(new BorderLayout());
    addComponents();
    setSize(300,300);
}

private void addComponents() {
    addButton();
    addTable();
}

private void addButton() {
    button = new JButton("Click Me");
    button.addActionListener( new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            setWaitCursor();
            for(int i=0; i<2000; i++) {
                System.out.print(i);
            }
            setDefaultCursor();
        }
    });
    add(button, BorderLayout.NORTH);
}

private void addTable() {
    scrollPane = new JScrollPane(createTable());
    add(scrollPane, BorderLayout.CENTER);
}

private JTable createTable() {
    Object[][] cellData = { { "1-1", "1-2","1-3" }, { "2-1", "2-2", "2-3" }, { "3-1", "3-2", "3-3" } };
    String[] columnNames = { "column1", "column2", "column3" };
    table = new JTable(cellData, columnNames);
    return table;
}

private void setWaitCursor() {
    Container container = getContentPane();
    setWaitCursor(container);
}

private void setWaitCursor(Container container) {
    for(int iCount = 0; iCount < container.getComponentCount(); iCount++) {
        Component child = (Component) container.getComponent(iCount);
        if(child instanceof Container) {
            setWaitCursor((Container) child);
        } else {
            child.setCursor(new Cursor(Cursor.WAIT_CURSOR));
        }
    }
    container.setCursor(new Cursor(Cursor.WAIT_CURSOR));
}

private void setDefaultCursor() {
    Container container = getContentPane();
    setDefaultCursor(container);
}

private void setDefaultCursor(Container container) {
    for(int iCount = 0; iCount < container.getComponentCount(); iCount++) {
        Component child = (Component) container.getComponent(iCount);
        if(child instanceof Container) {
            setDefaultCursor((Container) child);
        } else {
            child.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        }
    }
    container.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}

public static void main(String[] argv) throws Exception {
    ColumnResizeIconTest test = new ColumnResizeIconTest();
    test.setVisible(true);
}
}

点击按钮几次并尝试调整大小表格列。光标停留在默认光标上。

Click on the button a few times and try to resize the table column. The cursor is stuck with Default cursor.

推荐答案

正如我在评论中已经提到的那样:重新设置光标并不是一件容易的事。游标,甚至不是单个组件:-)基本问题(在等待的递归游标设置中)假设所有组件都有默认游标。

As already mentioned in my comment: it's not entirely trivial to re-/set the cursors, not even for a single component :-) The base problem (in the recursive cursor setting to wait) is the assumption that all components do have the default cursor.

正如您在表头上看到的那样,该假设不正确:在该组件上,default是defaultCursor或resizeCursor,具体取决于鼠标位置。此外,内部光标切换不是很聪明:它不会检查状态(从我的头顶,刚刚被这个事实击中: - )

As you see on the table header, that assumption is not correct: on that component, the "default" is either the defaultCursor or the resizeCursor, depending on mouse location. Additionally, the internal cursor toggling is not very intelligent: it doesn't check for state (from the top of my head, was hit by that fact a while ago :-)

不完全确定你想达到什么,所以没有具体的解决方案,除了完全放弃递归设置,它太难以正确。选项可能是

Not entirely sure what you want to reach, so don't have a concrete solution, except dropping the recursive setting entirely, it's too hard to get right. Options might be


  • 使glassPane(框架的rootpane)可见并在其上设置waitCursor

  • 在较小的区域使用JLayer(jdk7)或 JXLayer (jdk6)并在其上设置waitCursor

  • 使用较少侵入性的可视化,fi JProgressBar或JXBusyLabel(在某个地方在SwingX项目中

  • make the glassPane (of the frame's rootpane) visible and set the waitCursor on it
  • use JLayer (jdk7) or JXLayer (jdk6) on a smaller area and set the waitCursor on that
  • use a less intrusive visualization, f.i. JProgressBar or a JXBusyLabel (in the SwingX project) somewhere

附录(对于@mKorbel: - )

Addendum (for @mKorbel :-)

问题很容易重现,只需稍加改动即可OPs SSCCE(多亏了!):如下所示更改addButton方法,然后单击按钮,在显示等待光标时,将鼠标移动到标题中,然后移动到另一列(跨列边框)。多次这样做会导致标题上出现不可预测的游标...

the problem is easily reproducible, with a little change to the OPs SSCCE (thanks for that!): change the addButton method as below, then click on the button and while the wait cursor is shown, move the mouse into the header and then to another column (across the column border). Doing so several times will lead to unpredicable cursors on the header ...

private void addButton() {
    button = new JButton("Click Me");
    final ActionListener off = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            setDefaultCursor();
            button.setEnabled(true);
        }

    };
    button.addActionListener( new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            setWaitCursor();
            button.setEnabled(false);
            Timer timer = new Timer(2000, off);
            timer.setRepeats(false);
            timer.start();
        }
    });

    add(button, BorderLayout.NORTH);
}

这篇关于触发setCursor方法后,光标图标不会更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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