Search code examples
javaswingjscrollpanejdialogjeditorpane

Cannot set maximum height of JEditorPane inside JScrollPane inside JDialog


So I want to achieve something very simple. In my application, users can consult the content of some files. First of all, the content of the files is in HTML, so I used JEditorPane to display it. Secondly, the file content is a bit long. Since I want it to be scrollable, I wrapped it in a JScrollPane. Lastly, this window should be modal. So I wrapped it again in a JDialog. Here's my code:

JEditorPane ep = new JEditorPane();
ep.setContentType("text/html");
ep.setEditable(false);
ep.setText(longHtmlString);
        
JScrollPane sp = new JScrollPane(ep);
sp.getViewport().setPreferredSize(new java.awt.Dimension(500, 1500));
        
JDialog dialog = new JDialog();
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.getContentPane().add(sp);
dialog.setModal(true);
dialog.setResizable(false);
dialog.pack();

dialog.setVisible(true);

But here is the output that I get: Output

As you can see, there is NO scrollbar and the dialog just takes the entire height of the HTML content... I want the dialog to have a fixed height with a vertical scrollbar. The content will ALWAYS be long like on the screenshot. I already tried setting the size on any of the 3 components (editorpane, scrollpane, jdialog) but I cannot achieve what I want. Am I missing something?


Solution

  • Your dialog is going to be Modal so make sure you set the dialog to always be on top of other windows:

    dialog.setAlwaysOnTop(true);
    

    Display the dialog realative to something like a specific Window or component. If you want the dialog to display in the center of the monitor screen then make it display relative to null:

    ........
    dialog.pack();
    dialog.setLocationRelativeTo(null);
    dialog.setVisible(true);
    

    You can get away with setting the preferred size of things at the final component level in this particular case however you will eventually find later on that this can lead to some undesirable results. Set the dialog to the size you want then let pack() take care of the rest:

    dialog.setPreferredSize(new java.awt.Dimension(500, 400));
    

    Set the dimensions to something more realistic as @camickr has already mentioned in comments. A height setting of 1500 is a little much but I'm sure this was a typo and your actual intention was 500, 500.

    If you are going to have a title bar for you dialog (which most do) then it's always nice to have an actual title in it so as to denote what the display content is about:

    dialog.setTitle("Would be nice to have a title here... - longHtmlString");
    

    Set your Scroll Bar Pane's horizontal and vertical policies so that the component knows what is expected:

    sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    

    With the above setting, either of the scroll bars will be displayed IF they are needed.

    Sometimes it's just nice to be able to resize a window a little bit to to catch that wee bit of data that went beyond limits instead of working a scroll bar all the time. You might want to consider removing the dialog.setResizable(false); line of code so that the dialog can indeed be resized if desired.

    So that the text material placed into the JEditorPane starts its display from the top of the document instead of the bottom of the document, you may want to consider moving the caret location to index location 0. Yes, this will work even if the Editor Pane is set to non-editable:

    ep.setCaretPosition(0);
    

    The following should work fine:

    // The JDialog Window...
    JDialog dialog = new JDialog();
    dialog.setTitle("Would be nice to have a title here... - longHtmlString");
    dialog.setAlwaysOnTop(true);
    dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    dialog.setPreferredSize(new java.awt.Dimension(500, 400));
    dialog.setModal(true);
    //dialog.setResizable(false);
        
    // The JEditorPane...
    JEditorPane ep = new JEditorPane();
    ep.setContentType("text/html");
    ep.setEditable(false);
    ep.setText(longHtmlString);
    ep.setCaretPosition(0);
    
    // The JScrollPane...
    JScrollPane sp = new JScrollPane(ep);     // Declared JEditorPane added here.
    sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    
    // Add components to dialog, pack it, and display the dialog.
    dialog.getContentPane().add(sp);
    dialog.pack();
    dialog.setLocationRelativeTo(null);
    dialog.setVisible(true);