2

I want to display a list of strings in a window and i tried to use a JPanel surounded by JScrollPane because the size of the strings list is unknown. The problem is that the window is displaying the text Horizontally and i want to be displayed line after line. How to fix this? This is the code i've written so far.

package interface_classes;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextArea;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

public class ErrorMessageW {

    private JFrame errorMessageW;
    private ArrayList<String> errors;
    private JPanel panel;
    private JScrollPane scrollPane;
    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        final ArrayList<String> err = new ArrayList<>();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ErrorMessageW window = new ErrorMessageW(err);
                    window.errorMessageW.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public ErrorMessageW(ArrayList<String> err) {
        errors = err;
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        errorMessageW = new JFrame();
        errorMessageW.setTitle("Unfilled forms");
        errorMessageW.setBounds(100, 100, 367, 300);
        errorMessageW.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JButton btnOk = new JButton("OK");
        btnOk.setBounds(239, 208, 89, 23);
        btnOk.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                errorMessageW.dispose();
            }
        });
        errorMessageW.getContentPane().setLayout(null);
        errorMessageW.getContentPane().add(btnOk);
        
        scrollPane = new JScrollPane();
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setBounds(10, 10, 330, 175);
        errorMessageW.getContentPane().add(scrollPane);
        
        panel = new JPanel();
        for(String s : errors){
            JTextArea text = new JTextArea(1,20);
            text.setText(s);
            text.setFont(new Font("Verdana",1,10));
            text.setForeground(Color.RED);
            panel.add(text);
            
        }   
        scrollPane.setViewportView(panel);
    }
    
    public JFrame getErrorMessageW() {
        return errorMessageW;
    }

    public void setErrorMessageW(JFrame errorMessageW) {
        this.errorMessageW = errorMessageW;
    }


}

This is what i get enter image description here

This is what i want, but using the JScrollPane: enter image description here

Community
  • 1
  • 1
laura
  • 2,085
  • 13
  • 36
  • 68
  • 2
    `errorMessageW.setBounds(100, 100, 367, 300);` Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). – Andrew Thompson Jan 08 '14 at 13:37
  • @AndrewThompson the user can only read the error messages, click ok and fill corectly the forms. – laura Jan 08 '14 at 14:22
  • @AndrewThompson i've tried this piece of code `JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); scrollPane.setViewportView(panel); for(String s : errors){ JLabel text = new JLabel(); text.setFont(new Font("Verdana",1,10)); text.setForeground(Color.RED); text.setText(s); panel.add(text); }`, following the suggestion of Balduz and the result is the same like in the first picture. – laura Jan 08 '14 at 14:28
  • @AndrewThompson the only method that works until now is using a JTabel. – laura Jan 08 '14 at 14:36
  • @AndrewThompson What is your suggestion? – laura Jan 08 '14 at 15:00

3 Answers3

2

enter image description here

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.ArrayList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class ErrorMessageW {

    private JFrame errorMessageW;
    private ArrayList<String> errors;
    private JPanel panel;
    private JScrollPane scrollPane;
    private JTextArea errorMessage = new JTextArea(3, 30);

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        final ArrayList<String> err = new ArrayList<String>();
        err.add("Short String");
        err.add("A very very very very very very very very very very very "
                + "very very very very very very very very very very very "
                + "very very very very very very very very long String");
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    ErrorMessageW window = new ErrorMessageW(err);
                    window.errorMessageW.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public ErrorMessageW(ArrayList<String> err) {
        errors = err;
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        errorMessageW = new JFrame();
        JPanel contentPane = new JPanel(new BorderLayout(5, 15));
        contentPane.setBorder(new EmptyBorder(10, 10, 10, 10));
        errorMessage.setLineWrap(true);
        errorMessage.setWrapStyleWord(true);
        JScrollPane jsp = new JScrollPane(
                errorMessage,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
                );
        contentPane.add(jsp, BorderLayout.PAGE_START);

        errorMessageW.add(contentPane);
        errorMessageW.setTitle("Unfilled forms");
        errorMessageW.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JButton btnOk = new JButton("OK");
        btnOk.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent arg0) {
                errorMessageW.dispose();
            }
        });
        JPanel btnConstrain = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        btnConstrain.add(btnOk);
        contentPane.add(btnConstrain, BorderLayout.PAGE_END);

        scrollPane = new JScrollPane();
        scrollPane.setVerticalScrollBarPolicy(
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        contentPane.add(scrollPane, BorderLayout.CENTER);

        DefaultListModel<String> listModel = new DefaultListModel<String>();
        for (String s : errors) {
            listModel.addElement(s);
        }
        final JList<String> errorList = new JList<String>(listModel);
        Dimension preferredSize = new Dimension(errorMessage.getPreferredSize().width,200);
        errorList.setPreferredSize(preferredSize);
        ListSelectionListener errorSelect = new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                errorMessage.setText(errorList.getSelectedValue());
            }
        };
        errorList.addListSelectionListener(errorSelect);
        scrollPane.setViewportView(errorList);
        errorMessageW.pack();
    }

    public JFrame getErrorMessageW() {
        return errorMessageW;
    }

    public void setErrorMessageW(JFrame errorMessageW) {
        this.errorMessageW = errorMessageW;
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Note that code does have one major hack I did not have time to fix, but should warn you about. It sets the preferred size of the `JList` to the same preferred width as the `JTextArea`. See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Jan 08 '14 at 15:25
  • ..a better way to approach it is to override the preferred size of the list, to return the same width as what the text area returns. That way, if the PLAF is changed, the list will automatically adjust. – Andrew Thompson Jan 08 '14 at 15:27
0

First of all, you could try, instead of creating multiple instances of JTextArea, using only one and appending each error to it like this:

    JTextArea text = new JTextArea(1, 20);
    text.setFont(new Font("Verdana",1,10));
    text.setForeground(Color.RED);
    for(String s : errors) {
        text.append(s + "\n");
    }
    panel.add(text);

However, if you do need to create more than one JTextArea, you can use a BoxLayout like this:

    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
Balduz
  • 3,560
  • 19
  • 35
0

You just need to write a function that adds a new line character as an element of your ArrayList after every other element in your ArrayList of errors. Below i did a test program that shows how that can be done. I also checked the oputput. Just paste the code and understand the working of code. All the best!

       import java.util.ArrayList;

   public class TestingArraylist {


static ArrayList<String> errors = new ArrayList<String>();
static final String[] warnings = new String[]{"Error 0 occured","Error 1 occured","Error 2 occured","Error 3 occured","Error 4 occured"};;


   public static void addNewLineToArrayList(String[] elementofarraylist){

     for(int i =0;i<elementofarraylist.length;i++){
     errors.add(elementofarraylist[i]);
     errors.add("\n"); //this is what you need to do!
     }
 }

public static void main(String[] args) {

  addNewLineToArrayList(warnings);
  //checking below if our work has really succeded or not!!
  for(int j =0;j<errors.size();j++){

   System.out.print(errors.get(j));

  }

}

}