JProgressbar Width Using Grid / FlowLayout

I am working on a bootloader that looks like this:

Screen shot

JFrame uses BorderLayout. IN NORTH I have a JPanel (FlowLayout). There is also a JPanel (FlowLayout) in SOUTH, in WEST I just have a JTextArea (in JScrollPane). All this is correctly shown. However, in EAST, I currently have a JPanel (GridLayout (10, 1)).

I want to show up to 10 JProgressBars in an EAST section that are dynamically added and removed from the panel. The problem is that I cannot make them look the way I want them to look: I want the JProgressBars width to fill the entire EAST section, because 1) it gives the application a more symmetrical look and 2) The ProgressBars can contain long strings that are not suitable at the moment. I tried putting a JPanel that contains GridLayout (10, 1) in a flowlayout, and then putting that flowlayout in the EAST section, but that didn't work either.

My code (SSCCE) currently looks like this:

import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { new DownloadFrame(); } private static class DownloadFrame extends JFrame { private JButton downloadButton; private JTextField threadIdTextField; private JTextArea downloadStatusTextArea; private JScrollPane scrollPane; private JTextField downloadLocationTextField; private JButton downloadLocationButton; private JPanel North; private JPanel South; private JPanel ProgressBarPanel; private Map<String, JProgressBar> progressBarMap; public DownloadFrame() { InitComponents(); InitLayout(); AddComponents(); AddActionListeners(); setVisible(true); setSize(700, 300); } private void InitComponents() { downloadButton = new JButton("Dowload"); threadIdTextField = new JTextField(6); downloadStatusTextArea = new JTextArea(10, 30); scrollPane = new JScrollPane(downloadStatusTextArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); downloadLocationTextField = new JTextField(40); downloadLocationButton = new JButton("..."); North = new JPanel(); South = new JPanel(); ProgressBarPanel = new JPanel(); progressBarMap = new HashMap<String, JProgressBar>(); } private void InitLayout() { North.setLayout(new FlowLayout()); South.setLayout(new FlowLayout()); ProgressBarPanel.setLayout(new GridLayout(10, 1)); } private void AddComponents() { North.add(threadIdTextField); North.add(downloadButton); add(North, BorderLayout.NORTH); add(ProgressBarPanel, BorderLayout.EAST); South.add(downloadLocationTextField); South.add(downloadLocationButton); add(South, BorderLayout.SOUTH); add(scrollPane, BorderLayout.WEST); } private void AddActionListeners() { downloadButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { addNewProgessBar(threadIdTextField.getText()); } }); } public void addNewProgessBar(String threadId) { JProgressBar progressBar = new JProgressBar(); progressBar.setStringPainted(true); progressBarMap.put(threadId, progressBar); drawProgessBars(); } void drawProgessBars() { ProgressBarPanel.removeAll(); for (JProgressBar progressBar : progressBarMap.values()) { ProgressBarPanel.add(progressBar); } validate(); repaint(); } } } 

Thanks in advance.

EDIT

The easiest solution: change

 add(ProgressBarPanel, BorderLayout.EAST); 

to

 add(ProgressBarPanel, BorderLayout.CENTER); 
+4
source share
3 answers

