У меня возникают проблемы с отображением курсора ожидания в моем приложении. Всякий раз, когда мышь находится над панелью, которая определяет свой собственный курсор, курсор ожидания не появляется. Если панель не изменит курсор, появится курсор ожидания.
Я подключаю SSCE, чтобы точно объяснить мою проблему.
public class BusyCursorTest extends javax.swing.JFrame {
public BusyCursorTest() {
javax.swing.JMenuBar menuBar = new javax.swing.JMenuBar();
javax.swing.JMenu menu = new javax.swing.JMenu("Menu");
javax.swing.JMenuItem wait1 = new javax.swing.JMenuItem("Wait 100 ms");
javax.swing.JMenuItem wait2 = new javax.swing.JMenuItem("Wait 250 ms");
javax.swing.JMenuItem wait3 = new javax.swing.JMenuItem("Wait 500 ms");
javax.swing.JMenuItem wait4 = new javax.swing.JMenuItem("Wait 1000 ms");
menu.add(wait1);
menu.add(wait2);
menu.add(wait3);
menu.add(wait4);
menuBar.add(menu);
setJMenuBar(menuBar);
wait1.addActionListener(getActionListener(this, delayActionListener(100)));
wait2.addActionListener(getActionListener(this, delayActionListener(250)));
wait3.addActionListener(getActionListener(this, delayActionListener(500)));
wait4.addActionListener(getActionListener(this, delayActionListener(1000)));
cursorPanel = new javax.swing.JPanel();
cursorPanel.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent e) {
cursorPanel.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.CROSSHAIR_CURSOR));
}
public void mouseExited(java.awt.event.MouseEvent e) {
cursorPanel.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
}
});
javax.swing.JTabbedPane tabbedPane = new javax.swing.JTabbedPane();
tabbedPane.addTab("Default", new javax.swing.JPanel());
tabbedPane.addTab("Cursor change", cursorPanel);
getContentPane().add(tabbedPane);
setTitle("Cursor test");
setSize(400, 400);
setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
}
private java.awt.event.ActionListener delayActionListener(final int delay) {
java.awt.event.ActionListener listener = new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent ae) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
}
}
};
return listener;
}
public static void main(String[] args) {
new BusyCursorTest();
}
public static java.awt.event.ActionListener getActionListener(final java.awt.Component component,
final java.awt.event.ActionListener originalActionListener) {
java.awt.event.ActionListener actionListener = new java.awt.event.ActionListener() {
public void actionPerformed(final java.awt.event.ActionEvent e) {
java.util.TimerTask timerTask = new java.util.TimerTask() {
public void run() {
originalCursor = component.getCursor();
component.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
}
};
java.util.Timer timer = new java.util.Timer();
try {
timer.schedule(timerTask, DELAY_MS);
originalActionListener.actionPerformed(e);
} finally {
timer.cancel();
component.setCursor(originalCursor);
}
}
};
return actionListener;
}
private javax.swing.JPanel cursorPanel = null;
public static java.awt.Cursor originalCursor = null;
public static final int DELAY_MS = 250;
}
Запустите подключенный SSCE.
Когда выбрана первая вкладка ( "По умолчанию" ), нажатие на пункт меню 1000 мс покажет курсор занятости.
Когда выбрана вторая вкладка ( "Смена курсора" ), нажатие на пункт меню 1000 мс не отображает курсор занятости.
Как мне исправить эту проблему?
Я бы предпочел, чтобы мой код не учитывал ни одну из панелей, так как мне очень сложно отслеживать, какие панели могут быть на переднем крае. Кроме того, события не всегда генерируются из-за щелчка мыши.
Какое рекомендуемое обходное решение для изменения поведения в контейнере верхнего уровня?