Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > JScrollPane и ScrollPane, имеют проблемы


Автор: Lisus 21.10.2007, 13:09
ХОЧУ:
Сделать собственный компеонент-такблицу. Существующие компеоненты меня не устраивают. Минимальные требования, что должен делать компонент - это окно с файлами тоталКомандера. Но вобщем не в этом дело.

Проблема:
Естественно, что мой компонент будет содержать полосы прокрытки (далее скролы), простейшим решением является использование ScrollPane \ JScrollPane.
Всё бы хорошо, но у первого компонента есть дефект. при изменении размера внутреннего компонента (доб\удал строк таблицы) нужно переустанавливать размер внутреннего компонента, а затем вызывать doLayout для реагирования на эти изменения ScrollPane. Однако при выполнении последней операции происходит "сдвиг", что делает сам компонент дёргующимся. И выглядет не красиво. Вот код: Для проверки нажмите клавишу.

Код

package test;

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

public class ScrollPanelTestRect extends JFrame {
    public ScrollPanelTestRect() {
    }

    public static void main(String[] args) {
        ScrollPanelTestRect sc = new ScrollPanelTestRect();
        sc.getContentPane().add(new spyy());

        sc.setBounds(0, 0, 400, 400);
        sc.show();
    }
}

class spyy extends ScrollPane {
    spxx xx = new spxx();

    public boolean keyDown(Event ev, int code) {
        this.doLayout();
        xx.repaint();
        System.out.println("OKE");
        return true;
    }

    public spyy() {
        for (int i = 0; i < 50; i++) {
            xx.add(new Button("Super start 123456789 abcde 123456789"));
        }

        this.add(xx); //getViewport()
        this.setBounds(0, 0, 398, 398);
        xx.doLayout();
        xx.repaint();
    }
}

class spxx extends Panel {
    int s = 0;

    /* public Dimension getPreferredSize()
     {return new Dimension(700,1000);} */

    public void paint(Graphics g) {
        g.drawLine(0, 0, 300, 300);
        g.drawLine(300, 0, 0, 300);

        System.out.println(s + "  Clip " + g.getClipRect());
        s++;
    }
}


Попробывал найти понимание у JScrollPane. У него всё работает нормально, но есть другой дефект. При появлении одновременно 2-х скролов внутренний компонент "Налезает" на них, и закрывает собой. Т.е. если размер скрола 420, 420   толштна скролПолос 20 и размер внутреннего компонента 500,500. То при значениях полосс 0%, 0% (на экране виден левый верхний угол внутренего элемента) обе полосы прокрытки не видны. если опустить вертикальную полосу прокрутки в 100%, т.е.изображение подымется на 100 пикселей, тогда будет видна нижняя полоса прокрутки... и т.д. По логике полосы прокрутки должны быть выше (а не ниже) Viewport().

Что это? Глюк, недоработка или неполадкт в моей версии ДЖАВА? Код почти тотже, только заменен на Jверсию СкроллПане

Очень не хочется писать собственную реализацию понели прокрутки, помогите и объясните, что не так.

Автор: w1nd 22.10.2007, 22:53
Тест запустил, ни одного из описанных глюков не наблюдал. Java 1.5.0

Автор: Lisus 23.10.2007, 09:51
А в чем может быть проблема?
Сменил JBuilder нак JIdea  и тоже самое.

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

Во втором случае сокракщаете размер ФРЕЙМА до размера скакжем 200, 15
По логиаке должнак появиться правая полосак прокрутки.
Вместо этого часть панели заграждает нижную прокрутку.

Что может быть??? Для более подробного и удобного анализа я создал файл http://upload.com.ua/get/900004295

Таам есть какртинаки дефектов, и ещё один дефект, когда вместо Panel я заменил на JPanel и устакновил лучший размер 700,1000 , такм вообще акнопки на скролы налезают

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

Автор: w1nd 24.10.2007, 00:16
Отличия - у меня windows 2000. Рекомендации:
  • Не смешивайте компоненты AWT и Swing, используйте какой-то один набор.
  • Компонент JScrollPane реагирует на изменение preferredSize компонент.
  • Вызывать repaint() и doLayout() до отрисовки (например, в конструкторе) совершенно бессмысленно; вместо doLayout() для swing-компонентов нужно вызывать revalidate(). Для корректной работы стандартных компонент с ScrollPane/JScrollPane вручную вызывать ни один из этих методов не требуется.
  • Для переопределении метода рисования swing-компонента нужно замещать метод paintComponent(), а не paint().
Исправленный пример:
Код
import java.awt.*;
import javax.swing.*;

public class ScrollPanelTestRect extends JFrame {
    public ScrollPanelTestRect() {
    }
    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName()
            );
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
        ScrollPanelTestRect sc = new ScrollPanelTestRect();
        sc.getContentPane().add(new spyy());
        sc.setSize(400, 400);
        sc.setLocationRelativeTo(null);
        sc.show();
    }
}

class spxx extends JPanel {
    spxx() {
        s = 0;
    }
    public void paintComponent(Graphics g) {
        int w = getWidth(), h = getHeight();
        g.clearRect(0, 0, w, h);
        g.drawLine(0, 0, w, h);
        g.drawLine(w, 0, 0, h);
        s++;
    }
    int s;
}

class spyy extends JScrollPane {
    public spyy() {
        xx = new spxx();
        xx.setBackground(Color.blue);
        xx.setPreferredSize(new Dimension(700, 1000));
        for (int i = 0; i < 50; i++)
            xx.add(new JButton("Super start 123456789 abcde 123456789"));

        getViewport().add(xx);
        setBounds(0, 0, 398, 398);
    }
    spxx xx;
}


Автор: Lisus 24.10.2007, 13:47
пасибо...

Счас буду с напеисанным разбираться

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)