触发setCursor方法后光标图标不改变
我的应用程序中有一个带有可调整大小的标题列的 JTable。通常,当我将光标移到表格标题上以调整大小时,光标图标会更改为调整大小箭头,例如<-->。
但在下面的场景中情况有所不同。
在同一个框架中有一个按钮操作,在执行操作期间,我将光标设置为忙碌图标,并在操作完成后使用 Container.setCursor 将其更改回默认光标(光标光标) 方法。
有时,如果我将光标移动到调整大小的表标题上,则在按钮操作后,光标图标不会更改为调整大小箭头,光标根本不会改变。
这可以被视为 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);
}
}
单击按钮几次并尝试调整表列的大小。光标卡在默认光标上。
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.
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.setCursor(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.
Can this be considered as a bug in Java Swing or is there a solution for this issue?
Update : Sample code attached
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如我的评论中已经提到的:重新/设置光标并不是完全微不足道的,即使对于单个组件也不是:-)基本问题(在递归光标设置中等待)是假设所有组件都这样做 有默认光标。
正如您在表标题上看到的,该假设是不正确的:在该组件上,“默认”是 defaultCursor 或 resizeCursor,具体取决于鼠标位置。此外,内部光标切换不是很智能:它不会检查状态(从我的头顶上看,不久前就被这个事实击中了:-)
不完全确定你想要达到什么,所以不要有一个具体的解决方案,除了完全放弃递归设置之外,很难得到正确的结果。选项可能是
附录(对于@mKorbel :-)
这个问题很容易重现,对 OP SSCCE 进行一些更改(谢谢!):更改 addButton 方法如下,然后单击按钮,当显示等待光标时,将鼠标移到标题中,然后移到另一列(跨列) 边界)。这样做几次会导致标题上出现不可预测的光标......
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.
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
Addendum (for @mKorbel :-)
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 ...
1)您已将代码重定向
到后台任务,您可以实现 javax. swing.Timer,SwingWorker,或将这些代码行包装在 Runnable#Thread 内,例如这里
2)你必须恢复
Cursor
也出现在Error/Exception
上,这可能就是 Cursor 没有更改的原因1) you have redirect code
to the BackGround Task, you can implements javax.swing.Timer, SwingWorker, or wrap these code lines inside Runnable#Thread, example here
2) you have to restore
Cursor
onError/Exception
too, that's probably reason why Cursor wasn't changed