触发setCursor方法后,光标图标不会更改

Anu*_*upD 5 java icons swing cursor

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

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

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

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

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

更新:附加示例代码

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);
}
}
Run Code Online (Sandbox Code Playgroud)

单击按钮几次,然后尝试调整表格列的大小.光标停留在默认光标上.

kle*_*tra 8

正如我的评论已经提到的:它不是完全微不足道重新/设置光标,甚至不是:-)基地问题与单个组件(在递归光标设置等)是所有组件的假设了默认光标.

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

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

  • 使glassPane(框架的rootpane)可见并在其上设置waitCursor
  • 在较小的区域上使用JLayer(jdk7)或JXLayer(jdk6)并在其上设置waitCursor
  • 使用较少侵入性的可视化,fi JProgressBar或JXBusyLabel(在SwingX项目中)某处

附录(适用于@mKorbel :-)

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

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);
}
Run Code Online (Sandbox Code Playgroud)