Java: JScrollPane отменяет настройку курсора JFrame, но только при запуске - PullRequest
2 голосов
/ 04 октября 2011

У меня есть программа, которая собирается выполнить некоторую работу (в фоновом потоке) при запуске, поэтому я хотел бы отобразить курсор занятости в течение нескольких минут, пока заполняется таблица. К сожалению, что бы я ни делал, я не мог заставить курсор ожидания появляться, если мое окно (JFrame) появлялось под указателем. Я провел некоторые эксперименты и отследил их до простого контрольного примера (ниже). В принципе, если существует JScrollPanel (например, как родитель для JTable) как дочерний элемент JFrame, то появится только курсор по умолчанию, если я не переместу указатель из окна и не вернусь внутрь.

Вот скомпилированный код:

package cursortest;

import java.awt.Cursor;
import java.awt.Dimension;
import javax.swing.*;

public class CursorTest extends JFrame {

    void initPanel() {
        JScrollPane panel = new JScrollPane();
        panel.setMinimumSize(new Dimension(500, 500));
        panel.setMaximumSize(new Dimension(500, 500));
        panel.setPreferredSize(new Dimension(500, 500));

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(panel)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(panel)
        );
    }

    public CursorTest() {
        initPanel();
        setMinimumSize(new Dimension(500, 500));
        setMaximumSize(new Dimension(500, 500));
        setPreferredSize(new Dimension(500, 500));
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        pack();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new CursorTest().setVisible(true);
            }
        });
    }
}

Запустите программу, чтобы при появлении окна указатель мыши находился в пределах окна. Возможно, вам придется поиграть с размерами, чтобы это произошло (я знаю, что для этого примера я сделал это искусственно).

Если initPanel НЕ вызывается, тогда курсор мыши немедленно появится как курсор ожидания.

Если вызван initPanel IS, курсор мыши будет отображаться по умолчанию, пока вы не переместите указатель из окна, а затем не вернетесь внутрь.

Кроме того, если JScrollPane заменить другим виджетом другого типа, скажем, JLabel, то эта проблема с курсором не проявляется.

Может кто-нибудь помочь мне понять, как решить эту проблему? Я думал о том, чтобы также установить курсор занятости для виджетов (мои JScrollPanel и / или JTable), но это не работает. Вы можете попробовать это, добавив строку panel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));.

О, и я, наверное, должен упомянуть, что я делаю это на Mac.

1 Ответ

2 голосов
/ 04 октября 2011

например

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class CursorTest extends JFrame {

    private static final long serialVersionUID = 1L;
    private javax.swing.Timer timer = null;
    private JScrollPane scroll;

    public CursorTest() {
        scroll = new JScrollPane();
        scroll.setPreferredSize(new Dimension(400,300));
        setTitle("CursorTest");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());
        add(scroll);
        setLocation(100, 100);
        pack();
        setVisible(true);
        start();
    }

    private void start() {
        scroll.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        timer = new javax.swing.Timer(5000, stop());
        timer.start();
    }

    public Action stop() {
        return new AbstractAction("Change Cursor Action") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                timer.stop();
                scroll.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
        };
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new CursorTest().setVisible(true);
            }
        });
    }
}
...