2015-09-11 3 views
1

Мне недавно пришлось добавить несколько компонентов, JTextPane среди них, внутри одного окна просмотра JScrollPane. (См. Подробности here, если интересно).
Я поместил все Компоненты (два JPanels и JTextPane) внутри другого JPanel, у этого есть BorderLayout LayoutManager, и установите это JPanel как viewview view ScrollPane.JTextComponent внутри JPanel внутри JScrollPane

То, что я сразу заметил:
JTextPane не изменяет размер его ширину в соответствии с шириной JScrollPane больше, даже когда JScrollPane установлен в HORIZONTAL_SCROLLBAR_NEVER. Вместо этого он просто максимизирует свою ширину, чтобы вместить весь текст внутри одной строки (кроме разрывов строк \ n).

Вот две фотографии, как это выглядит:

enter image description here
enter image description here

И вот как это должно выглядеть вместо:

enter image description here

Теперь я найдено this question here, который отвечает t он первый вопрос. JPanel необходимо подклассифицировать, и подкласс должен реализовать прокручиваемый.

Однако с этим возникает другая проблема. JTextPane внутри JPanel больше не соблюдает BorderLayout.CENTER JPanel. Если текст не заполняет оставшееся пространство в окне, то JTextPane будет , а не.

enter image description here

То, что я ищу это решение для этого.

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

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

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.EmptyBorder; 
import java.awt.GridLayout; 
import java.awt.Rectangle; 
import javax.swing.JLabel; 
import javax.swing.JTextPane; 
import javax.swing.JScrollPane; 
import javax.swing.ScrollPaneConstants; 
import javax.swing.Scrollable; 


public class MinimalExample extends JFrame { 

    private JPanel contentPane; 
    private JPanel outerPanel; 
    private JPanel firstHeadlinePanel; 
    private JLabel lblSomeJlabel; 
    private JPanel secondHeadlinePanel; 
    private JLabel lblAnotherJlabel; 
    private JPanel headlinesPanel; 
    private JTextPane textPane; 
    private JScrollPane scrollPane; 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 

      public void run() { 

       try { 
        MinimalExample frame = new MinimalExample(); 
        frame.setVisible(true); 
       } 
       catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public MinimalExample() { 

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 230, 350); 
     contentPane = new JPanel(); 
     contentPane.setBorder(null); 
     setContentPane(contentPane); 
     contentPane.setLayout(new GridLayout(1, 0, 0, 0)); 

     outerPanel = new ScrollablePanel(); 
     //outerPanel = new JPanel(); 
     outerPanel.setLayout(new BorderLayout(0, 0)); 

     headlinesPanel = new JPanel(); 
     headlinesPanel.setBorder(new EmptyBorder(5, 0, 0, 0)); 
     outerPanel.add(headlinesPanel, BorderLayout.NORTH); 
     headlinesPanel.setLayout(new BorderLayout(0, 0)); 

     firstHeadlinePanel = new JPanel(); 
     firstHeadlinePanel.setBorder(new EmptyBorder(0, 0, 5, 0)); 
     headlinesPanel.add(firstHeadlinePanel, BorderLayout.NORTH); 
     firstHeadlinePanel.setLayout(new BorderLayout(0, 0)); 

     lblSomeJlabel = new JLabel("Some JLabel"); 
     firstHeadlinePanel.add(lblSomeJlabel, BorderLayout.CENTER); 

     secondHeadlinePanel = new JPanel(); 
     headlinesPanel.add(secondHeadlinePanel, BorderLayout.SOUTH); 
     secondHeadlinePanel.setLayout(new BorderLayout(0, 0)); 

     lblAnotherJlabel = new JLabel("Another JLabel"); 
     lblAnotherJlabel.setBorder(new EmptyBorder(0, 0, 5, 0)); 
     secondHeadlinePanel.add(lblAnotherJlabel, BorderLayout.NORTH); 

     textPane = new JTextPane(); 
     textPane.setText(addSomeShortText()); 
     //textPane.setText(addSomeLongText()); 
     outerPanel.add(textPane); 

     scrollPane = new JScrollPane(); 
     scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
     scrollPane.setViewportView(outerPanel); 

     contentPane.add(scrollPane); 
    } 

