Swing: Как я могу предотвратить мерцание и «вибрацию» компонента при ограничении его движения? - PullRequest
1 голос
/ 23 июня 2009

Мне нужно ограничить перемещение компонента (JInternalFrame) внутри JPanel.
Точнее: компонент должен перемещаться только вдоль одной оси при перетаскивании пользователем.

Я попытался сделать это, добавив компонентный слушатель и сбросив позицию одной оси каждый раз, когда компонент перемещается. Но это "вибрирует" (быстро перемещается во время перетаскивания).

Я даже написал собственный менеджер раскладки, это немного не помогло!

Полагаю, проблема в следующем: и менеджер раскладки, и слушатель. обрабатывать событие движения после фактического перемещения компонента, верно?

Есть предложения?

Должен ли я перехватить какое-либо событие и изменить его до его доставки?

Ответы [ 2 ]

2 голосов
/ 24 июня 2009

Нет «события», которое вам нужно перехватить. Как только Swing обрабатывает событие мыши, он сообщает компоненту о перемещении - и здесь вы можете настроить значения движения.

move, setLocation и resize - это всего лишь оболочки для setBounds. Расширьте JInternalFrame, переопределите метод setBounds () и игнорируйте новое значение x (или y, если вы хотите горизонтальное перемещение) перед вызовом super.setBounds ().

import javax.swing.JInternalFrame;
public class VerticalOnlyFrame extends JInternalFrame {

    public void setBounds(int x, int y, int width, int height) {
            super.setBounds(getBounds().x, y, width, height);
    }

}

Это должно решить ваш пример, хотя просмотр кода JRE setBounds () на самом деле является оберткой для устаревшего метода reshape (), так что если вы чувствуете смелое переопределение, вместо этого reshape ().

1 голос
/ 23 июня 2009

вы можете захотеть создать подкласс вашего InternalFrameUI. Я вижу в BasicInteralFrameUI.BorderListener.mouseDragged(event) (строка 885 в версии 1.129) вызов getDesktopManager().dragFrame(frame, newX, newY);

Вы можете расширить BasicInternalFrameUI, чтобы получить пользовательский DesktopManager (расширение DefaultDesktopManager), где в dragFrame() вы проверяете идентичность вашего кадра и корректируете ось.

редактирование:

Думая об этом, вы правы - это слишком сложно. поскольку пользовательский интерфейс для внутреннего фрейма соответствует DesktopManager из JDesktopPane, вы можете установить его там. вот документ:

public Demo() {
        JFrame frame = new JFrame();
        frame.setSize(300,300);
        JDesktopPane df = new JDesktopPane();
        DesktopManager dm = df.getDesktopManager();
        df.setDesktopManager(new DefaultDesktopManager(){
               public void dragFrame(JComponent f, int newX, int newY) {
                  super.dragFrame(f, newX, 5);
               }

        });
        JInternalFrame jif = new JInternalFrame("test ");
        jif.setLocation(5, 5);
        jif.setSize(150,100);
        jif.setVisible(true);
        df.add(jif);
        frame.setContentPane(df);
        frame.setVisible(true);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...