Screenshot of GUI

 import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { new DownloadFrame(); } private static class DownloadFrame extends JFrame { private JButton downloadButton; private JTextField threadIdTextField; private JTextArea downloadStatusTextArea; private JScrollPane scrollPane; private JTextField downloadLocationTextField; private JButton downloadLocationButton; private JPanel North; private JPanel South; private JPanel ProgressBarPanel; private Map<String, JProgressBar> progressBarMap; public DownloadFrame() { InitComponents(); AddComponents(); AddActionListeners(); pack(); setVisible(true); //setSize(700, 300); } private void InitComponents() { setLayout(new BorderLayout()); downloadButton = new JButton("Dowload"); threadIdTextField = new JTextField(6); downloadStatusTextArea = new JTextArea(10, 30); scrollPane = new JScrollPane(downloadStatusTextArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); downloadLocationTextField = new JTextField(40); downloadLocationButton = new JButton("..."); North = new JPanel(new FlowLayout()); South = new JPanel(new FlowLayout()); ProgressBarPanel = new JPanel(new GridLayout(0, 1)); ProgressBarPanel.setBorder(new LineBorder(Color.black)); ProgressBarPanel.setPreferredSize(new Dimension(300,20)); progressBarMap = new HashMap<String, JProgressBar>(); } private void AddComponents() { North.add(threadIdTextField); North.add(downloadButton); add(North, BorderLayout.NORTH); add(ProgressBarPanel, BorderLayout.EAST); South.add(downloadLocationTextField); South.add(downloadLocationButton); add(South, BorderLayout.SOUTH); add(scrollPane, BorderLayout.WEST); } private void AddActionListeners() { downloadButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { addNewProgessBar(threadIdTextField.getText()); } }); } public void addNewProgessBar(String threadId) { JProgressBar progressBar = new JProgressBar(); progressBar.setStringPainted(true); progressBarMap.put(threadId, progressBar); drawProgessBars(); } void drawProgessBars() { ProgressBarPanel.removeAll(); for (JProgressBar progressBar : progressBarMap.values()) { ProgressBarPanel.add(progressBar); } validate(); repaint(); } } } 
+6
source

Please post a compiled executable small program for quick help, SSCCE .

Suggestions include using GridLayout (0, 1) (a variable number of rows, one column) or mapping JProgressBars to a JList that uses its own renderer that extends JProgressBar.

Change 1:
I know that Andrei has already posted the accepted answer (and 1+ for an excellent answer), but I just wanted to demonstrate that this can be done easily with JList, something like this:

 import java.awt.*; import java.awt.event.*; import java.beans.*; import java.util.Random; import javax.swing.*; public class EastProgressList extends JPanel { private DefaultListModel myListModel = new DefaultListModel(); private JList myList = new JList(myListModel); private JTextField downloadUrlField = new JTextField(10); public EastProgressList() { JButton downLoadBtn = new JButton("Download"); downLoadBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { downloadAction(); } }); JPanel northPanel = new JPanel(); northPanel.add(new JLabel("File to Download:")); northPanel.add(downloadUrlField); northPanel.add(Box.createHorizontalStrut(15)); northPanel.add(downLoadBtn); myList.setCellRenderer(new ProgressBarCellRenderer()); JScrollPane eastSPane = new JScrollPane(myList); eastSPane.setPreferredSize(new Dimension(200, 100)); setLayout(new BorderLayout()); add(new JScrollPane(new JTextArea(20, 30)), BorderLayout.CENTER); add(northPanel, BorderLayout.NORTH); add(eastSPane, BorderLayout.EAST); } private void downloadAction() { String downloadUrl = downloadUrlField.getText(); final MyData myData = new MyData(downloadUrl); myListModel.addElement(myData); myData.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(MyData.VALUE)) { myList.repaint(); if (myData.getValue() >= 100) { myListModel.removeElement(myData); } } } }); } private class ProgressBarCellRenderer extends JProgressBar implements ListCellRenderer { protected ProgressBarCellRenderer() { setBorder(BorderFactory.createLineBorder(Color.blue)); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { //setText(value.toString()); MyData myData = (MyData)value; setValue(myData.getValue()); setString(myData.getText()); setStringPainted(true); return this; } } private static void createAndShowUI() { JFrame frame = new JFrame("EastProgressList"); frame.getContentPane().add(new EastProgressList()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } class MyData { public static final int TIMER_DELAY = 300; public static final String VALUE = "value"; protected static final int MAX_DELTA_VALUE = 5; private String text; private int value = 0; private Random random = new Random(); private PropertyChangeSupport pcSupport = new PropertyChangeSupport(this); public MyData(String text) { this.text = text; new Timer(TIMER_DELAY, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int deltaValue = random.nextInt(MAX_DELTA_VALUE); int newValue = value + deltaValue; if (newValue >= 100) { newValue = 100; ((Timer)e.getSource()).stop(); } setValue(newValue); } }).start(); } public String getText() { return text; } public int getValue() { return value; } public void setValue(int value) { int oldValue = this.value; this.value = value; PropertyChangeEvent pcEvent = new PropertyChangeEvent(this, VALUE, oldValue, value); pcSupport.firePropertyChange(pcEvent); } public void addPropertyChangeListener(PropertyChangeListener pcListener) { pcSupport.addPropertyChangeListener(pcListener); } } 

The result is a graphical interface similar to this:
enter image description here

+3
source

well. it is possible, but in your example the CENTER area occupied the Rectangle part, it is difficult to reduce / remove the CENTER area to zero Size

to the north of JPanel ( BorderLayout ) put another JPanel and place it in the EAST (with LayoutManager will be GridLayout(1,2,10,10) ) and put here two JComponents JTextField - threadIdTextField and JButton - downloadButton , there you will need setPreferredSize 1) for JComponents (right way) or 2) for whole JPanel (also possible)

JScrollPane with JTextArea must be placed in the CENTER area

JProgressBars JPanel with JProgressBars in EAST , but set the same PreferredSize again as for JPanel with JTextField and JButton from NORTH

SOUTH JPanel remains unchanged

+3
source

All Articles