Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> работа с JScrollPane 
V
    Опции темы
Scarlett
Дата 18.12.2006, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 14.12.2006

Репутация: нет
Всего: 1



у меня возникла следующая проблема
создается панель JPanel, которая помещается в JScrollPane
на ней помещаются компоненты JComponent, которые могут перемещаться.
в зависимости от координат этих компонент динамически определяется размер панели и устанавливается при помощи setPreferredSize.
когда перемещается какой-то компонент, то он всегда должен быть видим на панели. поэтому использую scrollVisibleToRect, в котором передается область видимости для данного компонента.

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

пыталась просто при перерисовки и изменении размера создавать новый Image и отображать его на панели. скролл пыталась у Viewport-а делать. так же не помогает. мигание остается.

PM MAIL   Вверх
LSD
Дата 19.12.2006, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 38
Всего: 538



Можешь пример кода выложить?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Scarlett
Дата 19.12.2006, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 14.12.2006

Репутация: нет
Всего: 1



да.
выкладываю только часть кода, которая связана с проблемой

сам класс Forest  в принципе неважен в данном случа
он только говорит, что добавляется некоторый узел на панель и соответственно создается компонент для такого узла.

Код

//данный класс прослушивает движение компонента и помещен на JScrollPane
public class ForestViewPanel extends JPanel implements Observer  {
    private static final int X_MARGIN = 10;
    private static final int Y_MARGIN = 10;
    private Forest forest;
  
//инициализируем панель
    public ForestViewPanel(Forest forest) {
        super();
        if (forest == null)
            throw new IllegalArgumentException(Forest.FOREST_ERROR);
        this.forest = forest;
        forest.addObserver(this);
        this.setLayout(null);
        setOpaque(true);
        NodeViewMouseListener mouseControl = new NodeViewMouseListener(
                forest);
        addMouseMotionListener(mouseControl);
        addMouseListener(mouseControl);
    }
//определяем ширину панели
    public int maxWidthOfPanel() {
        return forest.maxCoordX() + GraphicNodeView.DEFAULT_WIDTH + X_MARGIN;
    }

//определяем высоту панели
    public int maxHeightOfPanel() {
        return forest.maxCoordY() + GraphicNodeView.DEFAULT_HEIGHT + Y_MARGIN;
    }

//вычисляем новый размер панели
    public Dimension check() {
        Dimension d = getSize();
        d.width = maxWidthOfPanel();
        d.height = maxHeightOfPanel();
        return d;
    }

public void update(Observable o, Object arg) {
        if ((o instanceof Forest) && (arg instanceof Node)) {
            if (((Forest) o).getState().equals(Forest.ADD_TREE)) {
                addNode((Node) arg);
            }
        }
        if (o instanceof Node) {
            if (arg == null) return;
            if (arg.equals(Node.LOCATION_CHANGE)) {
//при изменении положения какого-то компонента переопределяем размер
                 this.setPreferredSize(check());
            }
       }
}

//добавление компонента на панель
public void addNode(Node newNode) {
        GraphicNodeView visualNode = new GraphicNodeView(this, newNode);
                this.add(visualNode, 0);
}

//поиск компонента по координатам
public GraphicNodeView findNodeViewAtPoint(int x, int y) {
       // String name = node.getName();
        Component[] components = this.getComponents();
        for (int i = 0; i < components.length; i++) {
            if (!(components[i] instanceof GraphicNodeView)) {
                continue;
            }
            if (((GraphicNodeView) components[i]).isContainPointInBorder(x, y)) {
                return (GraphicNodeView) components[i];
            }
        }
        return null;
    }

public GraphicNodeView findNodeView(Node node) {
        if (node == null) return null;
        String name = node.getName();
        Component[] components = this.getComponents();
        for (int i = 0; i < components.length; i++) {
            if (!(components[i] instanceof GraphicNodeView)) {
                continue;
            }
            if (components[i].toString().equals(name)) {
                return (GraphicNodeView) components[i];
            }
        }
        return null;
    }
..............
}




//класс определяет модель компонента
public class Node extends Observable {