    private String addSomeShortText() { 

     return ("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur facilisis " 
       + "dictum ullamcorper. Nulla sed diam sit amet ante pellentesque ultricies in non " 
       + "est."); 
    } 

    private String addSomeLongText() { 

     return (" Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur facilisis " 
       + "dictum ullamcorper. Nulla sed diam sit amet ante pellentesque ultricies in non " 
       + "est. Suspendisse sit amet leo purus. Aenean lacinia ornare quam, a porttitor " 
       + "tortor vulputate quis. Quisque suscipit porttitor nisl, mollis suscipit ligula " 
       + "laoreet vitae. Nulla quis faucibus dui. Donec vestibulum quam sit amet " 
       + "facilisis scelerisque. Pellentesque eu lacus eget nibh elementum venenatis in " 
       + "congue magna. Donec et vestibulum magna, ut dapibus sapien.\n" 
       + "Donec nec enim magna. Curabitur vitae est est. Etiam non tellus nec ipsum " 
       + "dapibus ultricies eget ac lacus. Aliquam eu rhoncus leo. Suspendisse sodales " 
       + "nibh eros, vel placerat velit bibendum ut. Vivamus feugiat purus at viverra " 
       + "volutpat. Donec tincidunt quam quam, ut mattis enim rutrum sit amet. Integer " 
       + "volutpat sit amet metus vitae elementum. Aenean ullamcorper iaculis vulputate. " 
       + "Etiam venenatis mollis arcu quis interdum. Quisque et pharetra justo, et " 
       + "ullamcorper augue. Phasellus id pellentesque massa. Proin suscipit, mauris et " 
       + "congue commodo, mi eros fermentum ante, vel ultricies nisl neque a sem. Mauris " 
       + "tristique quis erat vel pulvinar. "); 
    } 

    /* Original source of this is here: 
    * https://stackoverflow.com/questions/15783014/jtextarea-on-jpanel-inside-jscrollpane-does-not-resize-properly */ 
    private static class ScrollablePanel extends JPanel implements Scrollable { 

     @Override 
     public Dimension getPreferredScrollableViewportSize() { 

      return super.getPreferredSize(); 
     } 

     @Override 
     public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, 
       int direction) { 

      return 16; 
     } 

     @Override 
     public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, 
       int direction) { 

      return 16; 
     } 

     @Override 
     public boolean getScrollableTracksViewportWidth() { 

      return true; 
     } 

     @Override 
     public boolean getScrollableTracksViewportHeight() { 

      return false; 
     } 
    } 

} 

Заранее благодарим за любую помощь, которую вы можете мне дать!

ответ

4

Хорошо, поэтому в основном вам необходимо изменить способ работы getScrollableTracksViewportHeight, основанный на высоте JViewport и вашем компоненте.

В основном вы хотите, чтобы компонент отслеживал высоту видового экрана (приспосабливаясь к совпадению), в то время как высота видового экрана больше предпочтительной высоты компонента. Когда предпочтительная высота компонента больше, чем область просмотра, вы хотите прекратить отслеживание и позволить компоненту «переполнять» панель прокрутки, что-то вроде ...

enter image description here

@Override 
public boolean getScrollableTracksViewportHeight() { 

    boolean track = true; 
    Container parent = getParent(); 
    if (parent instanceof JViewport) { 

     JViewport viewport = (JViewport) parent; 
     if (viewport.getHeight() < getPreferredSize().height) { 
      track = false; 
     } 

    } 

    return track; 
} 

Это "в основном", как такие вещи, как JTable и JList работы

+0

Wow. Вы, сэр, БЫСТРО. как, очень быстро. Я немного ошеломлен прямо сейчас. : D Я подозревал, что это будет некоторые дополнения к методу getScrollableTracksViewportHeight(), но я понятия не имел, что именно там нужно. Большое спасибо за ваш быстрый ответ! Вы даже сделали анимированное изображение, ничего себе. Благодаря этому я действительно впечатлен этим сайтом. ;) – Blacklands

+0

Если вы не можете ослепить блеском, дефлектор с BS;) - Рад, что это помогло;) – MadProgrammer

 Смежные вопросы

  • Нет связанных вопросов^_^