Search code examples
javaswingjscrollpanejtextarealayout-manager

GroupLayout: JScrollPane in TextArea is not working


i'm new in java and recently started to develop an simple application. For the moment i have a problem with JScrollPanne, it's not able to scroll down (or up) when the text in textarea more than size of area. I have looked to some solutions, but all of them were for FlowLayot (GridLayout and BoxLayout), but not for GroupLayout. Here is the code:

JPanel conent_p = new JPanel();
    conent_p.setBorder(new TitledBorder(null, "", TitledBorder.LEADING, TitledBorder.TOP, null, null));

    JLabel lblItemName = new JLabel("Item name:");
    itemField = new JTextField();
    itemField.setColumns(10);

    JLabel lblMxPrice = new JLabel("Max price:");   
    mpriceField = new JTextField();
    mpriceField.setColumns(10);

    JLabel lblQuantity = new JLabel("Quantity:");
    quanField = new JTextField();
    quanField.setColumns(10);

    JLabel lblDelivery = new JLabel("Delivery:");
    delivField = new JTextField();
    delivField.setColumns(10);

    JLabel lblLogcat = new JLabel("LogCat:");
    final JTextArea txtConsole = new JTextArea();
    txtConsole.setEditable(false);
    txtConsole.setLineWrap(true);
    txtConsole.setWrapStyleWord(true);

    sbrText = new JScrollPane(txtConsole);
    sbrText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    // Now create a new TextAreaOutputStream to write to our JTextArea control and wrap a
    // PrintStream around it to support the println/printf methods.
    PrintStream out = new PrintStream(new TextAreaOutputStream(txtConsole));
    // redirect standard output stream to the TextAreaOutputStream
    System.setOut(out);
    // redirect standard error stream to the TextAreaOutputStream
    System.setErr(out);

    GroupLayout gl_conent_p = new GroupLayout(conent_p);
    gl_conent_p.setHorizontalGroup(
        gl_conent_p.createParallelGroup(Alignment.LEADING)
            .addGroup(gl_conent_p.createSequentialGroup()
                .addContainerGap()
                .addGroup(gl_conent_p.createParallelGroup(Alignment.LEADING)
                    .addComponent(lblMxPrice, Alignment.TRAILING)
                    .addComponent(lblItemName, Alignment.TRAILING)
                    .addComponent(lblLogcat, Alignment.TRAILING))
                .addGap(18)
                .addGroup(gl_conent_p.createParallelGroup(Alignment.LEADING)
                    .addGroup(gl_conent_p.createSequentialGroup()
                        .addGroup(gl_conent_p.createParallelGroup(Alignment.LEADING, false)
                            .addComponent(itemField, GroupLayout.PREFERRED_SIZE, 365, GroupLayout.PREFERRED_SIZE)
                            .addGroup(gl_conent_p.createSequentialGroup()
                                .addComponent(mpriceField, GroupLayout.PREFERRED_SIZE, 80, GroupLayout.PREFERRED_SIZE)
                                .addGap(18)
                                .addComponent(lblQuantity)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(quanField, 0, 0, Short.MAX_VALUE)
                                .addGap(18)
                                .addComponent(lblDelivery)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(delivField, GroupLayout.PREFERRED_SIZE, 80, GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(ComponentPlacement.RELATED)))
                        .addGap(100))
                    .addGroup(gl_conent_p.createSequentialGroup()
                        .addComponent(txtConsole, GroupLayout.PREFERRED_SIZE, 345, GroupLayout.PREFERRED_SIZE)
                        .addComponent(sbrText)
                        .addContainerGap())))
    );
    gl_conent_p.setVerticalGroup(
        gl_conent_p.createParallelGroup(Alignment.LEADING)
            .addGroup(gl_conent_p.createSequentialGroup()
                .addContainerGap()
                .addGroup(gl_conent_p.createParallelGroup(Alignment.BASELINE)
                    .addComponent(lblItemName)
                    .addComponent(itemField, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE))
                .addGap(20)
                .addGroup(gl_conent_p.createParallelGroup(Alignment.LEADING)
                    .addGroup(gl_conent_p.createParallelGroup(Alignment.BASELINE)
                        .addComponent(lblDelivery)
                        .addComponent(delivField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addGroup(gl_conent_p.createParallelGroup(Alignment.BASELINE)
                        .addComponent(lblMxPrice)
                        .addComponent(mpriceField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(lblQuantity)
                        .addComponent(quanField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                .addGap(55)
                .addGroup(gl_conent_p.createParallelGroup(Alignment.BASELINE)
                    .addComponent(lblLogcat)
                    .addComponent(txtConsole, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
                    .addComponent(sbrText))
                .addContainerGap())
    );
    conent_p.setLayout(gl_conent_p);

    getContentPane().add(conent_p, BorderLayout.NORTH);

    JButton btnBuy = new JButton("Buy");
    btnBuy.addActionListener( new ActionListener() {
        public void actionPerformed(ActionEvent ev) {
            try {
                String title = itemField.getText().trim();
                String mprice = mpriceField.getText().trim();
                String quantity = quanField.getText().trim();
                String deliver = delivField.getText().trim();

                Item_CONCEPT item = new Item_CONCEPT();

                item.setName(title);
                item.setDelivery(Integer.parseInt(deliver));
                item.setStartPrice(0);
                item.setMaxPrice(Integer.parseInt(mprice));

                myAgent.existsSeller(item);

                Date date = new Date();
                DateFormat df = new SimpleDateFormat("dd.MM.yy HH:mm");
                System.out.println(df.format(date)+": Buyer orders an item: "+item.getName());

                //Clearing all fields
                itemField.setText("");
                quanField.setText("");
                delivField.setText("");
                //txtConsole.setText("");
                mpriceField.setText("");
            }
            catch (Exception e) {
                JOptionPane.showMessageDialog(BuyerGUI.this, "A field is filled incorrectly. "+e.getMessage()+" is invalid.", "Error", JOptionPane.ERROR_MESSAGE); 
            }
        }
    } );![enter image description here][1]

Solution

  • The issue you observe comes from two facts:

    • You are adding your content panel to BorderLayout.NORTH
    • You add the text console as well as the scroll pane as separate components

    For the first one: replace

    getContentPane().add(conent_p, BorderLayout.NORTH);
    

    with

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

    and for the second: do not add the txtConsole separately, i.e.

    inside the horizontal group substitute

    .addGroup(gl_conent_p.createSequentialGroup()
      .addComponent(txtConsole, GroupLayout.PREFERRED_SIZE, 345, GroupLayout.PREFERRED_SIZE)
      .addComponent(sbrText).addContainerGap());
    

    with

    .addComponent(sbrText);
    

    and inside the vertical group

    .addGroup(gl_conent_p.createParallelGroup(Alignment.BASELINE)
      .addComponent(lblLogcat)
      .addComponent(txtConsole, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
      .addComponent(sbrText)).addContainerGap()));
    

    with

    .addGroup(gl_conent_p.createParallelGroup(Alignment.BASELINE)
      .addComponent(lblLogcat)
      .addComponent(sbrText)).addContainerGap()));