    public static final String STATE_CHANGE = "State change";
    public static final String LOCATION_CHANGE = "Location change";
    
    private String Name;
    private int posX = 0;
    private int posY = 0;
    private boolean isSelected = true;

    private Node parent = null;
    .....................

    public Node(String name) {
        this.Name = name;
       ..............
    }
//когда происходит изменение положения
    public void fireLocationChanged() {
        setChanged();
        notifyObservers(LOCATION_CHANGE);
    }
//установка новых координат и извещение всех об этом
public void setPosition(int x, int y) {
        posX = x;
        posY = y;
        fireLocationChanged();
    }
.....................
}

//определяет компонент который будет отображаться
public class GraphicNodeView extends JComponent implements Observer {
    public static final int DEFAULT_WIDTH = 150;
    public static final int DEFAULT_HEIGHT = 80;
    public static final Color ACTIVE_HEADER = Color.RED;
    public static final Color DEFAULT_HEADER = Color.BLUE;
    public static final Color DEFAULT_BACKGROUND = Color.WHITE;
    public static final Color NAME_COLOR = Color.WHITE;
    public static final int COUNT_OF_ROWS = 3;
    private ForestViewPanel parent;

    private Node owner;
    
    private boolean isActive = true;
    private Dimension preferredSize = new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    private JLabel lblName = new JLabel();
    private String name = "";
    boolean drag = false;
    int oldX;
    int oldY;
    /**
     * Identifies a image
     */
    private Image offScreen;

    public GraphicNodeView(ForestViewPanel parent, Node owner) {
        super();
        if ((parent == null) || (owner == null)) return;
        this.owner = owner;
        name = owner.getName();
        owner.addObserver(this);
        owner.addObserver(parent);
        this.parent = parent;   //only this
        parent.add(this, 0);
        init();
        this.update(owner, Node.STATE_CHANGE);
    }

    public void init() {
        setBorder(BorderFactory.createRaisedBevelBorder());
        setLayout(new FlowLayout(FlowLayout.CENTER));
        lblName.setForeground(NAME_COLOR);
        lblName.setBackground(isActive ? ACTIVE_HEADER : DEFAULT_HEADER);
        lblName.setOpaque(true);
        add(lblName);
        setBackground(DEFAULT_BACKGROUND);
        setBounds(0,  0,
                DEFAULT_WIDTH, DEFAULT_HEIGHT);
        setOpaque(true);
        setFocusable(true);

        lblName.setText(owner.getName());
        isActive = owner.isSelected();
        setLocation(owner.getPosX(),  owner.getPosY());
      }

protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (owner == null) return;
        
        if (offScreen == null) {
            Dimension size = getSize();

            int d = Math.min(size.width, size.height); // size

            offScreen = createImage(size.width, size.height);
            Graphics2D g2 = (Graphics2D) offScreen.getGraphics();
             g2.setColor(getBackground());
            g2.fillRect(0, 0, getWidth(), getHeight());
    
            g2.setColor(isActive ? ACTIVE_HEADER : DEFAULT_HEADER);
      
        int height = getHeight() / COUNT_OF_ROWS;
        g2.fillRect(0,  0, getWidth(), height);
        
        }
        g.drawImage(offScreen, 0, 0, this);
    }

public void update(Observable o, Object arg) {
        if (!(o instanceof Node)) return;
        if (arg == null) return;
        if ((arg.equals(Node.STATE_CHANGE)) ||
                (arg.equals(Node.LOCATION_CHANGE))) {
            isActive = ((Node) o).isSelected();
            lblName.setBackground(isActive ? ACTIVE_HEADER : DEFAULT_HEADER);
            lblName.setText(((Node) o).getName());
            name = lblName.getText();

            setLocation(((Node) o).getPosX(),  ((Node) o).getPosY());
            if (arg.equals(Node.STATE_CHANGE)) {
                offScreen = null;
                repaint();
            }
        }
    }

