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) для компонента вида, чтобы это исправить.

  • Браузер Webkit в приложении Java
  • SwingWorker не обновляет JProgressBar без Thread.sleep () в пользовательской диалоговой панели
  • Как узнать, когда пользователь действительно выпустил ключ на Java?
  • Почему setSelected on JCheckBox теряет эффект?
  • Попытка создания JTable с правильным заголовком строки
  • Изображения в paintComponent отображаются только после изменения размера windows
  • Нельзя ли добавить компонент Swing в несколько контейнеров?
  • Ограничение количества символов JTextField и прием только числовых символов
  • Повернуть BufferedImage внутри JPanel
  • Java Подождите, пока stream завершится
  • как добавить разные элементы JComboBox в столбце JTable в Swing
  • Interesting Posts

    Как я могу захватить событие KeyDown на странице WPF или объекте UserControl?

    Добавление списка предложений IN в запрос JPA

    Как использовать SearchView в панели инструментов Android

    Сохранять p: диалог открывается, когда возникает ошибка проверки после отправки

    NoSuchElementExeption, selenium, неспособный найти элемент

    Невозможно загрузить скрипт из активов index.android.bundle в windows

    Когда должен быть создан / открыт экземпляр EntityManagerFactory?

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

    Префикс SIMD на процессор Intel

    Алгоритм интерполяции ближайших соседей в MATLAB

    как сохранить массив в jQuery cookie?

    Что такое / dev / null 2> & 1?

    Как ограничить доступ к вложенному члену classа включению classа?

    Как получить Mac OS X Terminal.app и прокрутку экрана / vim, чтобы играть хорошо?

    Как преобразовать шестнадцатеричную строку в шестнадцатеричный номер

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