Why Jscrollpane in Joptionpane Not Showing All Its Content

Why JScrollPane in JOptionPane not showing all its content?

As shown in this related example, you can override the viewport's preferred size.

Sample Image

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

/**
* @see https://stackoverflow.com/a/14858272/230513
* @see https://stackoverflow.com/a/8504753/230513
* @see https://stackoverflow.com/a/14011536/230513
*/
public class DynamicGroupLayout {

private static final int NUM = 30;
private JTextField[] fields = new JTextField[NUM];
private JLabel[] labels = new JLabel[NUM];

private JPanel create() {
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
GroupLayout.ParallelGroup parallel = layout.createParallelGroup();
layout.setHorizontalGroup(layout.createSequentialGroup().addGroup(parallel));
GroupLayout.SequentialGroup sequential = layout.createSequentialGroup();
layout.setVerticalGroup(sequential);
for (int i = 0; i < NUM; i++) {
labels[i] = new JLabel(String.valueOf(i + 1), JLabel.RIGHT);
fields[i] = new JTextField(String.valueOf("String " + (i + 1)));
labels[i].setLabelFor(fields[i]);
parallel.addGroup(layout.createSequentialGroup().
addComponent(labels[i]).addComponent(fields[i]));
sequential.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).
addComponent(labels[i]).addComponent(fields[i]));
layout.linkSize(SwingConstants.HORIZONTAL, labels[i], labels[0]);
}
return panel;
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final JPanel panel = new DynamicGroupLayout().create();
JScrollPane jsp = new JScrollPane(panel) {
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
};
JOptionPane.showMessageDialog(null,
jsp, "Data", JOptionPane.PLAIN_MESSAGE);
}
});
}
}

JScrollPane doesn't show up in JFrame

Owing to clues given by @MadProgrammer, I figured out that the problem had risen from the way I added the JTextArea to the JScrollPane. It shouldn't have been done through scrlPane.add(serverResponseArea); but should have been done through JScrollPane scrlPane = new JScrollPane(serverResponseArea); instead.

However, since scrlPane.add(serverResponseArea); doesn't do the trick or create any obvious visual effect, why does the compiler let it get away in the firstplace and the runtime didn't throw such an exception? Isn't that a bug in the design of the library? The add mehtod might have been inherited from the parent component, but if it's 'useless' to the child component, why not kick it out of the child component? Maybe there is some reason for the method to continue stay there in the child component, but it can cause problems.

JScrollpane on JPanel doesn't work

In your button handlers you are re-adding a JTextArea to the GUI without its JScrollPane:

getContentPane().add(textArea, BorderLayout.CENTER);

which is essentially removing it from the JScrollPane just when you need it inside of it -- don't do that as this will totally mess you up and will remove the JScrollPane from view. Instead leave the JTextArea where it is, don't try to re-add components to your JFrame's contentPane, and simply add text to the JTextArea as needed.

Also, don't forget to give your JTextArea column and row properties, something that can easily be done by using the constructor that takes two ints. And leave the contentPane's layout as BorderLayout:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.net.*;
import javax.swing.border.LineBorder;

@SuppressWarnings("serial")
public class LabelFrame extends JFrame {
private static final int ROWS = 30;
private static final int COLS = 80;
private final JTextField urlString;
private final JButton loadButton;
String content;
JTextArea textArea = new JTextArea(ROWS, COLS);

public LabelFrame() {
super("WebStalker");
// setSize(600, 600);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// setLayout(new FlowLayout()); // !! no
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.setOpaque(false);
textArea.setEditable(false);
textArea.setFocusable(false);
textArea.setBackground(UIManager.getColor("Label.background"));
textArea.setFont(UIManager.getFont("Label.font"));
textArea.setBorder(UIManager.getBorder("Label.border"));

urlString = new JTextField("https:Search", 30);
loadButton = new JButton("Load");

JPanel panel = new JPanel();
JLabel label = new JLabel("URL");
panel.add(label);
panel.add(urlString);
panel.add(loadButton);

JScrollPane jp = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
// panel.add(jp);
this.add(panel, BorderLayout.PAGE_START);
add(jp);

pack(); // JFrame στο ελάχιστο μέγεθος με όλα τα περιεχόμενα
setLocationRelativeTo(null); // τοποθετεί στο κέντρο το παράθυρο

TextFieldHandler tHandler = new TextFieldHandler();
ButtonHandler bHandler = new ButtonHandler();

urlString.addActionListener(tHandler);
loadButton.addActionListener(bHandler);

urlString.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
urlString.setText("");
}
});

}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new LabelFrame().setVisible(true);
});
}

private class TextFieldHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
try {
content = URLReaderFinal.Reading(event.getActionCommand());

textArea.setText(content);

// !! getContentPane().add(textArea, BorderLayout.CENTER);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "This url doesnt exist", "Error", JOptionPane.ERROR_MESSAGE);
}

}
}

private class ButtonHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
try {
content = URLReaderFinal.Reading(urlString.getText());
textArea.setText(content);

// getContentPane().add(textArea, BorderLayout.CENTER);
} catch (Exception e) {
System.out.println("Unable to load page");
JOptionPane.showMessageDialog(null, "Unable to load page", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
}

edit: don't use a MouseListener on a JTextField. Perhaps you want to use a FocusListener instead.

Instead do something like:

public class LabelFrame extends JFrame {
private static final int ROWS = 30;
private static final int COLS = 80;
private static final String HTTPS_SEARCH = "https:Search";

// .....

public LabelFrame() {
// ....

urlString = new JTextField(HTTPS_SEARCH, 30);

//.....

urlString.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
JTextField textField = (JTextField) e.getComponent();
String text = textField.getText();
if (text.equals(HTTPS_SEARCH)) {
textField.setText("");
}
}
});

JOptionPane and scroll function

Here is an example using a JTextArea embedded in a JScrollPane:

JTextArea textArea = new JTextArea("Insert your Text here");
JScrollPane scrollPane = new JScrollPane(textArea);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
scrollPane.setPreferredSize( new Dimension( 500, 500 ) );
JOptionPane.showMessageDialog(null, scrollPane, "dialog test with textarea",
JOptionPane.YES_NO_OPTION);

JOptionPane.showConfirmDialog with a JScrollPane and a maximum size

As shown here, you can override the scroll pane's getPreferredSize() method to establish the desired size. If the content is larger in either dimension, the corresponding scroll bar will appear as needed.

JScrollPane myScrollPane = new JScrollPane(radioPanel){
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
};
JOptionPane.showConfirmDialog(null, myScrollPane);


Related Topics



Leave a reply



Submit