public boolean isContainPointInBorder(int x, int y) {
        int x0 = getX();
        int y0 = getY();
        int lastX = x0 + getWidth();
        int lastY = y0 + getHeight();
        return (x >= x0) && (x <= lastX) && (y >= y0) && (y <= lastY);
    }
.............................
}

public class NodeViewMouseListener implements MouseInputListener {
    private Node owner;
    private GraphicNodeView visualNode;
    private Forest parent;
    private boolean drag;
    int oldX;
    int oldY;
    

    /**
     * Create a controller of Mouse Events
     * @param parent
     */
    public NodeViewMouseListener(Forest parent) {
        if (parent == null) return;
        this.parent = parent;
     
    }
public void mousePressed(MouseEvent e) {
            if (!(e.getComponent() instanceof ForestViewPanel)) return;
            ForestViewPanel panel = (ForestViewPanel) e.getSource();
            int x = e.getX();
            int y = e.getY();
            GraphicNodeView visualNode = panel.findNodeViewAtPoint(x, y);
            Node source = null;
            if (visualNode != null) {
                source = visualNode.getOwner();
             }
            owner = source;
            parent.setActiveNode(source);

            oldX = x;
            oldY = y;

  }

public void mouseReleased(MouseEvent e) {
            if (owner == null) return;
            ForestViewPanel panel = (ForestViewPanel) e.getSource();
            int x = e.getX();
            int y = e.getY();

            
                int newX = owner.getPosX() + (x - oldX);
                int newY = owner.getPosY() + (y - oldY);
                if (newX < 0) newX = 0;
                if (newY < 0) newY = 0;
                owner.setPosition(newX, newY);
                GraphicNodeView visualNode = panel.findNodeView(owner);
           
                if (visualNode != null) {
                    int w = visualNode.getWidth() + 10;
                    int h = visualNode.getHeight() + 10;
                    Rectangle r = new Rectangle(newX,  newY, w, h);
                    panel.scrollRectToVisible(r);
                    
                                        
                }

                
      }

 public void mouseDragged(MouseEvent e) {
            if (owner == null) return;
            ForestViewPanel panel = (ForestViewPanel) e.getSource();
            int x = e.getX();
            int y = e.getY();
            
                int newX = owner.getPosX() + (x - oldX);
                int newY = owner.getPosY() + (y - oldY);
                if (newX < 0) newX = 0;
                if (newY < 0) newY = 0;
                owner.setPosition(newX, newY);
                GraphicNodeView visualNode = panel.findNodeView(owner);
                if (visualNode != null) {
                    int w = visualNode.getWidth() + 10;
                    int h = visualNode.getHeight() + 10;
                    Rectangle r = new Rectangle(newX,  newY, w, h);
                    panel.scrollRectToVisible(r);
                        panel.repaint(r);
                 

                }
               
                oldX = x;
                oldY = y;
      }
}

панель помещена в скролл на некоторую панель, которая размещается на фрейме, и определяется при помощи кода
root - это forest

Код

visualTree = new ForestViewPanel(root);
        visualTree.setBorder(BorderFactory.createEtchedBorder());
        JScrollPane scrollTree = new JScrollPane(visualTree);
        scrollTree.setPreferredSize(new Dimension(DEFAULT_VISUAL_WIDTH,
                DEFAULT_HEIGHT));

я тут поместила только то, что касается отображения в скролле

PM MAIL   Вверх
LSD
Дата 20.12.2006, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 38
Всего: 538



По коду я не вижу ничего такого, что могло бы вызвать подобные косяки. 
Хотелось бы примерчик, который можно запустить и "поиграться" с ним


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Scarlett
Дата 22.12.2006, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 14.12.2006

Репутация: нет
Всего: 1



ок
сварганю простенький примерчик и помещу
PM MAIL   Вверх
Scarlett
Дата 2.1.2007, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 14.12.2006

Репутация: нет
Всего: 1



извини не было времени ответить
нашла случайно в чем ошибка
оказывается я в какой-то момент изменила opaque у панели, по которой двигается компонент
теперь поставила setOpaque(false) и уже работает
спасибо

Добавлено @ 19:14 
в общем вопрос пока решен smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0510 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.