Пользовательский JComponent для установки предпочтительного размера прокручиваемого окна просмотра

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

JScrollPane scrollPane = new JScrollPane(leftTop);
customScroll t1 = new customScroll();
scrollPane.add(t1);
left.add(scrollPane);

leftTop — это вложенная панель внутри левой. Вот мой класс для customScroll, который является пользовательским компонентом, который я создаю, поэтому я могу установить размер панели прокрутки:

public class customScroll extends JComponent implements Scrollable {

    public customScroll() {
        getPreferredScrollableViewportSize();
    }

    @Override
    public Dimension getPreferredScrollableViewportSize() {
        return(new Dimension(266,300));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g); 
    }

    @Override
    public int getScrollableBlockIncrement(Rectangle visibleRect,
            int orientation, int direction) {
        return 0;
    }

    @Override
    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return false;
    }

    @Override
    public int getScrollableUnitIncrement(Rectangle visibleRect,
            int orientation, int direction) {
        return 0;
    }
}

Как я могу установить предпочтительный размер прокрутки?


person requiem requiem    schedule 16.06.2015    source источник
comment
Обратите внимание на соглашения об именах Java — oracle.com/technetwork/java/codeconventions- 135099.html — особенно имена классов; Кроме того, укажите, с какой именно проблемой вы столкнулись?   -  person ring bearer    schedule 16.06.2015


Ответы (1)


Предоставить сеттер...

public void setPreferredScrollableViewportSize(Dimension size) {
    this.preferredScrollableViewportSize = size;
}

Теперь, очевидно, ваш getPreferredScrollableViewportSize должен будет вернуть это значение...

public class CustomScroll extends JComponent implements Scrollable {

    private Dimension preferredScrollableViewportSize = new Dimension(266, 300);

    public CustomScroll() {
    }

    public void setPreferredScrollableViewportSize(Dimension size) {
        this.preferredScrollableViewportSize = size;
    }

    @Override
    public Dimension getPreferredScrollableViewportSize() {
        return preferredScrollableViewportSize;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

    @Override
    public int getScrollableBlockIncrement(Rectangle visibleRect,
                    int orientation, int direction) {
        return 64;
    }

    @Override
    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return false;
    }

    @Override
    public int getScrollableUnitIncrement(Rectangle visibleRect,
                    int orientation, int direction) {
        return 64;
    }
}

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

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

Но это все равно просто получит предпочтительный размер

Нет, не будет, он будет использовать preferredScrollableViewportSize (при условии, что вы выполняете перенос в пределах JScrollPane

моя панель прокрутки приспосабливается к тому, что в ней находится, поэтому она просто увеличивается с добавлением кнопок

Тогда вы делаете что-то не так

JScrollPane scrollPane = new JScrollPane(leftTop);    
customScroll t1 = new customScroll();
// This is wrong...
scrollPane.add(t1);
left.add(scrollPane);

Вы никогда не должны добавлять что-либо к JScrollPane, это не то, как они работают, вместо этого вам нужно обернуть компонент внутри него.

leftTop t1 = new CustomScroll();
JScrollPane scrollPane = new JScrollPane(leftTop);    
left.add(scrollPane);

Или что-то подобное...

Я хочу, чтобы он оставался фиксированным размером, поэтому мне нужно явно установить размер, от которого он не может отклоняться.

Да, это то, что делает preferredScrollableViewportSize

ExampleLayout

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class JavaApplication57 {

    public static void main(String[] args) {
        new JavaApplication57();
    }

    public JavaApplication57() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            CustomScroll comp = new CustomScroll();
            comp.setPreferredScrollableViewportSize(new Dimension(100, 100));

            comp.setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.insets = new Insets(5, 10, 10, 5);
            for (int index = 0; index < 100; index++) {

                JButton btn = new JButton("Hello world " + index);
                comp.add(btn, gbc);

            }

            add(new JScrollPane(comp));
        }

    }

    public class CustomScroll extends JComponent implements Scrollable {

        private Dimension preferredScrollableViewportSize = new Dimension(266, 300);

        public CustomScroll() {
        }

        public void setPreferredScrollableViewportSize(Dimension size) {
            this.preferredScrollableViewportSize = size;
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return preferredScrollableViewportSize;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect,
                        int orientation, int direction) {
            return 64;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return false;
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect,
                        int orientation, int direction) {
            return 64;
        }
    }
}
person MadProgrammer    schedule 16.06.2015
comment
Но это все равно просто получит предпочтительный размер, моя панель прокрутки подстраивается под то, что в ней есть, поэтому она просто увеличивается с добавлением кнопок. Я хочу, чтобы он оставался фиксированным размером, поэтому мне нужно явно установить размер, от которого он не может отклоняться. - person requiem requiem; 16.06.2015
comment
nvm Я отсталый и не могу прочитать страницу документации. +1 за ваш ответ, хотя, лол. - person requiem requiem; 16.06.2015