Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Swing.RepaintManager + PopupMenu + CustomDrawing

287
23 февраля 2010 года
Shiizoo
958 / / 14.03.2004
Здравствуйте. Столкнулся с проблемой при написании GUI для своего небольшого проекта. С Java знакомство только начал, разбираюсь по ходу написания. Проблема заключается в следующем.

При закрытии popupMenu RepaintManager выполняет перерисовку прямоугольника, который занимало это меню. Поскольку меню открывается поверх компонента, в котором происходит отрисовка различных фигур средствами java.awt.geom, то хотелось бы заменить перерисовку прямоугольника, освобождаемого меню, отрисовкой фигуры, которую перекрывало меню, либо еще что-то посложнее, если понадобится в будущем.

Никакими манипуляциями с передаваемым объектом Graphics расширить область прорисовки не получается — что ни делай, отрисовка за пределами изначальной clipping области не выходит.

Собственно, хотелось бы узнать, как правильно изменять clipping область на большую для объекта Graphics/Graphics2D и можно ли это сделать в принципе. Переопределять методы RepaintManager не хотелось бы.
Ниже привожу код, который воспроизводит проблему.
Код:
package popupRepaintIssue;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;

public class JPopupRepaintIssue extends JFrame {
    private class CustomDrawing extends JComponent {
        private Color color = Color.RED;
       
        public void paintComponent(Graphics g) {
            Dimension d = getSize();
            Graphics2D g2 = (Graphics2D) g;
            g2.setClip(getBounds());
            g2.setColor(color);
            g2.drawRect(d.width/4, d.height/4, d.width/2, d.height/2);
            log("PERFORMING CUSTOM DRAWING, " + color);
            log(g2.getClipBounds().toString());
            log(g2.getTransform().toString());
        }
        public void setColor(Color colour) {
            color = colour;
        }
        public Color getColor() {
            return color;
        }
    };
   
    public JPopupRepaintIssue() throws HeadlessException {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        setLayout(new GridBagLayout());
       
        final JLabel statusBar = new JLabel(" ");
        GridBagConstraints gc = new GridBagConstraints();
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.weightx = 1.0;
        gc.gridy = 1;
        add(statusBar,gc);
       
        final JPopupMenu popup = new JPopupMenu();
        popup.add(new JMenuItem("Item1"));
       
        /* *********** customDrawing setup *********** */
        final CustomDrawing drawing = new CustomDrawing();
        drawing.setPreferredSize(new Dimension(400, 400));
        JScrollPane sp = new JScrollPane(
                drawing,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
        );
        gc.fill = GridBagConstraints.BOTH;
        gc.gridy = 0;
        gc.weightx = 1.0;
        gc.weighty = 1.0;
        add(sp, gc);
       
        MouseAdapter adapter = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON3) {
                    popup.show(e.getComponent(), e.getX(), e.getY());
                }
                //if (!e.isPopupTrigger() && !popup.isShowing()) {
                    drawing.setColor(Color.RED);
                    log("changing to red");
                //}
            }
            @Override
            public void mouseMoved(MouseEvent e) {
                if (!popup.isShowing()) {
                    Dimension d = drawing.getSize();
                    Rectangle r2 = new Rectangle(
                        d.width/4, d.height/4,
                        d.width/2, d.height/2
                    );
                    if (r2.contains(e.getPoint())) {
                        if (!drawing.getColor().equals(Color.GREEN)) {
                            drawing.setColor(Color.GREEN);
                            drawing.repaint();
                        }
                    } else {
                        if (!drawing.getColor().equals(Color.RED)) {
                            drawing.setColor(Color.RED);
                            drawing.repaint();
                        }
                    }
                }
                statusBar.setText("Pointer location: "
                        + e.getX() + ", " + e.getY());
            }
        };

        sp.getViewport().addMouseListener(adapter);
        sp.getViewport().addMouseMotionListener(adapter);
        /* END *********** customDrawing setup *********** */

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }
   
    public static void log(String s) {
        System.err.print(s + "\n");
    }

    public static void main(String args[]) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JPopupRepaintIssue();
            }
        });
    }
}


Если открыть popup меню поверх линии прямоугольника, а затем кликом где-нибудь за пределами прямоугольника это меню сбросить, то перерисуется в новом цвете только то, что попало под меню.
Логики в такой смене цвета не ищите, хотелось бы разобраться с задачей в целом, а не с частным случаем (источником такой выборочной перерисовки, наверняка, может служить не только popup).

На скриншоте во вложении результат последовательного закрытия и открытия popup, не покидая прямоугольника.
14
25 февраля 2010 года
Phodopus
3.3K / / 19.06.2008
Ну и все верно, зачем перерисовывать то, что не изменялось?
287
28 февраля 2010 года
Shiizoo
958 / / 14.03.2004
Да, понимание пришло не сразу. =)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог