Search code examples
javaswingjpaneljscrollpanelayout-manager

Changing JScrollPane height in Swing


I failed to change the height of JPanel or JScrollPane to make more lines to appear, I used GridLayout. It seems that, every component in it should have the same size even when I use setSize(). Should I use another layout?

import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;


public class Main {

   private JFrame mainFrame;
   private JLabel headerLabel;
   private JLabel statusLabel;
   private JPanel controlPanel;
   private imagePanel image;

   JTextField textField = new JTextField(20);

   public Main() throws IOException{
        prepareGUI();
   }


   class imagePanel extends JPanel {
private static final long serialVersionUID = 1L;

public void paint(Graphics g) {
       try {
            BufferedImage image = ImageIO.read(new File("file.jpg"));
            g.drawImage(image, 170, 0, null);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
   }
   }

   public static void main(String[] args) throws IOException{
   Main swingControlDemo = new Main();  

  swingControlDemo.showEventDemo();      

   }

   private void prepareGUI(){
  mainFrame = new JFrame("Java SWING Examples");
  mainFrame.setSize(400,500);
  GridLayout gridlayout = new GridLayout(4, 1);
  gridlayout.setVgap(1);
  mainFrame.setLayout(gridlayout);

  headerLabel = new JLabel("",JLabel.CENTER );
  statusLabel = new JLabel("",JLabel.CENTER);        

  JScrollPane scroller = new JScrollPane(statusLabel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

  mainFrame.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent windowEvent){
        System.exit(0);
         }        
      });    
  controlPanel = new JPanel();
  controlPanel.setLayout(new FlowLayout());

  image = new imagePanel();
  image.setLayout(new FlowLayout());



 // mainFrame.add(headerLabel);
  mainFrame.add(image);
  mainFrame.add(controlPanel);
  mainFrame.add(scroller);
  mainFrame.setVisible(true);  
   }

   private void showEventDemo(){
  headerLabel.setText("Control in action: Button"); 

  JButton okButton = new JButton("reload");
  JButton submitButton = new JButton("Submit");
  JButton cancelButton = new JButton("Cancel");

  okButton.setActionCommand("reload");
  submitButton.setActionCommand("Submit");
  cancelButton.setActionCommand("Cancel");

  okButton.addActionListener(new ButtonClickListener()); 
  submitButton.addActionListener(new ButtonClickListener()); 
  cancelButton.addActionListener(new ButtonClickListener()); 

  controlPanel.add(okButton);
  controlPanel.add(submitButton);
  //controlPanel.add(cancelButton);     
  controlPanel.add(textField);
  System.out.println("---------------------");
  mainFrame.setVisible(true);  
   }

   private class ButtonClickListener implements ActionListener{
  public void actionPerformed(ActionEvent e) {
     String command = e.getActionCommand();  
     if( command.equals( "reload" ))  {

             statusLabel.setText(convertToMultiline("Line1\nLine2\nLine3\nLine4\nLine5\nLine6\nLine7\nLine8\nLine9\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine\nLine2\nLine3\nLine"));

     }
     else  {
        statusLabel.setText("Submit Button clicked.");
     }      
  }     
   }

   public static String convertToMultiline(String orig)
   {
       return "<html>" + orig.replaceAll("\n", "<br>");
   }
}

Run application

The GUI need to look like this

enter image description here


Solution

  • I want to remove the large vertical gaps between the componets, and the jLabel should use that space

    Well in your comment you say you want the label to use the space. But in your picture you show the text area with all the space. How can we answer a question when you give us conflicting requirements? Be specific and accurate when describing a problem.

    In any case, the default layout of a JFrame is a BorderLayout so you would probably start with that.

    Then the component that you want to grow/shrink as the frame is resized should be added to the CENTER of the frame.

    Then you create a second panel to contain your other components. This panel would then be added to either the PAGE_START or PAGE_NORTH of the frame depending on your exact requirement.

    The layout manager of this panel can then be whatever your want. Maybe a GridLayout, or a GridBagLayout or a vertical BoxLayout.

    Read the section from the Swing tutorial on Layout Managers for more information and working examples. The key point is you create nest panels each with a different layout manager to achieve your layout.