Java: Как нарисовать прокрутку без прокрутки над ScrollPane Viewport?

Я хотел бы использовать ScrollPane для отображения изображения в его видовом экране, а также накладывать на изображение сетку (или поле или любой другой тип маркера регистрации / местоположения). Мне нужно, чтобы наложение оставалось фиксированным при прокрутке (что означает, что изображение перемещается «под» наложением). Я буду прокручивать View в Viewport с фиксированной скоростью, чтобы обеспечить плавное движение, а наложение – для ссылки на определенное место в пределах Viewport. Концептуально подумайте о большой карте, прокручивающейся в окне просмотра, и в окне просмотра, имеющем прямоугольник, который не перемещается (относительно самого видового экрана), который отмечает область, которая может быть увеличена в зависимости от какого-либо действия пользователя.

Я предполагаю (но еще не подтвердил), что реализация ScrollPane обрабатывает рендеринг представления эффективно (из хранилища резервных копий, не перерисовывая весь View (или даже ViewPort) для каждой новой частичной экспозиции), и поэтому предпочли бы не иметь Переопределите метод paint ().

Я посмотрел на LayerPane, и, не освоив его, кажется, что это подход грубой силы. ScrollPane является одним из компонентов SplitPane и будет перемещаться / изменяться. Я ожидаю, что мне придется вручную поддерживать правильную связь между ViewPort и LayerPane, используя абсолютное позиционирование. Я далек от эксперта по дизайну и внедрению GUI, и я уверен, что мне не хватает возможностей, от очевидного до неясного и элегантного, что знал бы опытный человек.

Я открыт для любых предложений, а не только по пути, с которого я начал работать. Должен ли я (могу ли я) добавить JPanel в качестве одного из компонентов в моей SplitPane, а затем добавить LayerPane к тому, что содержит мою ScrollPane и наложение (другое JPanel) на разных уровнях LayerPane? Есть ли функция в ScrollPane для поддержки этого напрямую? Я просмотрел учебники Java Swing и документацию по API, но ничего не видел.

Благодарю.

ОБНОВИТЬ:

Спасибо за ссылку, trashgod. Это было намного легче, чем я ожидал. Нет необходимости в LayerPane, GlassPane, xor-based compositing … Я не знаю, почему мне не приходило в голову переопределить JViewport.paint (), чтобы нарисовать мой оверлей, – но с приведенным ниже кодом я подтвердил, что концепция будет дай мне то, что я ищу. Просто используйте подclass JViewport, и он делает то, что я хотел (в данном случае накладывая прямоугольник в центре видового экрана, пока изображение прокручивается внизу). Я не эксперт GUI, и Java API невероятно широк; Я понятия не имею, как вы, ребята, все это в своей голове, но спасибо!

class MyViewport extends JViewport { @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.BLACK); g2.drawRect(getWidth()/4,getHeight()/4,getWidth()/2,getHeight()/2); } } 

Обычно «Swing-программы должны переопределять paintComponent() вместо переопределения paint() », как указано в « Живопись в AWT» и «Swing: The Paint Methods» . На основе ScrollPanePaint , который рисует ниже прокручиваемого содержимого, следующий пример переопределяет paint() для рисования над прокручиваемым контентом.

ScrollPanePaint

 import java.awt.*; import javax.swing.*; /** * @see https://stackoverflow.com/a/10097538/230513 * @see https://stackoverflow.com/a/2846497/230513 * @see https://stackoverflow.com/a/3518047/230513 */ public class ScrollPanePaint extends JFrame { private static final int TILE = 64; public ScrollPanePaint() { JViewport viewport = new MyViewport(); viewport.setView(new MyPanel()); JScrollPane scrollPane = new JScrollPane(); scrollPane.setViewport(viewport); this.add(scrollPane); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.pack(); this.setLocationRelativeTo(null); this.setVisible(true); } private static class MyViewport extends JViewport { public MyViewport() { this.setOpaque(false); this.setPreferredSize(new Dimension(6 * TILE, 6 * TILE)); } @Override public void paint(Graphics g) { super.paint(g); g.setColor(Color.blue); g.fillRect(TILE, TILE, 3 * TILE, 3 * TILE); } } private static class MyPanel extends JPanel { public MyPanel() { this.setOpaque(false); this.setPreferredSize(new Dimension(9 * TILE, 9 * TILE)); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.lightGray); int w = this.getWidth() / TILE + 1; int h = this.getHeight() / TILE + 1; for (int row = 0; row < h; row++) { for (int col = 0; col < w; col++) { if ((row + col) % 2 == 0) { g.fillRect(col * TILE, row * TILE, TILE, TILE); } } } } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new ScrollPanePaint(); } }); } } 

Примечание. Установка непрозрачного компонента (например, JTable ) в качестве представления для панели прокрутки даст странные визуальные ошибки, например, перемещение фиксированного синего поля при прокрутке. Используйте setOpaque (false) для компонента вида, чтобы это исправить.

  • Разница между краской, paintComponent и paintComponents в Swing
  • Использование шаблона наблюдателя в дизайне GUI JavaFX
  • Установка максимального размера JDialog?
  • Как добавить кнопку закрытия на вкладку JTabbedPane?
  • Как добавить кнопку в строке JTable в Swing java
  • Получить выделенные строки в JTable с помощью AbstractTableModel
  • Java JTextField с подсказкой ввода
  • используя sleep () для одного streamа
  • Как сделать прямоугольник перемещаться по экрану с помощью привязок клавиш?
  • Порядок срабатывания EventListenerList
  • JAR Bundler с использованием OSXAdapter, заставляющий приложение запаздывать или заканчиваться
  • Interesting Posts

    Как работает метод pandas groupby?

    Отображение всех символов Unicode в TextView

    Есть ли быстрый способ создать гиперссылку для открытия офисного документа Microsoft в существующей цепочке электронной почты?

    Внешний жесткий диск не может безопасно удалить

    Закажите «смешанный» вектор (цифры с буквами)

    Удаленный сеанс удаленного доступа Powershell

    Переменная среды среды C #

    Почему переименовать синтезированные свойства в iOS с ведущими подчеркиваниями?

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

    iPhone – UILabel, содержащий текст с несколькими шрифтами одновременно

    Как выбрать «последний ребенок» с определенным именем classа в CSS?

    Устанавливать фокус элемента угловым способом

    Папки Windows 7 «Все программы» автоматически закрываются правой кнопкой мыши

    Как я могу использовать несколько функций IF в Excel 2010?

    OpenCV получает значение пиксельного канала от изображения Mat

    Давайте будем гением компьютера.